Still figuring out initial matchmaking hang (FROSTBITE). Lots of other changes.
- Added missing room images
- Removed internal rooms and disallow cloning some rooms
- License fixes
- Switched target to 20200306
- Socket header fixes
- Sockets are closed upon shutdown
* Sockets persist after being destroyed, fix
- Config changes for 20200306
- Settings initialized
- Name generation words cannot be longer than 9 characters
- Dorm generation changes and fixes
- Added some settings keys
- Matchmaking additions
* Instances are not yet updated to be or not to be in-progress
- Instance fixes and logging
- Image operation fixes
- DisplayName route start
- Challenge route start
- Default Amplitude key (i can see althe Amplitude requests are ignored
- Rate limiting ease
- GameConfigs properly queried and sent
- Many 'bulk' endpoints were added in or around 20200306
- Objective routes started
- DormRoom redirection in v2/name
- Client doesn't care if it gets 200 when setting prefs
- Balance/storefronts started
- Matchmaking goto/room timer and fixes
- Selfhosted Photon addition on the client sends matchmaking /photonregionpings, ignore since Photon is only one server in one region
This commit is contained in:
2
LICENSE
2
LICENSE
@@ -622,7 +622,7 @@ copy of the Program in return for a fee.
|
||||
LICENSE TEMPLATE
|
||||
|
||||
Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
delectable yum yum
|
||||
|
||||
Rec Room custom server for communities. Fast runtime and easy setup.<br>Built
|
||||
for Rec Room build 526 (Timestamp: 637098805133024772, Version: 20191120)
|
||||
for Rec Room build 1063 (Timestamp: 637191339113673856, Version: 20200306)
|
||||
|
||||
<img src="galv4.jpg" alt="drawing" width="200"/>
|
||||
|
||||
|
||||
BIN
res/img/Bowling.png
Normal file
BIN
res/img/Bowling.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
res/img/Crescendo.png
Normal file
BIN
res/img/Crescendo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/img/Lake.png
Normal file
BIN
res/img/Lake.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
BIN
res/img/LaserTag.png
Normal file
BIN
res/img/LaserTag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
BIN
res/img/MakerRoom.png
Normal file
BIN
res/img/MakerRoom.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
res/img/StuntRunner.png
Normal file
BIN
res/img/StuntRunner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
538
res/rooms.json
538
res/rooms.json
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -131,11 +131,11 @@ export function genericResponse(
|
||||
};
|
||||
}
|
||||
type RecNetResponse = {
|
||||
Success: boolean;
|
||||
Message: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
};
|
||||
export function RecNetResponse(success: boolean, message: string) {
|
||||
const msg: RecNetResponse = { Success: success, Message: message };
|
||||
export function RecNetResponse(success: boolean, message?: string) {
|
||||
const msg: RecNetResponse = { success: success, error: message };
|
||||
return (_rq: express.Request, rs: express.Response) => {
|
||||
rs.json(msg);
|
||||
};
|
||||
@@ -190,7 +190,7 @@ export class RateLimiter {
|
||||
* @param interval In seconds: rate at which hit counts will be cleared
|
||||
* @param limit Number of hits (inclusive) before requests are blocked
|
||||
*/
|
||||
constructor(interval: number, limit: number) {
|
||||
constructor(interval: number = 20, limit: number = 2) {
|
||||
this.#hitLimit = limit;
|
||||
|
||||
this.#intervalId = setInterval(() => {
|
||||
@@ -224,6 +224,11 @@ export class RateLimiter {
|
||||
nxt: express.NextFunction,
|
||||
) => {
|
||||
const address = getSrcIpDefault(rq);
|
||||
if (address == '127.0.0.1' || address == '::1') {
|
||||
nxt();
|
||||
return;
|
||||
}
|
||||
|
||||
this.#addressIncrement(address);
|
||||
|
||||
const hits = this.#getAddressHits(address);
|
||||
@@ -339,7 +344,7 @@ export function AuthenticationType(type: AuthType) {
|
||||
}
|
||||
|
||||
export function LoginLock(rq: express.Request<NoBody, NoBody, { LoginLock: string }>, rs: express.Response, nxt: express.NextFunction) {
|
||||
log.d(`LoginLock for ${rs.locals.profile.getId()}: ${rq.body.LoginLock}`);
|
||||
//log.d(`LoginLock for ${rs.locals.profile.getId()}: ${rq.body.LoginLock}`);
|
||||
const matches = Matchmaking.lockMatches(rs.locals.profile, rq.body.LoginLock);
|
||||
if (matches == null) {
|
||||
rs.json(genericResponseFormat(true, "Login Lock failure"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
import * as fs from "node:fs";
|
||||
import { PhotonRegionCodeString } from "./data/live/types.ts";
|
||||
import { PhotonRegionCodeNumber, PhotonRegionCodeString } from "./data/live/types.ts";
|
||||
|
||||
const log = new Logging("Config");
|
||||
|
||||
@@ -49,7 +49,7 @@ type PublicConfiguration = {
|
||||
levelScale: number;
|
||||
maxLevels: number;
|
||||
patches: string[];
|
||||
photonRegionId: PhotonRegionCodeString;
|
||||
photonRegionId: PhotonRegionCodeString | PhotonRegionCodeNumber;
|
||||
};
|
||||
|
||||
type LoggingConfiguration = {
|
||||
@@ -111,7 +111,7 @@ export const defaultConfig: GalvanicConfiguration = {
|
||||
levelScale: 1,
|
||||
maxLevels: 30,
|
||||
patches: [],
|
||||
photonRegionId: PhotonRegionCodeString.UnitedStates,
|
||||
photonRegionId: PhotonRegionCodeNumber.us,
|
||||
},
|
||||
logging: {
|
||||
notfound: false,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,10 +19,6 @@ import { Config } from "../config.ts";
|
||||
import { Redis } from "../db.ts";
|
||||
import { Objectives } from "./objectives.ts";
|
||||
|
||||
export type Config = {
|
||||
Key: string;
|
||||
Value: string;
|
||||
};
|
||||
export type LevelProgressionItem = {
|
||||
Level: number;
|
||||
RequiredXp: number;
|
||||
@@ -38,13 +34,13 @@ export type AutoMicMutingConfig = {
|
||||
MicSpamWarningStateVolumeMultiplier: number
|
||||
}
|
||||
export type PublicConfig = {
|
||||
ShareBaseUrl: string
|
||||
ServerMaintenance: {
|
||||
StartsInMinutes: number;
|
||||
};
|
||||
LevelProgressionMaps: LevelProgressionItem[];
|
||||
DailyObjectives: Objectives.Objective[][];
|
||||
ConfigTable: Config[];
|
||||
AutoMicMutingConfig: AutoMicMutingConfig
|
||||
AutoMicMutingConfig: AutoMicMutingConfig,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,7 +68,6 @@ export function getConfig() {
|
||||
},
|
||||
LevelProgressionMaps: generateLevelProgressionMap(),
|
||||
DailyObjectives: [],
|
||||
ConfigTable: [],
|
||||
AutoMicMutingConfig: {
|
||||
MicSpamVolumeThreshold: 1.125,
|
||||
MicVolumeSampleInterval: 0.25,
|
||||
@@ -82,7 +77,8 @@ export function getConfig() {
|
||||
MicSpamSamplePercentageForForceMute: 0.8,
|
||||
MicSpamSamplePercentageForForceMuteToEnd: 0.2,
|
||||
MicSpamWarningStateVolumeMultiplier: 0.25
|
||||
}
|
||||
},
|
||||
ShareBaseUrl: `${config.web.api.securepublichost ? 'https' : 'http'}://${config.web.api.publichost}/{0}` // {0} is replaced by the game
|
||||
};
|
||||
|
||||
return conf;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { Redis } from "../../db.ts";
|
||||
import { RootPath } from "./baseimages.ts";
|
||||
import { BuiltinRoom, RoomDetails, RoomState } from "./roomtypes.ts";
|
||||
import { BuiltinRoom, RoomAccessibility, RoomDetails, RoomState } from "./roomtypes.ts";
|
||||
import { RoomFetch } from "./room.ts";
|
||||
import { Profile } from "../profiles.ts";
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
@@ -172,7 +172,7 @@ class RoomsBase {
|
||||
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Room_Names, details.Room.Name), details.Room.RoomId);
|
||||
}
|
||||
|
||||
async cloneRoom(roomid: number, newname: string, newowner: Profile, dorm?: boolean) {
|
||||
async cloneRoom(roomid: number, newname: string, newowner: Profile) {
|
||||
const canBeClonedRaw = await Redis.Database.hget(Redis.buildKey(
|
||||
Redis.KeyGroups.Rooms.Root,
|
||||
roomid.toString(),
|
||||
@@ -183,22 +183,21 @@ class RoomsBase {
|
||||
try {
|
||||
canBeCloned = JSON.parse(canBeClonedRaw) as boolean;
|
||||
} catch {
|
||||
log.d(`Cloneroom ${roomid}: parse error`);
|
||||
return null;
|
||||
}
|
||||
if (!canBeCloned) {
|
||||
log.d(`Cloneroom ${roomid}: cannot be cloned`);
|
||||
return null;
|
||||
}
|
||||
if (!canBeCloned) return null;
|
||||
const beforeRoom = await Rooms.get(roomid); // room must exist
|
||||
if (!beforeRoom || !beforeRoom.Room.CloningAllowed) return null; // room must be cloneable
|
||||
if (await Rooms.getByName(newname) && beforeRoom.Room.Name !== 'DormRoom') return null; // room name cannot be taken
|
||||
if (beforeRoom.Room.Name !== 'DormRoom' && await Rooms.getByName(newname)) return null; // room name cannot be taken
|
||||
|
||||
const newId = await this.#getAvailableRoomId();
|
||||
beforeRoom.Room.CreatorPlayerId = newowner.getId();
|
||||
beforeRoom.Room.RoomId = newId;
|
||||
for (const subroom of beforeRoom.Scenes) subroom.RoomId = newId;
|
||||
if (dorm) {
|
||||
beforeRoom.Room.IsAGRoom = true;
|
||||
beforeRoom.Room.IsDormRoom = true;
|
||||
beforeRoom.Room.CloningAllowed = false;
|
||||
}
|
||||
|
||||
await Rooms.#setRoom(beforeRoom);
|
||||
return beforeRoom;
|
||||
@@ -211,19 +210,19 @@ class RoomsBase {
|
||||
Redis.KeyGroups.Rooms.PlayerDorms
|
||||
), player.getId().toString());
|
||||
if (unparsedId) {
|
||||
log.d(`Unparsed dorm ID for profile ${player.getId()}: ${unparsedId}`);
|
||||
const parsedId = parseInt(unparsedId);
|
||||
if (!isNaN(parsedId)) return await Rooms.get(parsedId);
|
||||
if (isNaN(parsedId)) {
|
||||
log.d(`Returning new dorm for profile ${player.getId()}`);
|
||||
return await Rooms.get(parsedId);
|
||||
}
|
||||
}
|
||||
|
||||
const baseDorm = await Rooms.getByName("DormRoom");
|
||||
|
||||
log.d('Base dorm existed');
|
||||
if (!baseDorm) return null;
|
||||
log.d('Base dorm was not null');
|
||||
const newDorm = await this.cloneRoom(baseDorm.Room.RoomId, "DormRoom", player, true);
|
||||
log.d('New dorm existed');
|
||||
const newDorm = await this.generateNewDorm(player);
|
||||
await this.#setRoom(newDorm);
|
||||
log.d(`New dorm for ${player.getId()} existed`);
|
||||
if (!newDorm) return null;
|
||||
log.d('New dorm was not null');
|
||||
log.d(`New dorm for ${player.getId()} was not null`);
|
||||
await Redis.Database.hset(Redis.buildKey(
|
||||
Redis.KeyGroups.Rooms.Root,
|
||||
Redis.KeyGroups.Rooms.PlayerDorms
|
||||
@@ -231,10 +230,59 @@ class RoomsBase {
|
||||
return newDorm;
|
||||
}
|
||||
|
||||
async generateNewDorm(player: Profile) {
|
||||
const id = await this.#getAvailableRoomId();
|
||||
const basedorm: RoomDetails = {
|
||||
Room: {
|
||||
RoomId: id,
|
||||
Name: `DormRoom`,
|
||||
Description: "Your private room.",
|
||||
CreatorPlayerId: player.getId(),
|
||||
ImageName: "DefaultProfileImage.png",
|
||||
State: RoomState.Active,
|
||||
Accessibility: RoomAccessibility.Private,
|
||||
SupportsLevelVoting: false,
|
||||
IsAGRoom: false,
|
||||
IsDormRoom: true,
|
||||
CloningAllowed: false,
|
||||
SupportsScreens: true,
|
||||
SupportsTeleportVR: true,
|
||||
SupportsWalkVR: true,
|
||||
AllowsJuniors: true,
|
||||
RoomWarningMask: 0,
|
||||
CustomRoomWarning: "",
|
||||
DisableMicAutoMute: false
|
||||
},
|
||||
Scenes: [
|
||||
{
|
||||
RoomId: id,
|
||||
RoomSceneId: 1,
|
||||
Name: "Home",
|
||||
RoomSceneLocationId: "76d98498-60a1-430c-ab76-b54a29b7a163",
|
||||
IsSandbox: true,
|
||||
CanMatchmakeInto: true,
|
||||
MaxPlayers: 4,
|
||||
DataBlobName: "",
|
||||
DataModifiedAt: new Date().toISOString()
|
||||
}
|
||||
],
|
||||
CoOwners: [],
|
||||
InvitedCoOwners: [],
|
||||
Hosts: [],
|
||||
InvitedHosts: [],
|
||||
CheerCount: 0,
|
||||
VisitCount: 0,
|
||||
FavoriteCount: 0,
|
||||
Tags: []
|
||||
}
|
||||
return basedorm;
|
||||
}
|
||||
|
||||
async generateBuiltinRooms() {
|
||||
|
||||
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
||||
for (const builtinRoom of rooms) {
|
||||
if (builtinRoom.Name == 'DormRoom') continue;
|
||||
const newId = await this.#getAvailableRoomId();
|
||||
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
||||
const roomDets: RoomDetails = {
|
||||
@@ -320,6 +368,11 @@ class RoomsBase {
|
||||
else return parsedIds.map(val => val.toString());
|
||||
}
|
||||
|
||||
getSubroomNameFromId(room: RoomDetails, subroomId: number) {
|
||||
const subroom = room.Scenes.find(scene => scene.RoomSceneId == subroomId);
|
||||
if (subroom) return subroom.Name;
|
||||
else return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -18,9 +18,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
export enum SettingKey {
|
||||
PlayerStatusVisibility = "PlayerStatusVisibility",
|
||||
VRMovementMode = "VR_MOVEMENT_MODE",
|
||||
RecroomOOBE = "Recroom.OOBE",
|
||||
PlayerSessionCount = "PlayerSessionCount",
|
||||
BACKPACK_FAVORITE_TOOL = "BACKPACK_FAVORITE_TOOL",
|
||||
Recroom_ChallengeMap = "Recroom.ChallengeMap",
|
||||
FIRST_TIME_IN_FLAGS = "FIRST_TIME_IN_FLAGS"
|
||||
}
|
||||
|
||||
export enum SettingDefault {
|
||||
PlayerStatusVisibility = "1",
|
||||
VRMovementMode = "0"
|
||||
PlayerStatusVisibility = "0",
|
||||
VRMovementMode = "0",
|
||||
RecroomOOBE = "100",
|
||||
PlayerSessionCount = "1",
|
||||
BACKPACK_FAVORITE_TOOL = "-1",
|
||||
Recroom_ChallengeMap = "0",
|
||||
FIRST_TIME_IN_FLAGS = "0"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -29,3 +29,22 @@ export enum StorefrontTypes {
|
||||
StuntRunner = 600,
|
||||
DormMirror = 700
|
||||
}
|
||||
|
||||
export enum StorefrontBalanceType {
|
||||
NonPurchasedNonP2P = -2,
|
||||
NonPurchasedP2P,
|
||||
SteamPurchased,
|
||||
OculusPurchased,
|
||||
PlayStationPurchased,
|
||||
MicrosoftPurchased,
|
||||
IOSPurchased = 5
|
||||
}
|
||||
|
||||
export enum CurrencyType {
|
||||
Invalid,
|
||||
LaserTagTickets,
|
||||
RecCenterTokens,
|
||||
LostSkullsGold = 100,
|
||||
DraculaSilver,
|
||||
RecRoyale_Season1 = 200
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -66,6 +66,7 @@ class MatchmakingBase {
|
||||
else if (instance.isPrivate) return { errorCode: MatchmakingErrorCode.RoomInstanceIsPrivate };
|
||||
|
||||
await Instances.setPlayerInstance(options.profile, instance);
|
||||
Instances.clearAllRoomEmptyInstances(instance.roomId);
|
||||
return { errorCode: MatchmakingErrorCode.Success, roomInstance: instance };
|
||||
}
|
||||
|
||||
@@ -73,36 +74,77 @@ class MatchmakingBase {
|
||||
|
||||
} else {
|
||||
|
||||
// check to make sure room exists, is not private, and is active
|
||||
const targetRoom = options.roomName !== 'DormRoom' ? await Rooms.getByName(options.roomName) : await Rooms.getProfileDormDefault(options.profile);
|
||||
if (!targetRoom) return { errorCode: MatchmakingErrorCode.NoSuchRoom };
|
||||
if (targetRoom.Room.Accessibility == RoomAccessibility.Private) return { errorCode: MatchmakingErrorCode.RoomIsPrivate };
|
||||
if (targetRoom.Room.Accessibility == RoomAccessibility.Private && targetRoom.Room.CreatorPlayerId !== options.profile.getId())
|
||||
return { errorCode: MatchmakingErrorCode.RoomIsPrivate };
|
||||
if (targetRoom.Room.State !== RoomState.Active) return { errorCode: MatchmakingErrorCode.RoomIsNotActive };
|
||||
const roomId = targetRoom.Room.RoomId;
|
||||
|
||||
Instances.clearAllRoomEmptyInstances(roomId);
|
||||
|
||||
// get all available instance
|
||||
let allInstances = Instances.getAllRoomInstances(roomId).values().toArray().filter(instance => !instance.isPrivate && !instance.isFull);
|
||||
const subroomId = targetRoom.Scenes.find(scene => scene.Name == options.subRoomName)?.RoomSceneId;
|
||||
if (subroomId) allInstances = allInstances.filter(instance => instance.subRoomId == subroomId);
|
||||
|
||||
const foundInstance = allInstances[Math.floor(Math.random() * allInstances.length)];
|
||||
// filter instances that do not support join in progress and are in progress
|
||||
const builtinRooms = Rooms.getAllBuiltinRooms();
|
||||
const joinInProgressSubrooms = builtinRooms.map(room =>
|
||||
({Name: room.Name, Scenes: room.Scenes.map(scene =>
|
||||
({Name: scene.Name, Supported: scene.SupportsJoinInProgress})
|
||||
)})
|
||||
);
|
||||
allInstances = allInstances.filter(instance => {
|
||||
const subroomName = Rooms.getSubroomNameFromId(targetRoom, instance.subRoomId);
|
||||
if (!subroomName) return false;
|
||||
const subrooms = joinInProgressSubrooms.find(room => room.Name == targetRoom.Room.Name);
|
||||
if (!subrooms) return false;
|
||||
const supportsJoinInProgress = subrooms.Scenes.find(subroom => subroom.Name == subroomName)?.Supported;
|
||||
if (supportsJoinInProgress) return true;
|
||||
else if (!instance.isInProgress) return true;
|
||||
else return false;
|
||||
});
|
||||
|
||||
allInstances = allInstances.sort((a, b) => {
|
||||
const pidsA = Instances.getInstancePlayers(a);
|
||||
const pidsB = Instances.getInstancePlayers(b);
|
||||
return pidsA.size - pidsB.size;
|
||||
}).reverse(); // Largest instances first
|
||||
|
||||
const foundInstance = allInstances[0];
|
||||
if (!foundInstance) {
|
||||
|
||||
const matchmakeableSubrooms = targetRoom.Scenes.filter(scene => scene.CanMatchmakeInto);
|
||||
const newInstance = Instances.createInstance({
|
||||
const newInstance = await Instances.createInstance({
|
||||
Room: targetRoom,
|
||||
SceneIndex: Math.floor(Math.random() * matchmakeableSubrooms.length),
|
||||
FirstPlayer: options.profile
|
||||
FirstPlayer: options.profile,
|
||||
Private: options.private,
|
||||
IsDorm: options.roomName == 'DormRoom'
|
||||
});
|
||||
|
||||
Instances.clearAllRoomEmptyInstances(roomId);
|
||||
return { errorCode: MatchmakingErrorCode.Success, roomInstance: newInstance };
|
||||
|
||||
} else {
|
||||
|
||||
const currentInstance = options.profile.getInstance();
|
||||
if (currentInstance?.roomInstanceId == foundInstance.roomInstanceId)
|
||||
return { errorCode: MatchmakingErrorCode.AlreadyInBestInstance };
|
||||
|
||||
await Instances.setPlayerInstance(options.profile, foundInstance);
|
||||
|
||||
Instances.clearAllRoomEmptyInstances(roomId);
|
||||
|
||||
return { errorCode: MatchmakingErrorCode.Success, roomInstance: foundInstance };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
import { Profile } from "../profiles.ts";
|
||||
import UnifiedProfile, { Profile } from "../profiles.ts";
|
||||
import { RoomInstance, InstanceOptions } from "./types.ts";
|
||||
import { Config } from "../../config.ts";
|
||||
import Presence from "./presence.ts";
|
||||
@@ -114,22 +114,28 @@ class InstancesBase {
|
||||
*
|
||||
* If one is, the player will be automatically added to the instance and their `profile.getInstance()` will be synchronized.
|
||||
*/
|
||||
createInstance(options: InstanceOptions) {
|
||||
async createInstance(options: InstanceOptions) {
|
||||
|
||||
const scene = options.Room.Scenes[options.SceneIndex];
|
||||
const newId = this.#generateUniqueInstanceId();
|
||||
if (!scene) throw new Error("The specified scene did not exist.");
|
||||
|
||||
let instanceName = scene.Name === "Home" || scene.Name === options.Room.Room.Name ? `^${options.Room.Room.Name}` : `^${options.Room.Room.Name}.${scene.Name}`;
|
||||
if (options.IsDorm) {
|
||||
const dormCreatorPlayer = UnifiedProfile.get(options.Room.Room.CreatorPlayerId);
|
||||
const player = await dormCreatorPlayer.export();
|
||||
if (player) instanceName = `@${player.displayName}'s Dorm`;
|
||||
}
|
||||
const newInstance: RoomInstance = {
|
||||
roomInstanceId: newId,
|
||||
roomId: options.Room.Room.RoomId,
|
||||
subRoomId: scene.RoomSceneId,
|
||||
location: scene.RoomSceneLocationId,
|
||||
dataBlob: scene.DataBlobName == "" ? undefined : scene.DataBlobName,
|
||||
dataBlob: scene.DataBlobName,
|
||||
eventId: options.EventId,
|
||||
photonRegionId: config.public.photonRegionId,
|
||||
photonRoomId: `20191120-GC${newId}`,
|
||||
name: scene.Name === "Home" ? `^${options.Room.Room.Name}` : `^${options.Room.Room.Name}.${scene.Name}`,
|
||||
photonRoomId: `20200306-GC${newId}`,
|
||||
name: instanceName,
|
||||
maxCapacity: scene.MaxPlayers,
|
||||
isFull: false,
|
||||
isPrivate: typeof options.Private !== 'boolean' ? false : options.Private,
|
||||
@@ -161,7 +167,9 @@ class InstancesBase {
|
||||
}
|
||||
|
||||
if (this.instanceCanFitPlayer(instance)) {
|
||||
this.getInstancePlayers(instance).add(player);
|
||||
const instancePlayers = this.getInstancePlayers(instance);
|
||||
log.i(`Player ${player.getId()} went to '${instance.name}' with ${instancePlayers.size} other players`);
|
||||
instancePlayers.add(player);
|
||||
|
||||
player.setInstance(instance);
|
||||
const pres = await Presence.get(player);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -58,7 +58,7 @@ export interface RoomInstance {
|
||||
location: string,
|
||||
dataBlob?: string,
|
||||
eventId?: number,
|
||||
photonRegionId: PhotonRegionCodeString,
|
||||
photonRegionId: PhotonRegionCodeString | PhotonRegionCodeNumber,
|
||||
photonRoomId: string,
|
||||
name?: string,
|
||||
maxCapacity: number,
|
||||
@@ -75,7 +75,8 @@ export interface InstanceOptions {
|
||||
EventId?: number,
|
||||
Name?: string,
|
||||
Private?: boolean,
|
||||
FirstPlayer?: Profile
|
||||
FirstPlayer?: Profile,
|
||||
IsDorm?: boolean
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -25,3 +25,13 @@ export enum PlatformMask {
|
||||
IOS = 32,
|
||||
All = -1
|
||||
}
|
||||
|
||||
export enum PlatformType {
|
||||
All = -1,
|
||||
Steam,
|
||||
Oculus,
|
||||
PlayStation,
|
||||
Microsoft,
|
||||
HeadlessBot,
|
||||
IOS
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -21,6 +21,10 @@ export class ProfileContentManager {
|
||||
this.profileId = profileId;
|
||||
}
|
||||
|
||||
onProfileInit() {
|
||||
return;
|
||||
}
|
||||
|
||||
profileId: number;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
33
src/data/profile/rooms.ts
Normal file
33
src/data/profile/rooms.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { Redis } from "../../db.ts";
|
||||
import { ProfileContentManager } from "./base/profilemanagerbase.ts";
|
||||
|
||||
export class ProfileRoomsManager extends ProfileContentManager {
|
||||
|
||||
#rootKey = Redis.buildKey(
|
||||
Redis.KeyGroups.Profiles.Root,
|
||||
this.profileId.toString(),
|
||||
Redis.KeyGroups.Profiles.Avatar.Root
|
||||
);
|
||||
|
||||
async getRooms() {
|
||||
// get player rooms
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { Redis } from "../../db.ts";
|
||||
import { SettingKey } from "../content/settings.ts";
|
||||
import { SettingKey, SettingDefault } from "../content/settings.ts";
|
||||
import { ProfileContentManager } from "./base/profilemanagerbase.ts";
|
||||
|
||||
export interface Setting {
|
||||
@@ -26,6 +26,14 @@ export interface Setting {
|
||||
|
||||
export class ProfileSettingsManager extends ProfileContentManager {
|
||||
|
||||
override async onProfileInit() {
|
||||
await this.setSetting(SettingKey.RecroomOOBE, SettingDefault.RecroomOOBE);
|
||||
await this.setSetting(SettingKey.PlayerStatusVisibility, SettingDefault.PlayerStatusVisibility);
|
||||
await this.setSetting(SettingKey.FIRST_TIME_IN_FLAGS, SettingDefault.FIRST_TIME_IN_FLAGS);
|
||||
await this.setSetting(SettingKey.BACKPACK_FAVORITE_TOOL, SettingDefault.BACKPACK_FAVORITE_TOOL);
|
||||
await this.setSetting(SettingKey.Recroom_ChallengeMap, SettingDefault.Recroom_ChallengeMap);
|
||||
}
|
||||
|
||||
async getSettings() {
|
||||
const settings = await Redis.Database.hgetall(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings));
|
||||
const returnSettings: Setting[] = [];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -140,7 +140,11 @@ class Profile {
|
||||
newUsername,
|
||||
);
|
||||
|
||||
return new Profile(newId);
|
||||
const profile = new Profile(newId);
|
||||
|
||||
profile.Settings.onProfileInit();
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
// surely this can be written better
|
||||
@@ -164,7 +168,7 @@ class Profile {
|
||||
platforms: 1,
|
||||
username: values[2] == null ? "DATABASEERROR" : values[2],
|
||||
displayName: values[3] == null ? (values[2] == null ? "DATABASEERROR" : values[2]) : values[3],
|
||||
email: "" // removes a notification in messages (untested)
|
||||
email: "notanemail@notanemailsite.local" // we are confirmed
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -219,7 +223,7 @@ class Profile {
|
||||
|
||||
async getBio() {
|
||||
const bio = await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.#id.toString(), Redis.KeyGroups.Profiles.Bio));
|
||||
if (!bio) return "This player has not yet set their bio. Remind them to set one!";
|
||||
if (!bio) return "";
|
||||
else return bio;
|
||||
}
|
||||
|
||||
@@ -302,7 +306,7 @@ class Profile {
|
||||
sub: this.#id,
|
||||
role: (await this.getIsOperator()) ? 'developer' : 'user',
|
||||
exp: Math.round(Date.now() / 1000) + Math.round(config.auth.timeout * 60 * 60),
|
||||
typ: AuthType.Game
|
||||
typ: AuthType.Game,
|
||||
};
|
||||
return await JsonWebToken.encode(payload, config.auth.secret, { algorithm: "HS512" });
|
||||
}
|
||||
@@ -335,6 +339,15 @@ class UnifiedProfileBase {
|
||||
return await Profile.existsByName(name);
|
||||
}
|
||||
|
||||
getAllSockets() {
|
||||
const returnSockets: Set<SignalRSocketHandler> = new Set();
|
||||
for (const profile of profiles.values()) {
|
||||
const socket = profile.getSocketHandler();
|
||||
if (socket) returnSockets.add(socket);
|
||||
}
|
||||
return returnSockets;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const UnifiedProfile = new UnifiedProfileBase();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -18,54 +18,36 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
const Dictionary = {
|
||||
Adjectives: [
|
||||
"Amazing",
|
||||
"Adventurous",
|
||||
"Affable",
|
||||
"Agreeable",
|
||||
"Ambitious",
|
||||
"Amicable",
|
||||
"Animated",
|
||||
"Approachable",
|
||||
"Articulate",
|
||||
"Astute",
|
||||
"Attractive",
|
||||
"Authentic",
|
||||
"Benevolent",
|
||||
"Blissful",
|
||||
"Bold",
|
||||
"Bright",
|
||||
"Buoyant",
|
||||
"Calm",
|
||||
"Captivating",
|
||||
"Charismatic",
|
||||
"Cheerful",
|
||||
"Clever",
|
||||
"Compassionate",
|
||||
"Confident",
|
||||
"Considerate",
|
||||
"Content",
|
||||
"Cooperative",
|
||||
"Courageous",
|
||||
"Creative",
|
||||
"Cultured",
|
||||
"Curious",
|
||||
"Dashing",
|
||||
"Dazzling",
|
||||
"Dedicated",
|
||||
"Delightful",
|
||||
"Dependable",
|
||||
"Determined",
|
||||
"Diligent",
|
||||
"Dynamic",
|
||||
"Earnest",
|
||||
"Easygoing",
|
||||
"Ebullient",
|
||||
"Effervescent",
|
||||
"Empathetic",
|
||||
"Enchanting",
|
||||
"Endearing",
|
||||
"Energetic",
|
||||
"Engaging",
|
||||
"Enthusiastic",
|
||||
"Exuberant",
|
||||
"Fantastic",
|
||||
"Fearless",
|
||||
@@ -77,28 +59,17 @@ const Dictionary = {
|
||||
"Genuine",
|
||||
"Gracious",
|
||||
"Grateful",
|
||||
"Harmonious",
|
||||
"Heartwarming",
|
||||
"Helpful",
|
||||
"Honest",
|
||||
"Humble",
|
||||
"Humorous",
|
||||
"Imaginative",
|
||||
"Impeccable",
|
||||
"Incisive",
|
||||
"Incredible",
|
||||
"Independent",
|
||||
"Industrious",
|
||||
"Ingenious",
|
||||
"Insightful",
|
||||
"Intelligent",
|
||||
"Intuitive",
|
||||
"Invigorating",
|
||||
"Jovial",
|
||||
"Jubilant",
|
||||
"Just",
|
||||
"Kind",
|
||||
"Knowledgeable",
|
||||
"Likable",
|
||||
"Lively",
|
||||
"Lovable",
|
||||
@@ -110,24 +81,14 @@ const Dictionary = {
|
||||
"Masterful",
|
||||
"Mature",
|
||||
"Merciful",
|
||||
"Methodical",
|
||||
"Meticulous",
|
||||
"Mindful",
|
||||
"Motivated",
|
||||
"Natural",
|
||||
"Nurturing",
|
||||
"Observant",
|
||||
"Optimistic",
|
||||
"Outgoing",
|
||||
"Passionate",
|
||||
"Patient",
|
||||
"Peaceful",
|
||||
"Perceptive",
|
||||
"Perseverant",
|
||||
"Persistent",
|
||||
"Persuasive",
|
||||
"Personable",
|
||||
"Philanthropic",
|
||||
"Placid",
|
||||
"Playful",
|
||||
"Pleasant",
|
||||
@@ -136,20 +97,14 @@ const Dictionary = {
|
||||
"Powerful",
|
||||
"Pragmatic",
|
||||
"Proactive",
|
||||
"Proficient",
|
||||
"Prudent",
|
||||
"Punctual",
|
||||
"Purposeful",
|
||||
"Radiant",
|
||||
"Rational",
|
||||
"Real",
|
||||
"Receptive",
|
||||
"Reflective",
|
||||
"Reliable",
|
||||
"Resilient",
|
||||
"Resourceful",
|
||||
"Respectful",
|
||||
"Responsible",
|
||||
"Robust",
|
||||
"Sagacious",
|
||||
"Serene",
|
||||
@@ -159,33 +114,23 @@ const Dictionary = {
|
||||
"Sociable",
|
||||
"Spirited",
|
||||
"Splendid",
|
||||
"Spontaneous",
|
||||
"Steady",
|
||||
"Sterling",
|
||||
"Strong",
|
||||
"Sublime",
|
||||
"Successful",
|
||||
"Supportive",
|
||||
"Sympathetic",
|
||||
"Talented",
|
||||
"Tenacious",
|
||||
"Thoughtful",
|
||||
"Tireless",
|
||||
"Tolerant",
|
||||
"Tough",
|
||||
"Tranquil",
|
||||
"Trustworthy",
|
||||
"Unassuming",
|
||||
"Understanding",
|
||||
"Unique",
|
||||
"Unpretentious",
|
||||
"Upbeat",
|
||||
"Valiant",
|
||||
"Vibrant",
|
||||
"Virtuous",
|
||||
"Visionary",
|
||||
"Vivacious",
|
||||
"Warmhearted",
|
||||
"Welcoming",
|
||||
"Wise",
|
||||
"Witty",
|
||||
@@ -198,7 +143,6 @@ const Dictionary = {
|
||||
"Elysium",
|
||||
"Horizon",
|
||||
"Catalyst",
|
||||
"Luminescence",
|
||||
"Utopia",
|
||||
"Eclipse",
|
||||
"Nebula",
|
||||
@@ -220,7 +164,6 @@ const Dictionary = {
|
||||
"Vibrance",
|
||||
"Astral",
|
||||
"Jubilant",
|
||||
"Ascendancy",
|
||||
"Zen",
|
||||
"Nebulous",
|
||||
"Ecliptic",
|
||||
@@ -233,7 +176,6 @@ const Dictionary = {
|
||||
"Enigma",
|
||||
"Luminous",
|
||||
"Epoch",
|
||||
"Serendipity",
|
||||
"Zenithal",
|
||||
"Paragon",
|
||||
"Panorama",
|
||||
@@ -255,7 +197,6 @@ const Dictionary = {
|
||||
"Endeavor",
|
||||
"Visionary",
|
||||
"Epoch",
|
||||
"Renaissance",
|
||||
"Panache",
|
||||
"Jubilee",
|
||||
"Resonance",
|
||||
@@ -264,13 +205,11 @@ const Dictionary = {
|
||||
"Ethereal",
|
||||
"Cascade",
|
||||
"Radiance",
|
||||
"Synchronicity",
|
||||
"Nebula",
|
||||
"Equinox",
|
||||
"Pulsar",
|
||||
"Apex",
|
||||
"Ethos",
|
||||
"Wanderlust",
|
||||
"Zenith",
|
||||
"Nebula",
|
||||
"Vertex",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -76,6 +76,7 @@ export const KeyGroups = {
|
||||
},
|
||||
Profile_Usernames: "profile-usernames",
|
||||
PlatformAssociations: "platforms",
|
||||
AddressBans: "address-bans",
|
||||
Profiles: {
|
||||
Root: "profiles",
|
||||
Username: "username",
|
||||
@@ -87,6 +88,7 @@ export const KeyGroups = {
|
||||
DeviceClass: "deviceClass",
|
||||
Xp: "xp",
|
||||
Bio: "bio",
|
||||
Rooms: "rooms",
|
||||
Relationships: {
|
||||
Root: "relationships",
|
||||
IncomingFriendRequests: "incomingFriendRequests",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
25
src/main.ts
25
src/main.ts
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -28,6 +28,7 @@ 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";
|
||||
import { GameConfigs } from "./data/config.ts";
|
||||
|
||||
const instanceId = generateRandomString(64);
|
||||
|
||||
@@ -114,10 +115,6 @@ if (!(await Rooms.generateBuiltinRooms())) log.i(`Generated built-in rooms`);
|
||||
|
||||
try {
|
||||
|
||||
/**
|
||||
* Galvanic WebSocket Server
|
||||
*/
|
||||
|
||||
type AuthResultBase = {
|
||||
valid: boolean
|
||||
}
|
||||
@@ -133,10 +130,13 @@ try {
|
||||
const authHeader = req.headers.get('authorization');
|
||||
if (!authHeader) return { valid: false } as AuthResult;
|
||||
|
||||
const token = authHeader.split(" ")[1];
|
||||
log.d(authHeader);
|
||||
const token = authHeader.split(", ")[1]; // Why is the header formatted like this?
|
||||
if (!token) return { valid: false } as AuthResult;
|
||||
const splitToken = token.split(' ')[1];
|
||||
if (!splitToken) return { valid: false } as AuthResult;
|
||||
|
||||
const decodedToken = await decode<ProfileTokenFormat>(token, config.auth.secret, {algorithm: 'HS512'});
|
||||
const decodedToken = await decode<ProfileTokenFormat>(splitToken, config.auth.secret, {algorithm: 'HS512'});
|
||||
const schemaResult = ProfileTokenSchema.safeParse(decodedToken);
|
||||
if (!schemaResult.success) return { valid: false } as AuthResult;
|
||||
else return { token: decodedToken, valid: true } as AuthResult;
|
||||
@@ -149,6 +149,14 @@ try {
|
||||
|
||||
const abort = new AbortController();
|
||||
|
||||
abort.signal.addEventListener('abort', () => {
|
||||
log.n("Closing all sockets");
|
||||
const sockets = UnifiedProfile.getAllSockets();
|
||||
for (const socket of sockets.values()) {
|
||||
socket.destroy(socket)();
|
||||
} // I used the socket to destroy the socket
|
||||
});
|
||||
|
||||
// Galvanic WebSocket
|
||||
Deno.serve({port: config.web.socket.port, hostname: config.web.socket.host, signal: abort.signal, onListen: addr => {
|
||||
log.n(`Socket listening on http://${addr.hostname}:${addr.port}`);
|
||||
@@ -209,6 +217,9 @@ try {
|
||||
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
|
||||
|
||||
if (!(await GameConfigs.getGameConfig('splitTestSoftOverrides'))) GameConfigs.setGameConfig('splitTestSoftOverrides', '');
|
||||
if (!(await GameConfigs.getGameConfig('splitTestHardOverrides'))) GameConfigs.setGameConfig('splitTestHardOverrides', '');
|
||||
|
||||
});
|
||||
|
||||
http.on('error', err => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,7 @@ import { APIUtils } from "../apiutils.ts";
|
||||
import { route as AccountRoute } from "./account/account.ts";
|
||||
import { route as ParentalControlRoute } from "./account/parentalcontrol.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/accountservice");
|
||||
export const route = APIUtils.createRouter("/accounts");
|
||||
|
||||
route.router.use(AccountRoute.path, AccountRoute.router);
|
||||
route.router.use(ParentalControlRoute.path, ParentalControlRoute.router);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,6 +19,7 @@ import { APIUtils } from "../../apiutils.ts";
|
||||
import express from "express";
|
||||
import UnifiedProfile, { Profile } from "../../data/profiles.ts";
|
||||
import { z } from "zod";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/account");
|
||||
|
||||
@@ -28,7 +29,7 @@ const CreateAccountRequestBodySchema = z.object({
|
||||
deviceId: z.string()
|
||||
});
|
||||
|
||||
const rateLimit = new APIUtils.RateLimiter(25, 5);
|
||||
const rateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
route.router.post("/create",
|
||||
|
||||
@@ -102,6 +103,15 @@ route.router.get("/me",
|
||||
|
||||
);
|
||||
|
||||
route.router.post("/me/displayname",
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
APIUtils.RecNetResponse(true, "DisplayName customization is not yet implemented."),
|
||||
|
||||
);
|
||||
|
||||
interface BioFetchParams {
|
||||
id?: string
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,30 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/challenge");
|
||||
|
||||
// create router for now
|
||||
// todo: challenges; all of it
|
||||
// will require a ChallengeBuilder to compile challenge configs
|
||||
route.router.get('/v2/getCurrent',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
(_rq, rs) => {
|
||||
rs.json({
|
||||
ChallengeMapId: 0,
|
||||
StartAt: new Date().toISOString(),
|
||||
EndAt: new Date(Date.now() + 604_800_000).toISOString(), // 1 week
|
||||
ServerTime: new Date().toISOString(),
|
||||
Challenges: [],
|
||||
Gift: {
|
||||
GiftDropId: 0,
|
||||
Xp: 0,
|
||||
Level: 0
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -20,7 +20,7 @@ import { GameConfigs } from "../../data/config.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/config");
|
||||
|
||||
const rateLimit = new APIUtils.RateLimiter(60, 2);
|
||||
const rateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
route.router.get("/v2", rateLimit.middle(), (_rq, rs) => {
|
||||
const config = GameConfigs.getConfig();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -27,4 +27,4 @@ route.router.get('/v2/getUnlocked',
|
||||
|
||||
APIUtils.emptyArrayResponse
|
||||
|
||||
)
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,12 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import { GameConfigs } from "../../data/config.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/gameconfigs");
|
||||
|
||||
route.router.get("/v1/all", APIUtils.emptyArrayResponse);
|
||||
const rateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
route.router.get("/v1/all", rateLimit.middle(), async (_rq, rs) => {
|
||||
rs.json((await GameConfigs.getAllGameConfigs()).entries().map(val => ({Key: val[0], Value: val[1]})).toArray());
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -15,8 +15,10 @@ 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import { z } from "zod";
|
||||
import { APIUtils, NoBody } from "../../apiutils.ts";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
import express from "express";
|
||||
|
||||
export const route = APIUtils.createRouter('/objectives');
|
||||
|
||||
@@ -33,3 +35,27 @@ route.router.get('/v1/myprogress',
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
interface ClearGroupRequestBody {
|
||||
Group: number
|
||||
}
|
||||
const ClearGroupRequestSchema = z.object({
|
||||
Group: z.number()
|
||||
});
|
||||
route.router.post('/v1/cleargroup',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
express.json(),
|
||||
APIUtils.logBody,
|
||||
APIUtils.validateRequestBody(ClearGroupRequestSchema),
|
||||
|
||||
(rq: express.Request<NoBody, NoBody, ClearGroupRequestBody>, rs: express.Response) => {
|
||||
rs.json({
|
||||
Group: rq.body.Group,
|
||||
IsCompleted: false,
|
||||
ClearedAt: new Date().toISOString() // todo: objectives; all of it
|
||||
});
|
||||
},
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -39,3 +39,15 @@ route.router.get('/v1/:id',
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
route.router.get('/v1/bulk',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
express.urlencoded({ extended: true }),
|
||||
APIUtils.logBody,
|
||||
|
||||
APIUtils.emptyArrayResponse
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,10 +19,11 @@ import Logging from "@proxnet/undead-logging";
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import express from "express";
|
||||
import UnifiedProfile from "../../data/profiles.ts";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
|
||||
const log = new Logging("ProgressionRoute");
|
||||
|
||||
const rateLimit = new APIUtils.RateLimiter(60, 2);
|
||||
const rateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
export const route = APIUtils.createRouter("/players");
|
||||
|
||||
@@ -49,3 +50,14 @@ route.router.get('/v1/progression/:id',
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
route.router.post('/v1/progression/bulk',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
express.urlencoded({ extended: true }),
|
||||
APIUtils.logBody,
|
||||
|
||||
APIUtils.emptyArrayResponse
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -66,7 +66,7 @@ route.router.get('/v1/hot',
|
||||
async (_rq, rs) => {
|
||||
// temporary: return all public AG rooms for testing
|
||||
const rooms = await Rooms.getAllBuiltinRoomGenerations();
|
||||
rs.json(rooms.map(room => room.Room).filter(room => room.Accessibility !== RoomAccessibility.Private));
|
||||
rs.json(rooms.map(room => room.Room).filter(room => room.Accessibility == RoomAccessibility.Public));
|
||||
},
|
||||
|
||||
);
|
||||
@@ -98,11 +98,16 @@ route.router.get('/v2/name/:name',
|
||||
}
|
||||
|
||||
const room = await Rooms.getByName(rq.params.name.trim());
|
||||
if (!room || rq.params.name == 'DormRoom') {
|
||||
rs.sendStatus(404);
|
||||
if (room) {
|
||||
rs.json(room.Room);
|
||||
return;
|
||||
} else if (rq.params.name == 'DormRoom') {
|
||||
const dorm = await Rooms.getProfileDormDefault(rs.locals.profile);
|
||||
if (dorm) rs.json(dorm.Room);
|
||||
else rs.sendStatus(404);
|
||||
return;
|
||||
} else {
|
||||
rs.json(room.Room);
|
||||
rs.sendStatus(404);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -59,11 +59,8 @@ route.router.post('/v2/set',
|
||||
|
||||
(rq: express.Request<NoBody, NoBody, SettingsSetBody>, rs: express.Response) => {
|
||||
rs.locals.profile.Settings.setSettingRaw(rq.body.Key, rq.body.Value),
|
||||
rs.json({
|
||||
Succeeded: true,
|
||||
Error: "",
|
||||
ShouldRetry: false
|
||||
});
|
||||
rs.sendStatus(200);
|
||||
log.d(`${rs.locals.profile.getId()} set settings key '${rq.body.Key}' to '${rq.body.Value}'`);
|
||||
}
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -17,6 +17,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import express from "express";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
import { CurrencyType, StorefrontBalanceType } from "../../data/content/storefronts.ts";
|
||||
|
||||
export const route = APIUtils.createRouter('/storefronts');
|
||||
|
||||
@@ -26,6 +28,7 @@ interface StorefrontFetchParams {
|
||||
route.router.get('/v3/giftdropstore/:id',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
(rq: express.Request<StorefrontFetchParams>, rs: express.Response) => {
|
||||
if (!rq.params.id) {
|
||||
@@ -40,3 +43,27 @@ route.router.get('/v3/giftdropstore/:id',
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
interface BalanceParams {
|
||||
currencyType?: string
|
||||
}
|
||||
route.router.get('/v4/balance/:currencyType',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
(rq: express.Request<BalanceParams>, rs: express.Response) => {
|
||||
const parsedCurrencyType = parseInt(rq.params.currencyType ? rq.params.currencyType : "2");
|
||||
if (isNaN(parsedCurrencyType)) {
|
||||
rs.sendStatus(400);
|
||||
} else {
|
||||
rs.json([{
|
||||
Balance: 0,
|
||||
BalanceType: StorefrontBalanceType.NonPurchasedNonP2P,
|
||||
CurrencyType: parsedCurrencyType
|
||||
}]);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,9 @@ import { APIUtils } from "../../apiutils.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/versioncheck");
|
||||
|
||||
const validVersion = "20191120";
|
||||
export const validVersions = [
|
||||
"20200306"
|
||||
];
|
||||
|
||||
enum VersionStatus {
|
||||
ValidForPlay,
|
||||
@@ -35,10 +37,10 @@ route.router.get("/v4", (rq, rs) => {
|
||||
const requestedVer = rq.query["v"];
|
||||
const pQuery = rq.query["p"];
|
||||
|
||||
if (typeof requestedVer == "undefined" || typeof pQuery == "undefined") {
|
||||
if (typeof requestedVer == "undefined" || typeof pQuery == "undefined" || typeof requestedVer == 'object') {
|
||||
rs.statusCode = 400;
|
||||
rs.json(APIUtils.genericResponseFormat(true, "One or more query parameters were not found."));
|
||||
} else if (requestedVer !== validVersion) {
|
||||
rs.json(APIUtils.genericResponseFormat(true, "One or more query parameters were not found or invalid."));
|
||||
} else if (!validVersions.includes(requestedVer as string)) {
|
||||
const res: ValidVersionResponse = {
|
||||
VersionStatus: VersionStatus.UpdateRequired,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -18,8 +18,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
import { APIUtils } from "../apiutils.ts";
|
||||
import { route as CachedLoginRoute } from "./auth/cachedlogin.ts";
|
||||
import { route as ConnectRoute } from "./auth/connect.ts";
|
||||
import { route as AccountRoute } from "./auth/account.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/authservice");
|
||||
export const route = APIUtils.createRouter("/auth");
|
||||
|
||||
route.router.use(CachedLoginRoute.path, CachedLoginRoute.router);
|
||||
route.router.use(ConnectRoute.path, ConnectRoute.router);
|
||||
route.router.use(AccountRoute.path, AccountRoute.router);
|
||||
41
src/routes/auth/account.ts
Normal file
41
src/routes/auth/account.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
import { APIUtils } from "../../apiutils.ts";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
|
||||
export const route = APIUtils.createRouter("/account");
|
||||
|
||||
route.router.post('/me/changepassword',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
APIUtils.RecNetResponse(true, "Passwords are unsupported on Galvanic Corrosion.")
|
||||
|
||||
);
|
||||
|
||||
route.router.get('/me/haspassword',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
(rq, rs) => {
|
||||
rs.json(true);
|
||||
},
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -24,6 +24,7 @@ import Logging from "@proxnet/undead-logging";
|
||||
import { z } from "zod";
|
||||
import { AuthType } from "../../data/users.ts";
|
||||
import { Redis } from "../../db.ts";
|
||||
import { validVersions } from "../api/versioncheck.ts";
|
||||
|
||||
const config = Config.getConfig();
|
||||
|
||||
@@ -116,7 +117,7 @@ route.router.post("/token",
|
||||
const conditionsMet = ![
|
||||
rq.body.client_id === "recroom",
|
||||
rq.body.platform === "0",
|
||||
rq.body.ver === '20191120',
|
||||
validVersions.includes(rq.body.ver),
|
||||
rq.body.device_class.length === 1,
|
||||
!isNaN(Number(rq.body.device_class)),
|
||||
!(rq.body.device_id.length > 96),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -36,6 +36,7 @@ interface ImageQueryOptions {
|
||||
cropSquare?: string;
|
||||
width?: string;
|
||||
height?: string;
|
||||
sig?: string;
|
||||
}
|
||||
|
||||
route.router.get(
|
||||
@@ -49,8 +50,6 @@ route.router.get(
|
||||
rq.path.substring(1, rq.path.length).replaceAll("%20", " "),
|
||||
);
|
||||
|
||||
// why does it think it is never reassigned? line 39
|
||||
// deno-lint-ignore prefer-const
|
||||
let image: Image;
|
||||
const imageSource = baseImages.includes(filename)
|
||||
? BaseImages.getBaseImage(filename)
|
||||
@@ -80,6 +79,23 @@ route.router.get(
|
||||
else height = num;
|
||||
}
|
||||
|
||||
if (cropSquare == 1) {
|
||||
if (image.width > image.height) {
|
||||
image.crop(
|
||||
Math.round(image.width / 2) - Math.round(image.height / 2),
|
||||
0,
|
||||
image.height,
|
||||
image.height,
|
||||
);
|
||||
} else {
|
||||
image.crop(
|
||||
0,
|
||||
Math.round(image.height / 2) - Math.round(image.width / 2),
|
||||
image.width,
|
||||
image.width,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (width && height) {
|
||||
const targetWidth = width > image.width ? image.width : width;
|
||||
const targetHeight = height > image.height ? image.height : height;
|
||||
@@ -102,23 +118,8 @@ route.router.get(
|
||||
}
|
||||
} else if (width) image.resize(width, Image.RESIZE_AUTO);
|
||||
else if (height) image.resize(Image.RESIZE_AUTO, height);
|
||||
if (cropSquare == 1) {
|
||||
if (image.width > image.height) {
|
||||
image.crop(
|
||||
Math.round(image.width / 2) - Math.round(image.height / 2),
|
||||
0,
|
||||
image.height,
|
||||
image.height,
|
||||
);
|
||||
} else {image.crop(
|
||||
0,
|
||||
Math.round(image.height / 2) - Math.round(image.width / 2),
|
||||
image.width,
|
||||
image.width,
|
||||
);}
|
||||
}
|
||||
|
||||
rs.setHeader('content-signature', 'key-id=KEY:RSA:p1.rec.net; data=aGk='); // enable image signature patch on client
|
||||
if (rq.query.sig) rs.setHeader('content-signature', 'key-id=KEY:RSA:p1.rec.net; data=aGk=');
|
||||
rs.type("png").send(Buffer.from(await image.encode()));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -35,8 +35,9 @@ route.router.post('/room/:roomName',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
APIUtils.startTimer,
|
||||
|
||||
async (rq: express.Request<MatchmakingParams>, rs: express.Response) => {
|
||||
async (rq: express.Request<MatchmakingParams>, rs: express.Response, nxt: express.NextFunction) => {
|
||||
if (!rq.params.roomName) {
|
||||
log.d('Matchmake failed: No room specified');
|
||||
rs.json({
|
||||
@@ -45,22 +46,30 @@ route.router.post('/room/:roomName',
|
||||
return;
|
||||
}
|
||||
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName }));
|
||||
nxt();
|
||||
},
|
||||
|
||||
APIUtils.stopTimer
|
||||
|
||||
);
|
||||
route.router.post('/room/:roomName/:subRoomName',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
APIUtils.startTimer,
|
||||
|
||||
async (rq: express.Request<MatchmakingParams>, rs: express.Response) => {
|
||||
async (rq: express.Request<MatchmakingParams>, rs: express.Response, nxt: express.NextFunction) => {
|
||||
if (!rq.params.roomName) {
|
||||
log.d('Matchmake failed: No room specified');
|
||||
rs.json({
|
||||
errorCode: MatchmakingErrorCode.NoSuchRoom
|
||||
});
|
||||
return;
|
||||
}
|
||||
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName, subRoomName: rq.params.subRoomName }));
|
||||
nxt();
|
||||
},
|
||||
|
||||
)
|
||||
APIUtils.stopTimer
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -25,6 +25,7 @@ import Logging from "@proxnet/undead-logging";
|
||||
import UnifiedProfile from "../../data/profiles.ts";
|
||||
import { PlayerStatusVisibility, VRMovementMode } from "../../data/live/types.ts";
|
||||
import { SettingKey } from "../../data/content/settings.ts";
|
||||
import Instances from "../../data/live/instances.ts";
|
||||
|
||||
const log = new Logging("MatchPlayerRoute");
|
||||
|
||||
@@ -85,7 +86,7 @@ route.router.post('/logout',
|
||||
APIUtils.validateRequestBody(LoginSchema),
|
||||
|
||||
(_rq, rs) => {
|
||||
Matchmaking.deleteLoginLock(rs.locals.profile);
|
||||
Instances.removePlayerFromCurrentInstance(rs.locals.profile);
|
||||
rs.sendStatus(200);
|
||||
}
|
||||
|
||||
@@ -110,14 +111,14 @@ interface StatusVisibilityBody {
|
||||
statusVisibility: PlayerStatusVisibility
|
||||
}
|
||||
const StatusVisibilitySchema = z.object({
|
||||
statusVisibility: z.nativeEnum(PlayerStatusVisibility)
|
||||
statusVisibility: z.enum(Object.values(PlayerStatusVisibility).map(String) as [string, ...string[]])
|
||||
});
|
||||
|
||||
route.router.put('/statusvisibility',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
express.urlencoded({ extended: true }),
|
||||
APIUtils.logBody,
|
||||
APIUtils.validateRequestBody(StatusVisibilitySchema),
|
||||
|
||||
async (rq: express.Request<NoBody, NoBody, StatusVisibilityBody>, rs: express.Response) => {
|
||||
@@ -149,3 +150,14 @@ route.router.put('/vrmovementmode',
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
route.router.put('/photonregionpings',
|
||||
|
||||
APIUtils.Authentication,
|
||||
APIUtils.AuthenticationType(AuthType.Game),
|
||||
|
||||
(rq, rs) => {
|
||||
rs.sendStatus(200);
|
||||
}
|
||||
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -24,6 +24,7 @@ const protocol = config.web.api.securepublichost ? "https" : "http";
|
||||
export const route = APIUtils.createRouter("/ns");
|
||||
|
||||
type NameserverHosts = {
|
||||
Accounts: string;
|
||||
Auth: string;
|
||||
API: string;
|
||||
WWW: string;
|
||||
@@ -38,6 +39,7 @@ type NameserverHosts = {
|
||||
};
|
||||
|
||||
const nameserver: NameserverHosts = {
|
||||
Accounts: `${protocol}://${config.web.api.publichost}/accounts`,
|
||||
Auth: `${protocol}://${config.web.api.publichost}/auth`,
|
||||
API: `${protocol}://${config.web.api.publichost}`,
|
||||
WWW: `${protocol}://${config.web.api.publichost}`,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -57,7 +57,7 @@ const AuthRequestRootSchema = z.object({
|
||||
pubkey: z.string(),
|
||||
});
|
||||
|
||||
const rateLimit = new APIUtils.RateLimiter(60, 2);
|
||||
const rateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
route.router.post("/auth",
|
||||
|
||||
@@ -140,7 +140,7 @@ route.router.post("/auth",
|
||||
},
|
||||
);
|
||||
|
||||
const checkRateLimit = new APIUtils.RateLimiter(10, 3);
|
||||
const checkRateLimit = new APIUtils.RateLimiter();
|
||||
|
||||
route.router.get('/checkExpired', checkRateLimit.middle(), async (rq, rs) => {
|
||||
|
||||
@@ -152,7 +152,7 @@ route.router.get('/checkExpired', checkRateLimit.middle(), async (rq, rs) => {
|
||||
|
||||
try {
|
||||
const decodedToken = await decode<UserTokenFormat>(token, config.auth.secret, { algorithm: "HS512", leeway: 31536000 }); // 1 year leeway
|
||||
rs.json(decodedToken.exp < Math.round(Date.now() / 1000));
|
||||
rs.json(decodedToken.exp < Math.round(Date.now() / 1000)); // check it manually
|
||||
} catch {
|
||||
rs.json(true);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -44,7 +44,7 @@ export class SignalRSocketHandler {
|
||||
|
||||
#Targets: Map<string, SocketTarget> = new Map();
|
||||
|
||||
#PresenceUpdateId: number;
|
||||
#PeriodicalId: number;
|
||||
|
||||
constructor(socket: WebSocket, player: Profile) {
|
||||
|
||||
@@ -57,9 +57,12 @@ export class SignalRSocketHandler {
|
||||
|
||||
this.#Targets.set('SubscribeToPlayers', new PlayerSocketSubscriptionTarget());
|
||||
|
||||
this.#PresenceUpdateId = setInterval(async () => {
|
||||
const pres = await Presence.get(this.#profile);
|
||||
this.sendNotification("PresenceUpdate", await pres.export());
|
||||
this.#PeriodicalId = setInterval(async () => {
|
||||
if (this.#socket.readyState !== this.#socket.CLOSED) {
|
||||
const pres = await Presence.get(this.#profile);
|
||||
this.sendNotification("PresenceUpdate", await pres.export());
|
||||
this.sendRaw({ type: 6 });
|
||||
}
|
||||
}, 8000);
|
||||
|
||||
}
|
||||
@@ -83,7 +86,7 @@ export class SignalRSocketHandler {
|
||||
this.sendRaw({});
|
||||
return;
|
||||
} else {
|
||||
this.#log.d(`CLIENT MESSAGE\n Type: ${message.data.type} (${SignalMessageType[message.data.type]})\n ${JSON.stringify(message.data)}`);
|
||||
//this.#log.d(`CLIENT MESSAGE\n Type: ${message.data.type} (${SignalMessageType[message.data.type]})\n ${JSON.stringify(message.data)}`);
|
||||
if (message.data.type == SignalMessageType.Invocation && message.data.invocationId) { // don't send completion messages for nonblocking invocations
|
||||
const res = await this.#dispatchTarget(message.data.target, message.data.arguments[0]); // rec room only uses the first index
|
||||
if (res.type == TargetResultType.Success) {
|
||||
@@ -145,18 +148,19 @@ export class SignalRSocketHandler {
|
||||
|
||||
destroy(sock: SignalRSocketHandler) {
|
||||
return () => {
|
||||
clearInterval(sock.#PresenceUpdateId);
|
||||
clearInterval(sock.#PeriodicalId);
|
||||
sock.sendRaw({ type: 7, error: "Socket closed" });
|
||||
sock.#socket.close();
|
||||
sock.#log.i(`Closed hub socket`);
|
||||
sock.#log.i(`Closed socket`);
|
||||
sock.#profile.clearSocketHandler();
|
||||
}
|
||||
}
|
||||
|
||||
sendRaw(data: object) {
|
||||
this.#socket.send(`${JSON.stringify(data)}\u001e`);
|
||||
// todo sometime: make this less confusing
|
||||
const type = `Type: ${JSON.stringify(data) == '{}' ? 'Protocol Message' : `${(data as SignalRMessage).type} (${SignalMessageType[(data as SignalRMessage).type]})`}`;
|
||||
this.#log.d(`SERVER MESSAGE\n ${type}\n ${JSON.stringify(data as SignalRMessage)}`);
|
||||
// todo sometime: make the below less confusing
|
||||
//const type = `Type: ${JSON.stringify(data) == '{}' ? 'Protocol Message' : `${(data as SignalRMessage).type} (${SignalMessageType[(data as SignalRMessage).type]})`}`;
|
||||
//this.#log.d(`SERVER MESSAGE\n ${type}\n ${JSON.stringify(data as SignalRMessage)}`);
|
||||
}
|
||||
|
||||
sendNotification(id: PushNotificationId | string, args: object) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
||||
<https://gitea.proxnet.dev/zombieb-galvanic-corrosion>
|
||||
<https://gitea.proxnet.dev/zombieb/galvanic-corrosion>
|
||||
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
||||
Reference in New Issue
Block a user