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:
2025-04-13 01:06:23 -04:00
parent 1cfd0426dd
commit 3b6d905180
89 changed files with 990 additions and 421 deletions

View File

@@ -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;
}
}