diff --git a/.gitignore b/.gitignore index 118e45b..1d25002 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,6 @@ dist build/ config.json -.vscode \ No newline at end of file +.vscode +# used to attach license to each file +/append.ts \ No newline at end of file diff --git a/src/apiutils.ts b/src/apiutils.ts index c2d4be6..2a6583b 100644 --- a/src/apiutils.ts +++ b/src/apiutils.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + // @ts-types = "npm:@types/express" import express from "express"; import Logging from "@proxnet/undead-logging"; @@ -338,7 +355,7 @@ export function LoginLock(rq: express.Request; -export function startTimer(rq: express.Request, rs: express.Response, nxt: express.NextFunction) { +export function startTimer(_rq: express.Request, rs: express.Response, nxt: express.NextFunction) { rs.locals.timer = performance.now(); nxt(); } diff --git a/src/config.ts b/src/config.ts index 167899f..b313289 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import Logging from "@proxnet/undead-logging"; import * as fs from "node:fs"; import { PhotonRegionCodeString } from "./data/live/types.ts"; diff --git a/src/data/config.ts b/src/data/config.ts index e2598aa..bbd5ee9 100644 --- a/src/data/config.ts +++ b/src/data/config.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Config } from "../config.ts"; import { Redis } from "../db.ts"; import { Objectives } from "./objectives.ts"; @@ -10,6 +27,16 @@ export type LevelProgressionItem = { Level: number; RequiredXp: number; }; +export type AutoMicMutingConfig = { + MicSpamVolumeThreshold: number, + MicVolumeSampleInterval: number, + MicVolumeSampleRollingWindowLength: number, + MicSpamSamplePercentageForWarning: number, + MicSpamSamplePercentageForWarningToEnd: number, + MicSpamSamplePercentageForForceMute: number, + MicSpamSamplePercentageForForceMuteToEnd: number, + MicSpamWarningStateVolumeMultiplier: number +} export type PublicConfig = { ServerMaintenance: { StartsInMinutes: number; @@ -17,6 +44,7 @@ export type PublicConfig = { LevelProgressionMaps: LevelProgressionItem[]; DailyObjectives: Objectives.Objective[][]; ConfigTable: Config[]; + AutoMicMutingConfig: AutoMicMutingConfig }; /** @@ -45,6 +73,16 @@ export function getConfig() { LevelProgressionMaps: generateLevelProgressionMap(), DailyObjectives: [], ConfigTable: [], + AutoMicMutingConfig: { + MicSpamVolumeThreshold: 1.125, + MicVolumeSampleInterval: 0.25, + MicVolumeSampleRollingWindowLength: 7.0, + MicSpamSamplePercentageForWarning: 0.8, + MicSpamSamplePercentageForWarningToEnd: 0.2, + MicSpamSamplePercentageForForceMute: 0.8, + MicSpamSamplePercentageForForceMuteToEnd: 0.2, + MicSpamWarningStateVolumeMultiplier: 0.25 + } }; return conf; diff --git a/src/data/content/avatar.ts b/src/data/content/avatar.ts index 25fee34..d123b2d 100644 --- a/src/data/content/avatar.ts +++ b/src/data/content/avatar.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + enum AvatarItemType { None = -1, Hat, diff --git a/src/data/content/baseimages.ts b/src/data/content/baseimages.ts index 2c2a5b4..f543417 100644 --- a/src/data/content/baseimages.ts +++ b/src/data/content/baseimages.ts @@ -1,17 +1,34 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { platform } from "node:process"; -const base = Deno.mainModule.substring(platform == 'win32' ? 8 : 7, Deno.mainModule.length - 11); +export const RootPath = Deno.mainModule.substring(platform == 'win32' ? 8 : 7, Deno.mainModule.length - 11); export function getBaseImage(name: string) { try { - return Deno.readFileSync(`${base}/res/img/${name}`); + return Deno.readFileSync(`${RootPath}/res/img/${name}`); } catch (_err) { return null; } } export function getAllBaseImages() { return Array.from( - Deno.readDirSync(`${base}/res/img/`).map((val) => val.isFile ? val.name : undefined), + Deno.readDirSync(`${RootPath}/res/img/`).map((val) => val.isFile ? val.name : undefined), ).filter((val) => typeof val == "string"); } // todo: make this async diff --git a/src/data/content/consumable.ts b/src/data/content/consumable.ts index 32f52da..d807844 100644 --- a/src/data/content/consumable.ts +++ b/src/data/content/consumable.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export enum Consumable { ASSORTED_DONUTS, SUPREME_PIZZA, diff --git a/src/data/content/gamerooms.ts b/src/data/content/gamerooms.ts index f95686a..12eaa75 100644 --- a/src/data/content/gamerooms.ts +++ b/src/data/content/gamerooms.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + interface InternalScene { Name: string; ReplicationId: string; diff --git a/src/data/content/images.ts b/src/data/content/images.ts index bedd5d8..f7814c6 100644 --- a/src/data/content/images.ts +++ b/src/data/content/images.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Buffer } from "node:buffer"; import { Redis } from "../../db.ts"; diff --git a/src/data/content/room.ts b/src/data/content/room.ts new file mode 100644 index 0000000..c3ce3ab --- /dev/null +++ b/src/data/content/room.ts @@ -0,0 +1,132 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { Redis } from "../../db.ts"; +import Rooms from "./rooms.ts"; +import { IntegratedRoomScene, RoomAccessibility, RoomDetails, RoomState } from "./roomtypes.ts"; + +interface RoomFetchOptions { + roomName?: string, + roomId?: number +} + +export function parseBooleanDefault(obj: string, def: boolean | undefined = false) { + try { + return JSON.parse(obj) as boolean; + } catch { + return def; + } +} + +export class RoomFetch { + + roomId: number | null = null; + roomName: string | null = null; + + constructor(options: RoomFetchOptions) { + + this.roomId = options.roomId ?? null; + this.roomName = options.roomName ?? null; + + } + + async fetch() { + + if (!this.roomId && this.roomName) { + const givenId = await Rooms.getIdFromName(this.roomName); + if (!givenId) return null; + else this.roomId = givenId; + } else if (!this.roomName && this.roomId) { + const givenName = await Rooms.getNameFromId(this.roomId); + if (!givenName) return null; + else this.roomName = givenName; + } else if (!this.roomId && !this.roomName) return null; + + const roomRootKey = Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + this.roomId!.toString(), // code above takes care of null possibility + ); + const roomMetaKey = Redis.buildKey( + roomRootKey, + Rooms.roomRootKeys.Meta + ); + + const [ hash, cheerCount, favoriteCount, visitCount ] = await Promise.all([ + Redis.Database.hgetall(roomMetaKey), + Redis.Database.get(Redis.buildKey(roomRootKey, Rooms.roomRootKeys.CheerCount)), + Redis.Database.get(Redis.buildKey(roomRootKey, Rooms.roomRootKeys.FavoriteCount)), + Redis.Database.get(Redis.buildKey(roomRootKey, Rooms.roomRootKeys.VisitCount)), + ]); + + const room: RoomDetails = { + Room: { + RoomId: hash[Rooms.roomMetaKeys.RoomId] ? parseInt(hash[Rooms.roomMetaKeys.RoomId]) : 0, + Name: hash[Rooms.roomMetaKeys.Name] ?? "DATABASEERROR", + Description: hash[Rooms.roomMetaKeys.Description] ?? "DATABASEERROR", + CreatorPlayerId: hash[Rooms.roomMetaKeys.CreatorPlayerId] ? parseInt(hash[Rooms.roomMetaKeys.CreatorPlayerId]) : 1, + ImageName: hash[Rooms.roomMetaKeys.ImageName] ?? "DefaultProfileImage.png", + State: hash[Rooms.roomMetaKeys.State] ? parseInt(hash[Rooms.roomMetaKeys.State]) : RoomState.Active, + Accessibility: hash[Rooms.roomMetaKeys.Accessibility] ? parseInt(hash[Rooms.roomMetaKeys.Accessibility]) : RoomAccessibility.Unlisted, + SupportsLevelVoting: hash[Rooms.roomMetaKeys.SupportsLevelVoting] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.SupportsLevelVoting], true) : true, + IsAGRoom: hash[Rooms.roomMetaKeys.IsAGRoom] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.IsAGRoom], false) : false, + IsDormRoom: hash[Rooms.roomMetaKeys.IsDormRoom] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.IsDormRoom], false) : false, + CloningAllowed: hash[Rooms.roomMetaKeys.CloningAllowed] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.CloningAllowed], false) : false, + SupportsScreens: hash[Rooms.roomMetaKeys.SupportsScreens] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.SupportsScreens], true) : true, + SupportsWalkVR: hash[Rooms.roomMetaKeys.SupportsWalkVR] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.SupportsWalkVR], true) : true, + SupportsTeleportVR: hash[Rooms.roomMetaKeys.SupportsTeleportVR] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.SupportsTeleportVR], true) : true, + AllowsJuniors: hash[Rooms.roomMetaKeys.AllowsJuniors] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.AllowsJuniors], true) : true, + RoomWarningMask: hash[Rooms.roomMetaKeys.RoomWarningMask] ? parseInt(hash[Rooms.roomMetaKeys.RoomWarningMask]) : 0, + CustomRoomWarning: hash[Rooms.roomMetaKeys.CustomRoomWarning] ?? "", + DisableMicAutoMute: hash[Rooms.roomMetaKeys.DisableMicAutoMute] ? parseBooleanDefault(hash[Rooms.roomMetaKeys.DisableMicAutoMute], false) : undefined, + }, + Scenes: [], // temporary + CoOwners: [], // temporary + InvitedCoOwners: [], // temporary + Hosts: [], // temporary + InvitedHosts: [], // temporary + CheerCount: cheerCount ? parseInt(cheerCount) : 0, + FavoriteCount: favoriteCount ? parseInt(favoriteCount) : 0, + VisitCount: visitCount ? parseInt(visitCount) : 0, + Tags: [] // temporary + } + const subrooms = await Rooms.getSubroomIdsFromRoom(this.roomId!); + for (const subroom of subrooms) { + const subroomMetaKey = Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + this.roomId!.toString(), + Rooms.roomRootKeys.Subrooms, + subroom.toString(), + Rooms.subroomRootKeys.Meta + ); + const subroomDetails = await Redis.Database.hgetall(subroomMetaKey); + room.Scenes.push({ + RoomSceneId: parseInt(subroom), + RoomId: this.roomId ?? 0, + RoomSceneLocationId: subroomDetails[Rooms.subroomMetaKeys.RoomSceneLocationId] ?? IntegratedRoomScene.MakerRoom, + Name: subroomDetails[Rooms.subroomMetaKeys.Name] ?? "DATABASE ERROR", + IsSandbox: subroomDetails[Rooms.subroomMetaKeys.IsSandbox] ? parseBooleanDefault(subroomDetails[Rooms.subroomMetaKeys.IsSandbox], false) : false, + CanMatchmakeInto: subroomDetails[Rooms.subroomMetaKeys.IsSandbox] ? parseBooleanDefault(subroomDetails[Rooms.subroomMetaKeys.IsSandbox], true) : undefined, + DataBlobName: subroomDetails[Rooms.subroomMetaKeys.DataBlobName] ?? "", + MaxPlayers: subroomDetails[Rooms.subroomMetaKeys.MaxPlayers] ? parseInt(subroomDetails[Rooms.subroomMetaKeys.MaxPlayers]) : 1, + DataModifiedAt: subroomDetails[Rooms.subroomMetaKeys.DataModifiedAt] ?? new Date().toISOString() + }); + } + + return room; + } + +} \ No newline at end of file diff --git a/src/data/content/rooms.ts b/src/data/content/rooms.ts index 088c07a..174d678 100644 --- a/src/data/content/rooms.ts +++ b/src/data/content/rooms.ts @@ -1,8 +1,218 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { it } from "node:test"; +import { Redis } from "../../db.ts"; +import { RootPath } from "./baseimages.ts"; +import { BuiltinRoom, RoomState } from "./roomtypes.ts"; +import { RoomFetch } from "./room.ts"; + +const rooms = JSON.parse(Deno.readTextFileSync(`${RootPath}/res/rooms.json`)) as BuiltinRoom[]; + class RoomsBase { + readonly roomMetaKeys = { // hash keys + RoomId: "id", + Name: "name", + Description: "desc", + CreatorPlayerId: "creatorId", + ImageName: "imagename", + State: "state", + Accessibility: "access", + SupportsLevelVoting: "levelvoting", + IsAGRoom: "isagroom", + IsDormRoom: "isdorm", + CloningAllowed: "cloneable", + SupportsScreens: "can-screen", + SupportsWalkVR: "can-walkvr", + SupportsTeleportVR: "can-televr", + AllowsJuniors: "juniors", + RoomWarningMask: "warningmask", + CustomRoomWarning: "warning", + DisableMicAutoMute: "disableautomute" + } + readonly subroomMetaKeys = { // hash keys + Name: "name", + RoomSceneLocationId: "location", + IsSandbox: "issandbox", + CanMatchmakeInto: "matchmakeable", + RoomSceneId: "sceneid", + DataBlobName: "datablob", + MaxPlayers: "playercap", + DataModifiedAt: "modifiedat" + } + readonly roomRootKeys = { + CheerCount: "cheers", // string + CheerPids: "cheers-players", // set + VisitCount: "visits", // string + FavoriteCount: "favorites", // string + FavoritePids: "favorites-players", // set + Subrooms: "subrooms", // set + Meta: "roommeta" // hash + } + readonly subroomRootKeys = { + Meta: "scenemeta" + } + readonly miscKeys = { + BuiltinGenerated: "builtinrooms-done", + AGRooms: "agrooms" + } + + getAllBuiltinRooms() { + return rooms; + } + + async get(id: number) { + try { + return await new RoomFetch({ roomId: id }).fetch(); + } catch { + return null; + } + } + + async getByName(name: string) { + try { + return await new RoomFetch({ roomName: name }).fetch(); + } catch { + return null; + } + } + + async getAllBuiltinRoomGenerations() { + const ids = await Redis.Database.smembers(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms)); + const parsedIds = ids.map(val => parseInt(val)).filter(val => !isNaN(val)); + return (await Promise.all(parsedIds.map(id => this.get(id)))).filter(val => val !== null); + } + + async #getAvailableRoomId() { + let id = Math.round(Math.random() * Math.pow(2, 31)); + while ((await Redis.Database.exists(Redis.buildKey(Redis.KeyGroups.Rooms.Root, id.toString(), this.roomRootKeys.Meta))) >= 1) + id = await this.#getAvailableRoomId(); + return id; + } + + async #getAvailableSubRoomId(roomid: number) { + let id = Math.round(Math.random() * Math.pow(2, 31)); + while ((await Redis.Database.exists( + Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + roomid.toString(), + this.roomRootKeys.Subrooms, + id.toString(), + this.subroomRootKeys.Meta + ))) >= 1) + id = await this.#getAvailableSubRoomId(roomid); + return id; + } + + async generateBuiltinRooms() { + + if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true; + for (const builtinRoom of rooms) { + const newId = await this.#getAvailableRoomId(); + await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId); + await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Room_Names, builtinRoom.Name), newId); + const rootKey = Redis.buildKey(Redis.KeyGroups.Rooms.Root, newId.toString()); + + const roomMetaRootKey = Redis.buildKey(rootKey, this.roomRootKeys.Meta); + await Promise.all([ + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomId, newId), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Name, builtinRoom.Name), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Description, builtinRoom.Description), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CreatorPlayerId, `1`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.ImageName, `${builtinRoom.Name}.png`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.State, `${RoomState.Active}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Accessibility, `${builtinRoom.Accessibility}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsLevelVoting, `${builtinRoom.SupportsLevelVoting}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsAGRoom, "true"), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsDormRoom, "false"), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CloningAllowed, `${builtinRoom.CloningAllowed}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsScreens, `${builtinRoom.SupportsScreens}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsWalkVR, `${builtinRoom.SupportsWalkVR}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsTeleportVR, `${builtinRoom.SupportsTeleportVR}`), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.AllowsJuniors, "true"), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomWarningMask, 0), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CustomRoomWarning, ""), + Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.DisableMicAutoMute, "false"), + ]); + + for (const subroom of builtinRoom.Scenes) { + const newSubId = await this.#getAvailableSubRoomId(newId); + const subRootMetaKey = Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + newId.toString(), + this.roomRootKeys.Subrooms, + newSubId.toString(), + this.subroomRootKeys.Meta + ); + + await Promise.all([ + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.RoomSceneLocationId, subroom.RoomSceneLocationId), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.Name, subroom.RoomSceneLocationId), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.IsSandbox, `${subroom.IsSandbox}`), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataBlobName, ""), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.MaxPlayers, subroom.MaxPlayers), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.CanMatchmakeInto, `${subroom.CanMatchmakeInto}`), + Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataModifiedAt, new Date().toISOString()), + ]); + await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, newId.toString(), this.roomRootKeys.Subrooms), newSubId); + } + } + Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated), "1"); + return false; + + } + + async getIdFromName(name: string) { + const unparsedId = await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Room_Names, name)); + if (!unparsedId) return null; + const parsedId = parseInt(unparsedId); + if (isNaN(parsedId)) return null; + return parsedId; + } + + async getNameFromId(id: number) { + const name = await Redis.Database.hget(Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + id.toString(), + this.roomRootKeys.Meta + ), this.roomMetaKeys.Name); + if (!name) return null; + return name; + } + + async getSubroomIdsFromRoom(id: number): Promise; + async getSubroomIdsFromRoom(id: number, stringify: false): Promise; + async getSubroomIdsFromRoom(id: number, stringify: boolean | undefined = false): Promise { + const ids = await Redis.Database.smembers(Redis.buildKey( + Redis.KeyGroups.Rooms.Root, + id.toString(), + this.roomRootKeys.Subrooms + )); + const parsedIds = ids.map(val => parseInt(val)).filter(val => !isNaN(val)); + + if (!stringify) return parsedIds; + else return parsedIds.map(val => val.toString()); + } } const Rooms = new RoomsBase(); + +export { rooms as BuiltinRooms }; export default Rooms; \ No newline at end of file diff --git a/src/data/content/roomtypes.ts b/src/data/content/roomtypes.ts index b4d9b67..a2c75c2 100644 --- a/src/data/content/roomtypes.ts +++ b/src/data/content/roomtypes.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export enum IntegratedRoomScene { Calibration = "f5fbd9c9-e853-4036-9d48-5f68e861af04", DormRoom = "76d98498-60a1-430c-ab76-b54a29b7a163", @@ -60,6 +77,30 @@ export enum RoomAccessibility { Unlisted } +export interface BuiltinScene { + Name: string, + RoomSceneLocationId: IntegratedRoomScene, + IsSandbox: boolean, + CanMatchmakeInto: boolean, + SupportsJoinInProgress: boolean, + UseLevelBasedMatchmaking: boolean, + UseAgeBasedMatchmaking: boolean, + UseRecRoyaleMatchmaking: boolean, + MaxPlayers: number +} + +export interface BuiltinRoom { + Name: string, + Description: string, + Accessibility: RoomAccessibility, + SupportsLevelVoting: boolean, + CloningAllowed: boolean, + SupportsScreens: boolean, + SupportsWalkVR: boolean, + SupportsTeleportVR: boolean, + Scenes: BuiltinScene[] +} + export interface Room { RoomId: number, Name: string, @@ -72,8 +113,6 @@ export interface Room { IsAGRoom: boolean, IsDormRoom?: boolean, CloningAllowed: boolean, - SupportsVRLow?: boolean, - SupportsMobile?: boolean, SupportsScreens: boolean, SupportsWalkVR: boolean, SupportsTeleportVR: boolean, @@ -108,7 +147,7 @@ export interface TagDTO { export interface RoomScene { RoomSceneId: number, RoomId: number, - RoomSceneLocationId: IntegratedRoomScene, + RoomSceneLocationId: string, Name: string, IsSandbox: boolean, DataBlobName: string, diff --git a/src/data/content/settings.ts b/src/data/content/settings.ts index cd7699a..c0441ac 100644 --- a/src/data/content/settings.ts +++ b/src/data/content/settings.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export enum SettingKey { PlayerStatusVisibility = "PlayerStatusVisibility", VRMovementMode = "VR_MOVEMENT_MODE", diff --git a/src/data/live/base.ts b/src/data/live/base.ts index da63ce0..e197fbf 100644 --- a/src/data/live/base.ts +++ b/src/data/live/base.ts @@ -1,7 +1,39 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Profile } from "../profiles.ts"; +import Instances from "./instances.ts"; +import { MatchmakingErrorCode, RoomInstance } from "./types.ts"; const loginLocks: Map = new Map(); +interface MatchmakingOptions { + roomName: string, + subRoomName?: string, + private?: boolean, + instanceId?: string, + profile: Profile +} + +interface MatchmakingResponse { + errorCode: MatchmakingErrorCode, + roomInstance?: RoomInstance +} + class MatchmakingBase { createLoginLock(prof: Profile, lock: string) { @@ -19,6 +51,33 @@ class MatchmakingBase { loginLocks.delete(prof.getId()); } + matchmake(options: MatchmakingOptions) { + + if (options.instanceId) { + + // get instance + // if instance exists, check private + + } + /* + if roomname is dormroom, create the profile's dormroom if it does not exist + set the target room to the profile's dormroom id + + get all public instances for roomname + filter out private and full instances + if a subroomname was specified, filter out subrooms that are not that subroom + + pick an instance of the given instances at random + if none exist, create one + use only matchmakeable subrooms + if none are matchmakeable, go to "Home" + if "Home" does not exist, go to the first index + + go to that instance + */ + + } + } const Matchmaking = new MatchmakingBase(); diff --git a/src/data/live/instances.ts b/src/data/live/instances.ts index baab969..8eeb54d 100644 --- a/src/data/live/instances.ts +++ b/src/data/live/instances.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import Logging from "@proxnet/undead-logging"; import { Profile } from "../profiles.ts"; import { RoomInstance, InstanceOptions } from "./types.ts"; @@ -7,15 +24,25 @@ const log = new Logging("Instances"); const config = Config.getConfig(); -// `Profile` isn't synchronized. Fix this. const instancePlayers: Map> = new Map(); /** * `Map` */ const instanceMap: Map> = new Map(); +/** + * `Map` + */ +const instanceRoomMap: Map = new Map(); class InstancesBase { + getInstance(id: number) { + const instances = instancePlayers.keys(); + const instance = instances.find(val => val.roomInstanceId == id); + if (instance) return instance; + else return null; + } + getAllInstances() { return new Set([...instanceMap.values()].flatMap(set => [...set])); } @@ -62,9 +89,8 @@ class InstancesBase { } updateGlobalInstancesIsFull() { - for (const instance of this.getAllInstances()) { + for (const instance of this.getAllInstances()) instance.isFull = this.getInstancePlayers(instance).size >= instance.maxCapacity; - } } updateSingleInstanceIsFull(instance: RoomInstance) { @@ -78,7 +104,7 @@ class InstancesBase { } #generateUniqueInstanceId() { - let newInstanceId = Math.round(Math.random() * Math.pow(2, 31)) + let newInstanceId = Math.round(Math.random() * Math.pow(2, 31)); const allInstances = this.getAllInstances(); while (Array.from(allInstances.values()).map(val => val.roomInstanceId).includes(newInstanceId)) newInstanceId = Math.round(Math.random() * Math.pow(2, 31)); return newInstanceId; @@ -119,6 +145,8 @@ class InstancesBase { this.getInstancePlayers(newInstance).add(options.FirstPlayer); } + return newInstance; + } /** diff --git a/src/data/live/presence.ts b/src/data/live/presence.ts index 1f031b4..a3e8b47 100644 --- a/src/data/live/presence.ts +++ b/src/data/live/presence.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { z } from "zod"; import { SettingKey } from "../content/settings.ts"; import { Profile } from "../profiles.ts"; diff --git a/src/data/live/types.ts b/src/data/live/types.ts index 3864641..9ab5270 100644 --- a/src/data/live/types.ts +++ b/src/data/live/types.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { IntegratedRoomScene, RoomDetails } from "../content/roomtypes.ts"; import { Profile } from "../profiles.ts"; @@ -38,7 +55,7 @@ export interface RoomInstance { roomInstanceId: number, roomId: number, subRoomId: number, - location: IntegratedRoomScene, + location: string, dataBlob?: string, eventId?: number, photonRegionId: PhotonRegionCodeString, @@ -88,4 +105,40 @@ export interface PlayerPresence { deviceClass: DeviceClass; vrMovementMode: VRMovementMode; roomInstance: RoomInstance; +} + +export enum MatchmakingErrorCode { + Success, + NoSuchGame, + PlayerNotOnline, + InsufficientSpace, + EventNotStarted, + EventAlreadyFinished, + EventCreatorNotReady, + BlockedFromRoom, + ProfileLocked, + NoBirthday, + MarkedForDelete, + JuniorNotAllowed, + Banned, + AlreadyInBestInstance, + InsufficientRelationship, + UpdateRequired = 16, + AlreadyInTargetInstance, + RegistrationRequired, + UGCNotAllowed, + NoSuchRoom, + RoomCreatorNotReady, + RoomIsNotActive, + RoomBlockedByCreator, + RoomBlockingCreator, + RoomIsPrivate, + RoomInstanceIsPrivate, + DeviceClassNotSupported = 30, + VRMovementModeNotSupportedByRoomOwner, + EventIsPrivate = 35, + RoomInviteExpired = 40, + NoAvailableRegion = 45, + NotorietyTooPoor = 50, + BannedFromRoom = 55 } \ No newline at end of file diff --git a/src/data/objectives.ts b/src/data/objectives.ts index 7fe8753..115e777 100644 --- a/src/data/objectives.ts +++ b/src/data/objectives.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export enum ObjectiveType { Default = -1, FirstSessionOfDay = 1, diff --git a/src/data/platformtypes.ts b/src/data/platformtypes.ts index 49be607..e33e56e 100644 --- a/src/data/platformtypes.ts +++ b/src/data/platformtypes.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export enum PlatformMask { None = 0, Steam = 1, diff --git a/src/data/profile/avatar.ts b/src/data/profile/avatar.ts index a5459c7..d47a0ea 100644 --- a/src/data/profile/avatar.ts +++ b/src/data/profile/avatar.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "../../db.ts"; import { ProfileContentManager } from "./base/profilemanagerbase.ts"; diff --git a/src/data/profile/base/events.ts b/src/data/profile/base/events.ts index d3a13a5..92b322a 100644 --- a/src/data/profile/base/events.ts +++ b/src/data/profile/base/events.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export class ProfileEventsManager { diff --git a/src/data/profile/base/profilemanagerbase.ts b/src/data/profile/base/profilemanagerbase.ts index 7f7ab96..a49890b 100644 --- a/src/data/profile/base/profilemanagerbase.ts +++ b/src/data/profile/base/profilemanagerbase.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export class ProfileContentManager { constructor(profileId: number) { diff --git a/src/data/profile/progression.ts b/src/data/profile/progression.ts index c64fe8b..663d1e1 100644 --- a/src/data/profile/progression.ts +++ b/src/data/profile/progression.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import Logging from "@proxnet/undead-logging"; import { GameConfigs } from "../config.ts"; import { ProfileContentManager } from "./base/profilemanagerbase.ts"; diff --git a/src/data/profile/relationships.ts b/src/data/profile/relationships.ts index 20560b4..320c247 100644 --- a/src/data/profile/relationships.ts +++ b/src/data/profile/relationships.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "../../db.ts"; import UnifiedProfile, { Profile } from "../profiles.ts"; import { ProfileContentManager } from "./base/profilemanagerbase.ts"; diff --git a/src/data/profile/reputation.ts b/src/data/profile/reputation.ts index 3210586..0fa098d 100644 --- a/src/data/profile/reputation.ts +++ b/src/data/profile/reputation.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { ProfileContentManager } from "./base/profilemanagerbase.ts"; export class ProfileReputationManager extends ProfileContentManager { diff --git a/src/data/profile/settings.ts b/src/data/profile/settings.ts index 26761cc..f568d30 100644 --- a/src/data/profile/settings.ts +++ b/src/data/profile/settings.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "../../db.ts"; import { SettingKey } from "../content/settings.ts"; import { ProfileContentManager } from "./base/profilemanagerbase.ts"; @@ -24,6 +41,10 @@ export class ProfileSettingsManager extends ProfileContentManager { await Redis.Database.hset(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings), key, value); } + async setSettingRaw(key: string, value: string) { + await Redis.Database.hset(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings), key, value); + } + async delSetting(key: SettingKey) { await Redis.Database.hdel(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings), key); } diff --git a/src/data/profiles.ts b/src/data/profiles.ts index c67d0cb..a308f31 100644 --- a/src/data/profiles.ts +++ b/src/data/profiles.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "../db.ts"; import Dictionary from "./usernames.ts"; import { Config } from "../config.ts"; diff --git a/src/data/usernames.ts b/src/data/usernames.ts index 64ca4c9..9af3541 100644 --- a/src/data/usernames.ts +++ b/src/data/usernames.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + const Dictionary = { Adjectives: [ "Amazing", diff --git a/src/data/users.ts b/src/data/users.ts index 2b91d76..407d587 100644 --- a/src/data/users.ts +++ b/src/data/users.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "../db.ts"; import * as JsonWebToken from "@gz/jwt"; import { Config } from "../config.ts"; diff --git a/src/db.ts b/src/db.ts index eea5c80..5bf661e 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Redis } from "ioredis"; import * as Config from "./config.ts"; import Logging from "@proxnet/undead-logging"; @@ -76,6 +93,7 @@ export const KeyGroups = { Friends: "friends", Ignoring: "ignore", Muted: "muted", + Favorites: "favorites" }, Avatar: { Root: "avatar", @@ -85,6 +103,10 @@ export const KeyGroups = { Face: "face" } }, + Room_Names: "room-names", + Rooms: { + Root: "room", + }, Operators: "operators", Users: { Root: "users", diff --git a/src/discord.ts b/src/discord.ts index 58c1088..f0b4ea6 100644 --- a/src/discord.ts +++ b/src/discord.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import * as discord from "discord.js"; import { Config } from "./config.ts"; import Logging from "@proxnet/undead-logging"; diff --git a/src/main.ts b/src/main.ts index 8c39498..64ac3df 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import * as Log from "@proxnet/undead-logging"; import * as Config from "./config.ts"; import { Database } from "./db.ts"; @@ -10,6 +27,7 @@ import { decode } from "@gz/jwt"; import UnifiedProfile, { ProfileTokenFormat } from "./data/profiles.ts"; import { SocketHandoff } from "./socket/handoff.ts"; import { SignalRSocketHandler } from "./socket/socket.ts"; +import Rooms from "./data/content/rooms.ts"; const instanceId = generateRandomString(64); @@ -42,11 +60,6 @@ try { Deno.exit(1); } -const port = config.web.api.port; -const host = config.web.api.host; - -log.n(`Starting HTTP server on http://${host}:${port}`); - const app = express(); app.disable("etag"); @@ -92,11 +105,13 @@ app.use(notifyRouter.route.path, notifyRouter.route.router); app.use(cdnRouter.route.path, cdnRouter.route.router); app.use((rq: express.Request, rs: express.Response) => { - log.e(`${APIUtils.getSrcIpDefault(rq)} 404 ${rq.method} ${rq.url.toString()}`); + log.e(`${rs.locals.reqId} ${APIUtils.getSrcIpDefault(rq)} 404 ${rq.method} ${rq.url.toString()}`); rs.statusCode = 404; rs.json(APIUtils.genericResponseFormat(true, "Endpoint not found. Check your syntax and/or method.")); }); +if (!(await Rooms.generateBuiltinRooms())) log.i(`Generated built-in rooms`); + try { /** @@ -127,6 +142,11 @@ try { else return { token: decodedToken, valid: true } as AuthResult; } + const port = config.web.api.port; + const host = config.web.api.host; + + log.n(`Starting HTTP server on http://${host}:${port}`); + const abort = new AbortController(); // Galvanic WebSocket @@ -186,11 +206,6 @@ try { for (const handoff of SocketHandoff.all()) handoff.complete(); }); - - /* - PLACE TEST HERE - */ - if (!(await UnifiedProfile.existsByName("Coach"))) UnifiedProfile.create({ username: "Coach", id: 1 }); // create Coach id 1 if they do not exist if (!(await UnifiedProfile.existsByName("Server"))) UnifiedProfile.create({ username: "Server", id: 2 }); // create Server id 2 if they do not exist diff --git a/src/routes/account.ts b/src/routes/account.ts index f9af5fb..55d1379 100644 --- a/src/routes/account.ts +++ b/src/routes/account.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { route as AccountRoute } from "./account/account.ts"; diff --git a/src/routes/account/account.ts b/src/routes/account/account.ts index 8a25b63..2bd9cbf 100644 --- a/src/routes/account/account.ts +++ b/src/routes/account/account.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; import express from "express"; import { Profile } from "../../data/profiles.ts"; diff --git a/src/routes/api.ts b/src/routes/api.ts index 82207be..c9bff07 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { route as VersionCheckRoute } from "./api/versioncheck.ts"; import { route as ConfigRoute } from "./api/config.ts"; @@ -10,6 +27,9 @@ import { route as SettingsRoute } from "./api/settings.ts"; import { route as PlayerSubscriptionsRoute } from "./api/playersubscriptions.ts"; import { route as PlayerReputationRoute } from "./api/playerReputation.ts"; import { route as AvatarRoute } from "./api/avatar.ts"; +import { route as QuickPlayRoute } from "./api/quickplay.ts"; +import { route as RoomsRoute } from "./api/rooms.ts"; +import { route as ChallengeRoute } from "./api/challenge.ts"; export const route = APIUtils.createRouter("/api"); @@ -23,4 +43,7 @@ route.router.use(PlayersRoute.path, PlayersRoute.router); route.router.use(SettingsRoute.path, SettingsRoute.router); route.router.use(PlayerSubscriptionsRoute.path, PlayerSubscriptionsRoute.router); route.router.use(PlayerReputationRoute.path, PlayerReputationRoute.router); -route.router.use(AvatarRoute.path, AvatarRoute.router); \ No newline at end of file +route.router.use(AvatarRoute.path, AvatarRoute.router); +route.router.use(QuickPlayRoute.path, QuickPlayRoute.router); +route.router.use(RoomsRoute.path, RoomsRoute.router); +route.router.use(ChallengeRoute.path, ChallengeRoute.router); \ No newline at end of file diff --git a/src/routes/api/PlayerReporting.ts b/src/routes/api/PlayerReporting.ts index 26e38e6..b28c163 100644 --- a/src/routes/api/PlayerReporting.ts +++ b/src/routes/api/PlayerReporting.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils, NoBody } from "../../apiutils.ts"; import express from "express"; import Logging from "@proxnet/undead-logging"; diff --git a/src/routes/api/avatar.ts b/src/routes/api/avatar.ts index 016581c..17c2193 100644 --- a/src/routes/api/avatar.ts +++ b/src/routes/api/avatar.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; import { AuthType } from "../../data/users.ts"; @@ -12,4 +29,15 @@ route.router.get('/v2', rs.json(await rs.locals.profile.Avatar.getAvatar()); }, +); + +route.router.get('/v4/items', + + APIUtils.Authentication, + APIUtils.AuthenticationType(AuthType.Game), + + (_rq, rs) => { + rs.json([]); + } + ); \ No newline at end of file diff --git a/src/routes/api/challenge.ts b/src/routes/api/challenge.ts new file mode 100644 index 0000000..9e17317 --- /dev/null +++ b/src/routes/api/challenge.ts @@ -0,0 +1,22 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { APIUtils } from "../../apiutils.ts"; + +export const route = APIUtils.createRouter("/challenge"); + +// create router for now \ No newline at end of file diff --git a/src/routes/api/config.ts b/src/routes/api/config.ts index 2306071..c314f5d 100644 --- a/src/routes/api/config.ts +++ b/src/routes/api/config.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; import { GameConfigs } from "../../data/config.ts"; diff --git a/src/routes/api/gameconfigs.ts b/src/routes/api/gameconfigs.ts index 32358b7..94e44de 100644 --- a/src/routes/api/gameconfigs.ts +++ b/src/routes/api/gameconfigs.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; export const route = APIUtils.createRouter("/gameconfigs"); diff --git a/src/routes/api/messages.ts b/src/routes/api/messages.ts index 48d5f2e..d3cff2e 100644 --- a/src/routes/api/messages.ts +++ b/src/routes/api/messages.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; export const route = APIUtils.createRouter("/messages"); diff --git a/src/routes/api/playerReputation.ts b/src/routes/api/playerReputation.ts index bcb962e..90c3fa2 100644 --- a/src/routes/api/playerReputation.ts +++ b/src/routes/api/playerReputation.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; import UnifiedProfile from "../../data/profiles.ts"; import { AuthType } from "../../data/users.ts"; diff --git a/src/routes/api/players.ts b/src/routes/api/players.ts index ea74499..6dab77d 100644 --- a/src/routes/api/players.ts +++ b/src/routes/api/players.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import Logging from "@proxnet/undead-logging"; import { APIUtils } from "../../apiutils.ts"; import express from "express"; diff --git a/src/routes/api/playersubscriptions.ts b/src/routes/api/playersubscriptions.ts index 2512c38..08549e4 100644 --- a/src/routes/api/playersubscriptions.ts +++ b/src/routes/api/playersubscriptions.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; export const route = APIUtils.createRouter("/playersubscriptions"); diff --git a/src/routes/api/quickplay.ts b/src/routes/api/quickplay.ts new file mode 100644 index 0000000..5830840 --- /dev/null +++ b/src/routes/api/quickplay.ts @@ -0,0 +1,32 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { APIUtils } from "../../apiutils.ts"; +import { AuthType } from "../../data/users.ts"; + +export const route = APIUtils.createRouter("/quickPlay"); + +route.router.get('/v1/getandclear', + + APIUtils.Authentication, + APIUtils.AuthenticationType(AuthType.Game), + + (_rq, rs) => { + rs.json({}); + } + +); \ No newline at end of file diff --git a/src/routes/api/relationships.ts b/src/routes/api/relationships.ts index ad4e07f..b5f5770 100644 --- a/src/routes/api/relationships.ts +++ b/src/routes/api/relationships.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { z } from "zod"; import { APIUtils, NoBody } from "../../apiutils.ts"; import { AuthType } from "../../data/users.ts"; diff --git a/src/routes/api/rooms.ts b/src/routes/api/rooms.ts new file mode 100644 index 0000000..d0f04e5 --- /dev/null +++ b/src/routes/api/rooms.ts @@ -0,0 +1,49 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { APIUtils } from "../../apiutils.ts"; +import Rooms from "../../data/content/rooms.ts"; +import { AuthType } from "../../data/users.ts"; +import express from "express"; + +export const route = APIUtils.createRouter("/rooms"); + +interface Params { + roomId?: string +} + +route.router.get('/v4/details/:roomId', + + APIUtils.Authentication, + APIUtils.AuthenticationType(AuthType.Game), + + async (rq: express.Request, rs: express.Response) => { + if (!rq.params.roomId) { + rs.sendStatus(400); + return; + } + const parsedId = parseInt(rq.params.roomId); + if (isNaN(parsedId)) { + rs.sendStatus(400); + return; + } + const room = await Rooms.get(parsedId); + if (room == null) rs.sendStatus(404); + else rs.json(room); + }, + +) \ No newline at end of file diff --git a/src/routes/api/settings.ts b/src/routes/api/settings.ts index 90df3e9..5e29795 100644 --- a/src/routes/api/settings.ts +++ b/src/routes/api/settings.ts @@ -1,6 +1,25 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import Logging from "@proxnet/undead-logging"; -import { APIUtils } from "../../apiutils.ts"; +import { APIUtils, NoBody } from "../../apiutils.ts"; import { AuthType } from "../../data/users.ts"; +import z from "zod"; +import express from "express"; const log = new Logging("SettingsRoute"); @@ -19,4 +38,32 @@ route.router.get('/v2', } +); + +interface SettingsSetBody { + Key: string; + Value: string; +} + +const SettingsSetSchema = z.object({ + Key: z.string(), + Value: z.string() +}); + +route.router.post('/v2/set', + + APIUtils.Authentication, + APIUtils.AuthenticationType(AuthType.Game), + express.json(), + APIUtils.validateRequestBody(SettingsSetSchema), + + (rq: express.Request, rs: express.Response) => { + rs.locals.profile.Settings.setSettingRaw(rq.body.Key, rq.body.Value), + rs.json({ + Succeeded: true, + Error: "", + ShouldRetry: false + }); + } + ); \ No newline at end of file diff --git a/src/routes/api/versioncheck.ts b/src/routes/api/versioncheck.ts index 20db52b..007c063 100644 --- a/src/routes/api/versioncheck.ts +++ b/src/routes/api/versioncheck.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; export const route = APIUtils.createRouter("/versioncheck"); diff --git a/src/routes/auth.ts b/src/routes/auth.ts index 07b38fa..1889b6a 100644 --- a/src/routes/auth.ts +++ b/src/routes/auth.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { route as CachedLoginRoute } from "./auth/cachedlogin.ts"; import { route as ConnectRoute } from "./auth/connect.ts"; diff --git a/src/routes/auth/cachedlogin.ts b/src/routes/auth/cachedlogin.ts index e0599c1..cfc1067 100644 --- a/src/routes/auth/cachedlogin.ts +++ b/src/routes/auth/cachedlogin.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; import { AuthType } from "../../data/users.ts"; diff --git a/src/routes/auth/connect.ts b/src/routes/auth/connect.ts index 157e59f..b6aa2c0 100644 --- a/src/routes/auth/connect.ts +++ b/src/routes/auth/connect.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils, NoBody } from "../../apiutils.ts"; import express from "express"; import UnifiedProfile, { Profile } from "../../data/profiles.ts"; diff --git a/src/routes/cdn.ts b/src/routes/cdn.ts index 84f5d94..507092f 100644 --- a/src/routes/cdn.ts +++ b/src/routes/cdn.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { route as ConfigRoute } from "./cdn/config.ts"; diff --git a/src/routes/cdn/config.ts b/src/routes/cdn/config.ts index fcc4290..94001a5 100644 --- a/src/routes/cdn/config.ts +++ b/src/routes/cdn/config.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../../apiutils.ts"; export const route = APIUtils.createRouter("/config"); diff --git a/src/routes/img.ts b/src/routes/img.ts index 8232943..dc4e5ec 100644 --- a/src/routes/img.ts +++ b/src/routes/img.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils, NoBody } from "../apiutils.ts"; import * as BaseImages from "../data/content/baseimages.ts"; import express from "express"; diff --git a/src/routes/match.ts b/src/routes/match.ts index bade688..43e14e5 100644 --- a/src/routes/match.ts +++ b/src/routes/match.ts @@ -1,6 +1,25 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { route as PlayerRoute } from "./match/player.ts"; +import { route as GotoRoute } from "./match/goto.ts"; export const route = APIUtils.createRouter('/match'); -route.router.use(PlayerRoute.path, PlayerRoute.router); \ No newline at end of file +route.router.use(PlayerRoute.path, PlayerRoute.router); +route.router.use(GotoRoute.path, GotoRoute.router); \ No newline at end of file diff --git a/src/routes/match/goto.ts b/src/routes/match/goto.ts new file mode 100644 index 0000000..534e9a7 --- /dev/null +++ b/src/routes/match/goto.ts @@ -0,0 +1,46 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + +import { APIUtils } from "../../apiutils.ts"; +import Matchmaking from "../../data/live/base.ts"; +import { MatchmakingErrorCode } from "../../data/live/types.ts"; +import { AuthType } from "../../data/users.ts"; +import express from "express"; + +export const route = APIUtils.createRouter('/goto'); + +interface MatchmakingParams { + roomName?: string, + subRoomName?: string +} + +route.router.post('/room/:roomName', + + APIUtils.Authentication, + APIUtils.AuthenticationType(AuthType.Game), + + (rq: express.Request, rs: express.Response) => { + if (!rq.params.roomName) { + rs.json({ + errorCode: MatchmakingErrorCode.NoSuchRoom + }); + return; + } + rs.json(Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName })); + }, + +); \ No newline at end of file diff --git a/src/routes/match/player.ts b/src/routes/match/player.ts index 194c47c..9bf929f 100644 --- a/src/routes/match/player.ts +++ b/src/routes/match/player.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { z } from "zod"; import { APIUtils, NoBody } from "../../apiutils.ts"; import express from "express"; diff --git a/src/routes/nameserver.ts b/src/routes/nameserver.ts index c3cce31..a93c62c 100644 --- a/src/routes/nameserver.ts +++ b/src/routes/nameserver.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { Config } from "../config.ts"; diff --git a/src/routes/user.ts b/src/routes/user.ts index 56f6666..4955288 100644 --- a/src/routes/user.ts +++ b/src/routes/user.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils, getSrcIpDefault, NoBody } from "../apiutils.ts"; // @ts-types = "npm:@types/express" import express from "express"; diff --git a/src/socket/handoff.ts b/src/socket/handoff.ts index 9092a69..ffc526b 100644 --- a/src/socket/handoff.ts +++ b/src/socket/handoff.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + const handoffs: Set = new Set(); function randomId(length: number) { diff --git a/src/socket/route.ts b/src/socket/route.ts index e96dfda..011eca1 100644 --- a/src/socket/route.ts +++ b/src/socket/route.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { APIUtils } from "../apiutils.ts"; import { Config } from "../config.ts"; import { AuthType } from "../data/users.ts"; diff --git a/src/socket/socket.ts b/src/socket/socket.ts index 9a08baf..e190bc2 100644 --- a/src/socket/socket.ts +++ b/src/socket/socket.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Profile } from "../data/profiles.ts"; import Logging from "@proxnet/undead-logging"; import { diff --git a/src/socket/targets/SubscribeToPlayers.ts b/src/socket/targets/SubscribeToPlayers.ts index e62c63f..d160ad0 100644 --- a/src/socket/targets/SubscribeToPlayers.ts +++ b/src/socket/targets/SubscribeToPlayers.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { z } from "zod"; import { SocketTarget } from "./targetbase.ts"; diff --git a/src/socket/targets/targetbase.ts b/src/socket/targets/targetbase.ts index ff0a972..74c350e 100644 --- a/src/socket/targets/targetbase.ts +++ b/src/socket/targets/targetbase.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + export class SocketTarget { profileNotSetError = new Error("The profile on this target is not set."); diff --git a/src/socket/types.ts b/src/socket/types.ts index 4795419..9684d3b 100644 --- a/src/socket/types.ts +++ b/src/socket/types.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { z } from "zod"; export enum MessageKind { diff --git a/src/types/express.ts b/src/types/express.ts index f907509..d2f4548 100644 --- a/src/types/express.ts +++ b/src/types/express.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { Profile } from "../data/profiles.ts"; import { User } from "../data/users.ts"; diff --git a/src/types/http.ts b/src/types/http.ts index 45983ab..0e32514 100644 --- a/src/types/http.ts +++ b/src/types/http.ts @@ -1,3 +1,20 @@ +/* Galvanic Corrosion - Rec Room custom server for communities. + +Copyright (C) 2025 @zombieb (Discord / proxnet Gitea) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . */ + import { ProfileTokenFormat } from "../data/profiles.ts"; // Extend IncomingMessage interface to include custom properties