Still figuring out initial matchmaking hang (FROSTBITE). Lots of other changes.
- Added missing room images
- Removed internal rooms and disallow cloning some rooms
- License fixes
- Switched target to 20200306
- Socket header fixes
- Sockets are closed upon shutdown
* Sockets persist after being destroyed, fix
- Config changes for 20200306
- Settings initialized
- Name generation words cannot be longer than 9 characters
- Dorm generation changes and fixes
- Added some settings keys
- Matchmaking additions
* Instances are not yet updated to be or not to be in-progress
- Instance fixes and logging
- Image operation fixes
- DisplayName route start
- Challenge route start
- Default Amplitude key (i can see althe Amplitude requests are ignored
- Rate limiting ease
- GameConfigs properly queried and sent
- Many 'bulk' endpoints were added in or around 20200306
- Objective routes started
- DormRoom redirection in v2/name
- Client doesn't care if it gets 200 when setting prefs
- Balance/storefronts started
- Matchmaking goto/room timer and fixes
- Selfhosted Photon addition on the client sends matchmaking /photonregionpings, ignore since Photon is only one server in one region
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { Redis } from "../../db.ts";
|
||||
import { RootPath } from "./baseimages.ts";
|
||||
import { BuiltinRoom, RoomDetails, RoomState } from "./roomtypes.ts";
|
||||
import { BuiltinRoom, RoomAccessibility, RoomDetails, RoomState } from "./roomtypes.ts";
|
||||
import { RoomFetch } from "./room.ts";
|
||||
import { Profile } from "../profiles.ts";
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
@@ -172,7 +172,7 @@ class RoomsBase {
|
||||
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Room_Names, details.Room.Name), details.Room.RoomId);
|
||||
}
|
||||
|
||||
async cloneRoom(roomid: number, newname: string, newowner: Profile, dorm?: boolean) {
|
||||
async cloneRoom(roomid: number, newname: string, newowner: Profile) {
|
||||
const canBeClonedRaw = await Redis.Database.hget(Redis.buildKey(
|
||||
Redis.KeyGroups.Rooms.Root,
|
||||
roomid.toString(),
|
||||
@@ -183,22 +183,21 @@ class RoomsBase {
|
||||
try {
|
||||
canBeCloned = JSON.parse(canBeClonedRaw) as boolean;
|
||||
} catch {
|
||||
log.d(`Cloneroom ${roomid}: parse error`);
|
||||
return null;
|
||||
}
|
||||
if (!canBeCloned) {
|
||||
log.d(`Cloneroom ${roomid}: cannot be cloned`);
|
||||
return null;
|
||||
}
|
||||
if (!canBeCloned) return null;
|
||||
const beforeRoom = await Rooms.get(roomid); // room must exist
|
||||
if (!beforeRoom || !beforeRoom.Room.CloningAllowed) return null; // room must be cloneable
|
||||
if (await Rooms.getByName(newname) && beforeRoom.Room.Name !== 'DormRoom') return null; // room name cannot be taken
|
||||
if (beforeRoom.Room.Name !== 'DormRoom' && await Rooms.getByName(newname)) return null; // room name cannot be taken
|
||||
|
||||
const newId = await this.#getAvailableRoomId();
|
||||
beforeRoom.Room.CreatorPlayerId = newowner.getId();
|
||||
beforeRoom.Room.RoomId = newId;
|
||||
for (const subroom of beforeRoom.Scenes) subroom.RoomId = newId;
|
||||
if (dorm) {
|
||||
beforeRoom.Room.IsAGRoom = true;
|
||||
beforeRoom.Room.IsDormRoom = true;
|
||||
beforeRoom.Room.CloningAllowed = false;
|
||||
}
|
||||
|
||||
await Rooms.#setRoom(beforeRoom);
|
||||
return beforeRoom;
|
||||
@@ -211,19 +210,19 @@ class RoomsBase {
|
||||
Redis.KeyGroups.Rooms.PlayerDorms
|
||||
), player.getId().toString());
|
||||
if (unparsedId) {
|
||||
log.d(`Unparsed dorm ID for profile ${player.getId()}: ${unparsedId}`);
|
||||
const parsedId = parseInt(unparsedId);
|
||||
if (!isNaN(parsedId)) return await Rooms.get(parsedId);
|
||||
if (isNaN(parsedId)) {
|
||||
log.d(`Returning new dorm for profile ${player.getId()}`);
|
||||
return await Rooms.get(parsedId);
|
||||
}
|
||||
}
|
||||
|
||||
const baseDorm = await Rooms.getByName("DormRoom");
|
||||
|
||||
log.d('Base dorm existed');
|
||||
if (!baseDorm) return null;
|
||||
log.d('Base dorm was not null');
|
||||
const newDorm = await this.cloneRoom(baseDorm.Room.RoomId, "DormRoom", player, true);
|
||||
log.d('New dorm existed');
|
||||
const newDorm = await this.generateNewDorm(player);
|
||||
await this.#setRoom(newDorm);
|
||||
log.d(`New dorm for ${player.getId()} existed`);
|
||||
if (!newDorm) return null;
|
||||
log.d('New dorm was not null');
|
||||
log.d(`New dorm for ${player.getId()} was not null`);
|
||||
await Redis.Database.hset(Redis.buildKey(
|
||||
Redis.KeyGroups.Rooms.Root,
|
||||
Redis.KeyGroups.Rooms.PlayerDorms
|
||||
@@ -231,10 +230,59 @@ class RoomsBase {
|
||||
return newDorm;
|
||||
}
|
||||
|
||||
async generateNewDorm(player: Profile) {
|
||||
const id = await this.#getAvailableRoomId();
|
||||
const basedorm: RoomDetails = {
|
||||
Room: {
|
||||
RoomId: id,
|
||||
Name: `DormRoom`,
|
||||
Description: "Your private room.",
|
||||
CreatorPlayerId: player.getId(),
|
||||
ImageName: "DefaultProfileImage.png",
|
||||
State: RoomState.Active,
|
||||
Accessibility: RoomAccessibility.Private,
|
||||
SupportsLevelVoting: false,
|
||||
IsAGRoom: false,
|
||||
IsDormRoom: true,
|
||||
CloningAllowed: false,
|
||||
SupportsScreens: true,
|
||||
SupportsTeleportVR: true,
|
||||
SupportsWalkVR: true,
|
||||
AllowsJuniors: true,
|
||||
RoomWarningMask: 0,
|
||||
CustomRoomWarning: "",
|
||||
DisableMicAutoMute: false
|
||||
},
|
||||
Scenes: [
|
||||
{
|
||||
RoomId: id,
|
||||
RoomSceneId: 1,
|
||||
Name: "Home",
|
||||
RoomSceneLocationId: "76d98498-60a1-430c-ab76-b54a29b7a163",
|
||||
IsSandbox: true,
|
||||
CanMatchmakeInto: true,
|
||||
MaxPlayers: 4,
|
||||
DataBlobName: "",
|
||||
DataModifiedAt: new Date().toISOString()
|
||||
}
|
||||
],
|
||||
CoOwners: [],
|
||||
InvitedCoOwners: [],
|
||||
Hosts: [],
|
||||
InvitedHosts: [],
|
||||
CheerCount: 0,
|
||||
VisitCount: 0,
|
||||
FavoriteCount: 0,
|
||||
Tags: []
|
||||
}
|
||||
return basedorm;
|
||||
}
|
||||
|
||||
async generateBuiltinRooms() {
|
||||
|
||||
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
||||
for (const builtinRoom of rooms) {
|
||||
if (builtinRoom.Name == 'DormRoom') continue;
|
||||
const newId = await this.#getAvailableRoomId();
|
||||
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
||||
const roomDets: RoomDetails = {
|
||||
@@ -320,6 +368,11 @@ class RoomsBase {
|
||||
else return parsedIds.map(val => val.toString());
|
||||
}
|
||||
|
||||
getSubroomNameFromId(room: RoomDetails, subroomId: number) {
|
||||
const subroom = room.Scenes.find(scene => scene.RoomSceneId == subroomId);
|
||||
if (subroom) return subroom.Name;
|
||||
else return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user