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
|
LICENSE TEMPLATE
|
||||||
|
|
||||||
Galvanic Corrosion - Rec Room custom server for communities.
|
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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
delectable yum yum
|
delectable yum yum
|
||||||
|
|
||||||
Rec Room custom server for communities. Fast runtime and easy setup.<br>Built
|
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"/>
|
<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 |
540
res/rooms.json
540
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -131,11 +131,11 @@ export function genericResponse(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
type RecNetResponse = {
|
type RecNetResponse = {
|
||||||
Success: boolean;
|
success: boolean;
|
||||||
Message: string;
|
error?: string;
|
||||||
};
|
};
|
||||||
export function RecNetResponse(success: boolean, message: string) {
|
export function RecNetResponse(success: boolean, message?: string) {
|
||||||
const msg: RecNetResponse = { Success: success, Message: message };
|
const msg: RecNetResponse = { success: success, error: message };
|
||||||
return (_rq: express.Request, rs: express.Response) => {
|
return (_rq: express.Request, rs: express.Response) => {
|
||||||
rs.json(msg);
|
rs.json(msg);
|
||||||
};
|
};
|
||||||
@@ -190,7 +190,7 @@ export class RateLimiter {
|
|||||||
* @param interval In seconds: rate at which hit counts will be cleared
|
* @param interval In seconds: rate at which hit counts will be cleared
|
||||||
* @param limit Number of hits (inclusive) before requests are blocked
|
* @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.#hitLimit = limit;
|
||||||
|
|
||||||
this.#intervalId = setInterval(() => {
|
this.#intervalId = setInterval(() => {
|
||||||
@@ -224,6 +224,11 @@ export class RateLimiter {
|
|||||||
nxt: express.NextFunction,
|
nxt: express.NextFunction,
|
||||||
) => {
|
) => {
|
||||||
const address = getSrcIpDefault(rq);
|
const address = getSrcIpDefault(rq);
|
||||||
|
if (address == '127.0.0.1' || address == '::1') {
|
||||||
|
nxt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.#addressIncrement(address);
|
this.#addressIncrement(address);
|
||||||
|
|
||||||
const hits = this.#getAddressHits(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) {
|
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);
|
const matches = Matchmaking.lockMatches(rs.locals.profile, rq.body.LoginLock);
|
||||||
if (matches == null) {
|
if (matches == null) {
|
||||||
rs.json(genericResponseFormat(true, "Login Lock failure"));
|
rs.json(genericResponseFormat(true, "Login Lock failure"));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 Logging from "@proxnet/undead-logging";
|
||||||
import * as fs from "node:fs";
|
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");
|
const log = new Logging("Config");
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ type PublicConfiguration = {
|
|||||||
levelScale: number;
|
levelScale: number;
|
||||||
maxLevels: number;
|
maxLevels: number;
|
||||||
patches: string[];
|
patches: string[];
|
||||||
photonRegionId: PhotonRegionCodeString;
|
photonRegionId: PhotonRegionCodeString | PhotonRegionCodeNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LoggingConfiguration = {
|
type LoggingConfiguration = {
|
||||||
@@ -111,7 +111,7 @@ export const defaultConfig: GalvanicConfiguration = {
|
|||||||
levelScale: 1,
|
levelScale: 1,
|
||||||
maxLevels: 30,
|
maxLevels: 30,
|
||||||
patches: [],
|
patches: [],
|
||||||
photonRegionId: PhotonRegionCodeString.UnitedStates,
|
photonRegionId: PhotonRegionCodeNumber.us,
|
||||||
},
|
},
|
||||||
logging: {
|
logging: {
|
||||||
notfound: false,
|
notfound: false,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { Redis } from "../db.ts";
|
||||||
import { Objectives } from "./objectives.ts";
|
import { Objectives } from "./objectives.ts";
|
||||||
|
|
||||||
export type Config = {
|
|
||||||
Key: string;
|
|
||||||
Value: string;
|
|
||||||
};
|
|
||||||
export type LevelProgressionItem = {
|
export type LevelProgressionItem = {
|
||||||
Level: number;
|
Level: number;
|
||||||
RequiredXp: number;
|
RequiredXp: number;
|
||||||
@@ -38,13 +34,13 @@ export type AutoMicMutingConfig = {
|
|||||||
MicSpamWarningStateVolumeMultiplier: number
|
MicSpamWarningStateVolumeMultiplier: number
|
||||||
}
|
}
|
||||||
export type PublicConfig = {
|
export type PublicConfig = {
|
||||||
|
ShareBaseUrl: string
|
||||||
ServerMaintenance: {
|
ServerMaintenance: {
|
||||||
StartsInMinutes: number;
|
StartsInMinutes: number;
|
||||||
};
|
};
|
||||||
LevelProgressionMaps: LevelProgressionItem[];
|
LevelProgressionMaps: LevelProgressionItem[];
|
||||||
DailyObjectives: Objectives.Objective[][];
|
DailyObjectives: Objectives.Objective[][];
|
||||||
ConfigTable: Config[];
|
AutoMicMutingConfig: AutoMicMutingConfig,
|
||||||
AutoMicMutingConfig: AutoMicMutingConfig
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,7 +68,6 @@ export function getConfig() {
|
|||||||
},
|
},
|
||||||
LevelProgressionMaps: generateLevelProgressionMap(),
|
LevelProgressionMaps: generateLevelProgressionMap(),
|
||||||
DailyObjectives: [],
|
DailyObjectives: [],
|
||||||
ConfigTable: [],
|
|
||||||
AutoMicMutingConfig: {
|
AutoMicMutingConfig: {
|
||||||
MicSpamVolumeThreshold: 1.125,
|
MicSpamVolumeThreshold: 1.125,
|
||||||
MicVolumeSampleInterval: 0.25,
|
MicVolumeSampleInterval: 0.25,
|
||||||
@@ -82,7 +77,8 @@ export function getConfig() {
|
|||||||
MicSpamSamplePercentageForForceMute: 0.8,
|
MicSpamSamplePercentageForForceMute: 0.8,
|
||||||
MicSpamSamplePercentageForForceMuteToEnd: 0.2,
|
MicSpamSamplePercentageForForceMuteToEnd: 0.2,
|
||||||
MicSpamWarningStateVolumeMultiplier: 0.25
|
MicSpamWarningStateVolumeMultiplier: 0.25
|
||||||
}
|
},
|
||||||
|
ShareBaseUrl: `${config.web.api.securepublichost ? 'https' : 'http'}://${config.web.api.publichost}/{0}` // {0} is replaced by the game
|
||||||
};
|
};
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { Redis } from "../../db.ts";
|
||||||
import { RootPath } from "./baseimages.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 { RoomFetch } from "./room.ts";
|
||||||
import { Profile } from "../profiles.ts";
|
import { Profile } from "../profiles.ts";
|
||||||
import Logging from "@proxnet/undead-logging";
|
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);
|
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(
|
const canBeClonedRaw = await Redis.Database.hget(Redis.buildKey(
|
||||||
Redis.KeyGroups.Rooms.Root,
|
Redis.KeyGroups.Rooms.Root,
|
||||||
roomid.toString(),
|
roomid.toString(),
|
||||||
@@ -183,22 +183,21 @@ class RoomsBase {
|
|||||||
try {
|
try {
|
||||||
canBeCloned = JSON.parse(canBeClonedRaw) as boolean;
|
canBeCloned = JSON.parse(canBeClonedRaw) as boolean;
|
||||||
} catch {
|
} catch {
|
||||||
|
log.d(`Cloneroom ${roomid}: parse error`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!canBeCloned) {
|
||||||
|
log.d(`Cloneroom ${roomid}: cannot be cloned`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!canBeCloned) return null;
|
|
||||||
const beforeRoom = await Rooms.get(roomid); // room must exist
|
const beforeRoom = await Rooms.get(roomid); // room must exist
|
||||||
if (!beforeRoom || !beforeRoom.Room.CloningAllowed) return null; // room must be cloneable
|
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();
|
const newId = await this.#getAvailableRoomId();
|
||||||
beforeRoom.Room.CreatorPlayerId = newowner.getId();
|
beforeRoom.Room.CreatorPlayerId = newowner.getId();
|
||||||
beforeRoom.Room.RoomId = newId;
|
beforeRoom.Room.RoomId = newId;
|
||||||
for (const subroom of beforeRoom.Scenes) subroom.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);
|
await Rooms.#setRoom(beforeRoom);
|
||||||
return beforeRoom;
|
return beforeRoom;
|
||||||
@@ -211,19 +210,19 @@ class RoomsBase {
|
|||||||
Redis.KeyGroups.Rooms.PlayerDorms
|
Redis.KeyGroups.Rooms.PlayerDorms
|
||||||
), player.getId().toString());
|
), player.getId().toString());
|
||||||
if (unparsedId) {
|
if (unparsedId) {
|
||||||
|
log.d(`Unparsed dorm ID for profile ${player.getId()}: ${unparsedId}`);
|
||||||
const parsedId = parseInt(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");
|
const newDorm = await this.generateNewDorm(player);
|
||||||
|
await this.#setRoom(newDorm);
|
||||||
log.d('Base dorm existed');
|
log.d(`New dorm for ${player.getId()} 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');
|
|
||||||
if (!newDorm) return null;
|
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(
|
await Redis.Database.hset(Redis.buildKey(
|
||||||
Redis.KeyGroups.Rooms.Root,
|
Redis.KeyGroups.Rooms.Root,
|
||||||
Redis.KeyGroups.Rooms.PlayerDorms
|
Redis.KeyGroups.Rooms.PlayerDorms
|
||||||
@@ -231,10 +230,59 @@ class RoomsBase {
|
|||||||
return newDorm;
|
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() {
|
async generateBuiltinRooms() {
|
||||||
|
|
||||||
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
||||||
for (const builtinRoom of rooms) {
|
for (const builtinRoom of rooms) {
|
||||||
|
if (builtinRoom.Name == 'DormRoom') continue;
|
||||||
const newId = await this.#getAvailableRoomId();
|
const newId = await this.#getAvailableRoomId();
|
||||||
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
||||||
const roomDets: RoomDetails = {
|
const roomDets: RoomDetails = {
|
||||||
@@ -320,6 +368,11 @@ class RoomsBase {
|
|||||||
else return parsedIds.map(val => val.toString());
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 {
|
export enum SettingKey {
|
||||||
PlayerStatusVisibility = "PlayerStatusVisibility",
|
PlayerStatusVisibility = "PlayerStatusVisibility",
|
||||||
VRMovementMode = "VR_MOVEMENT_MODE",
|
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 {
|
export enum SettingDefault {
|
||||||
PlayerStatusVisibility = "1",
|
PlayerStatusVisibility = "0",
|
||||||
VRMovementMode = "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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -28,4 +28,23 @@ export enum StorefrontTypes {
|
|||||||
Bowling = 500,
|
Bowling = 500,
|
||||||
StuntRunner = 600,
|
StuntRunner = 600,
|
||||||
DormMirror = 700
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 };
|
else if (instance.isPrivate) return { errorCode: MatchmakingErrorCode.RoomInstanceIsPrivate };
|
||||||
|
|
||||||
await Instances.setPlayerInstance(options.profile, instance);
|
await Instances.setPlayerInstance(options.profile, instance);
|
||||||
|
Instances.clearAllRoomEmptyInstances(instance.roomId);
|
||||||
return { errorCode: MatchmakingErrorCode.Success, roomInstance: instance };
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: instance };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,35 +74,76 @@ class MatchmakingBase {
|
|||||||
|
|
||||||
} else {
|
} 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);
|
const targetRoom = options.roomName !== 'DormRoom' ? await Rooms.getByName(options.roomName) : await Rooms.getProfileDormDefault(options.profile);
|
||||||
if (!targetRoom) return { errorCode: MatchmakingErrorCode.NoSuchRoom };
|
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 };
|
if (targetRoom.Room.State !== RoomState.Active) return { errorCode: MatchmakingErrorCode.RoomIsNotActive };
|
||||||
const roomId = targetRoom.Room.RoomId;
|
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);
|
let allInstances = Instances.getAllRoomInstances(roomId).values().toArray().filter(instance => !instance.isPrivate && !instance.isFull);
|
||||||
const subroomId = targetRoom.Scenes.find(scene => scene.Name == options.subRoomName)?.RoomSceneId;
|
const subroomId = targetRoom.Scenes.find(scene => scene.Name == options.subRoomName)?.RoomSceneId;
|
||||||
if (subroomId) allInstances = allInstances.filter(instance => instance.subRoomId == subroomId);
|
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) {
|
if (!foundInstance) {
|
||||||
|
|
||||||
const matchmakeableSubrooms = targetRoom.Scenes.filter(scene => scene.CanMatchmakeInto);
|
const matchmakeableSubrooms = targetRoom.Scenes.filter(scene => scene.CanMatchmakeInto);
|
||||||
const newInstance = Instances.createInstance({
|
const newInstance = await Instances.createInstance({
|
||||||
Room: targetRoom,
|
Room: targetRoom,
|
||||||
SceneIndex: Math.floor(Math.random() * matchmakeableSubrooms.length),
|
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 };
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: newInstance };
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
const currentInstance = options.profile.getInstance();
|
||||||
|
if (currentInstance?.roomInstanceId == foundInstance.roomInstanceId)
|
||||||
|
return { errorCode: MatchmakingErrorCode.AlreadyInBestInstance };
|
||||||
|
|
||||||
await Instances.setPlayerInstance(options.profile, foundInstance);
|
await Instances.setPlayerInstance(options.profile, foundInstance);
|
||||||
|
|
||||||
|
Instances.clearAllRoomEmptyInstances(roomId);
|
||||||
|
|
||||||
return { errorCode: MatchmakingErrorCode.Success, roomInstance: foundInstance };
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: foundInstance };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import Logging from "@proxnet/undead-logging";
|
import Logging from "@proxnet/undead-logging";
|
||||||
import { Profile } from "../profiles.ts";
|
import UnifiedProfile, { Profile } from "../profiles.ts";
|
||||||
import { RoomInstance, InstanceOptions } from "./types.ts";
|
import { RoomInstance, InstanceOptions } from "./types.ts";
|
||||||
import { Config } from "../../config.ts";
|
import { Config } from "../../config.ts";
|
||||||
import Presence from "./presence.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.
|
* 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 scene = options.Room.Scenes[options.SceneIndex];
|
||||||
const newId = this.#generateUniqueInstanceId();
|
const newId = this.#generateUniqueInstanceId();
|
||||||
if (!scene) throw new Error("The specified scene did not exist.");
|
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 = {
|
const newInstance: RoomInstance = {
|
||||||
roomInstanceId: newId,
|
roomInstanceId: newId,
|
||||||
roomId: options.Room.Room.RoomId,
|
roomId: options.Room.Room.RoomId,
|
||||||
subRoomId: scene.RoomSceneId,
|
subRoomId: scene.RoomSceneId,
|
||||||
location: scene.RoomSceneLocationId,
|
location: scene.RoomSceneLocationId,
|
||||||
dataBlob: scene.DataBlobName == "" ? undefined : scene.DataBlobName,
|
dataBlob: scene.DataBlobName,
|
||||||
eventId: options.EventId,
|
eventId: options.EventId,
|
||||||
photonRegionId: config.public.photonRegionId,
|
photonRegionId: config.public.photonRegionId,
|
||||||
photonRoomId: `20191120-GC${newId}`,
|
photonRoomId: `20200306-GC${newId}`,
|
||||||
name: scene.Name === "Home" ? `^${options.Room.Room.Name}` : `^${options.Room.Room.Name}.${scene.Name}`,
|
name: instanceName,
|
||||||
maxCapacity: scene.MaxPlayers,
|
maxCapacity: scene.MaxPlayers,
|
||||||
isFull: false,
|
isFull: false,
|
||||||
isPrivate: typeof options.Private !== 'boolean' ? false : options.Private,
|
isPrivate: typeof options.Private !== 'boolean' ? false : options.Private,
|
||||||
@@ -161,7 +167,9 @@ class InstancesBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.instanceCanFitPlayer(instance)) {
|
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);
|
player.setInstance(instance);
|
||||||
const pres = await Presence.get(player);
|
const pres = await Presence.get(player);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -58,7 +58,7 @@ export interface RoomInstance {
|
|||||||
location: string,
|
location: string,
|
||||||
dataBlob?: string,
|
dataBlob?: string,
|
||||||
eventId?: number,
|
eventId?: number,
|
||||||
photonRegionId: PhotonRegionCodeString,
|
photonRegionId: PhotonRegionCodeString | PhotonRegionCodeNumber,
|
||||||
photonRoomId: string,
|
photonRoomId: string,
|
||||||
name?: string,
|
name?: string,
|
||||||
maxCapacity: number,
|
maxCapacity: number,
|
||||||
@@ -75,7 +75,8 @@ export interface InstanceOptions {
|
|||||||
EventId?: number,
|
EventId?: number,
|
||||||
Name?: string,
|
Name?: string,
|
||||||
Private?: boolean,
|
Private?: boolean,
|
||||||
FirstPlayer?: Profile
|
FirstPlayer?: Profile,
|
||||||
|
IsDorm?: boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -24,4 +24,14 @@ export enum PlatformMask {
|
|||||||
HeadlessBot = 16,
|
HeadlessBot = 16,
|
||||||
IOS = 32,
|
IOS = 32,
|
||||||
All = -1
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -21,6 +21,10 @@ export class ProfileContentManager {
|
|||||||
this.profileId = profileId;
|
this.profileId = profileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onProfileInit() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
profileId: number;
|
profileId: number;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import { Redis } from "../../db.ts";
|
import { Redis } from "../../db.ts";
|
||||||
import { SettingKey } from "../content/settings.ts";
|
import { SettingKey, SettingDefault } from "../content/settings.ts";
|
||||||
import { ProfileContentManager } from "./base/profilemanagerbase.ts";
|
import { ProfileContentManager } from "./base/profilemanagerbase.ts";
|
||||||
|
|
||||||
export interface Setting {
|
export interface Setting {
|
||||||
@@ -26,6 +26,14 @@ export interface Setting {
|
|||||||
|
|
||||||
export class ProfileSettingsManager extends ProfileContentManager {
|
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() {
|
async getSettings() {
|
||||||
const settings = await Redis.Database.hgetall(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings));
|
const settings = await Redis.Database.hgetall(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.profileId.toString(), Redis.KeyGroups.Profiles.Settings));
|
||||||
const returnSettings: Setting[] = [];
|
const returnSettings: Setting[] = [];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -140,7 +140,11 @@ class Profile {
|
|||||||
newUsername,
|
newUsername,
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Profile(newId);
|
const profile = new Profile(newId);
|
||||||
|
|
||||||
|
profile.Settings.onProfileInit();
|
||||||
|
|
||||||
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// surely this can be written better
|
// surely this can be written better
|
||||||
@@ -164,7 +168,7 @@ class Profile {
|
|||||||
platforms: 1,
|
platforms: 1,
|
||||||
username: values[2] == null ? "DATABASEERROR" : values[2],
|
username: values[2] == null ? "DATABASEERROR" : values[2],
|
||||||
displayName: values[3] == null ? (values[2] == null ? "DATABASEERROR" : values[2]) : values[3],
|
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() {
|
async getBio() {
|
||||||
const bio = await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, this.#id.toString(), Redis.KeyGroups.Profiles.Bio));
|
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;
|
else return bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +306,7 @@ class Profile {
|
|||||||
sub: this.#id,
|
sub: this.#id,
|
||||||
role: (await this.getIsOperator()) ? 'developer' : 'user',
|
role: (await this.getIsOperator()) ? 'developer' : 'user',
|
||||||
exp: Math.round(Date.now() / 1000) + Math.round(config.auth.timeout * 60 * 60),
|
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" });
|
return await JsonWebToken.encode(payload, config.auth.secret, { algorithm: "HS512" });
|
||||||
}
|
}
|
||||||
@@ -335,6 +339,15 @@ class UnifiedProfileBase {
|
|||||||
return await Profile.existsByName(name);
|
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();
|
const UnifiedProfile = new UnifiedProfileBase();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 = {
|
const Dictionary = {
|
||||||
Adjectives: [
|
Adjectives: [
|
||||||
"Amazing",
|
"Amazing",
|
||||||
"Adventurous",
|
|
||||||
"Affable",
|
"Affable",
|
||||||
"Agreeable",
|
"Agreeable",
|
||||||
"Ambitious",
|
"Ambitious",
|
||||||
"Amicable",
|
"Amicable",
|
||||||
"Animated",
|
"Animated",
|
||||||
"Approachable",
|
|
||||||
"Articulate",
|
|
||||||
"Astute",
|
"Astute",
|
||||||
"Attractive",
|
|
||||||
"Authentic",
|
"Authentic",
|
||||||
"Benevolent",
|
|
||||||
"Blissful",
|
"Blissful",
|
||||||
"Bold",
|
"Bold",
|
||||||
"Bright",
|
"Bright",
|
||||||
"Buoyant",
|
"Buoyant",
|
||||||
"Calm",
|
"Calm",
|
||||||
"Captivating",
|
|
||||||
"Charismatic",
|
|
||||||
"Cheerful",
|
"Cheerful",
|
||||||
"Clever",
|
"Clever",
|
||||||
"Compassionate",
|
|
||||||
"Confident",
|
"Confident",
|
||||||
"Considerate",
|
|
||||||
"Content",
|
"Content",
|
||||||
"Cooperative",
|
|
||||||
"Courageous",
|
|
||||||
"Creative",
|
"Creative",
|
||||||
"Cultured",
|
"Cultured",
|
||||||
"Curious",
|
"Curious",
|
||||||
"Dashing",
|
"Dashing",
|
||||||
"Dazzling",
|
"Dazzling",
|
||||||
"Dedicated",
|
"Dedicated",
|
||||||
"Delightful",
|
|
||||||
"Dependable",
|
|
||||||
"Determined",
|
|
||||||
"Diligent",
|
"Diligent",
|
||||||
"Dynamic",
|
"Dynamic",
|
||||||
"Earnest",
|
"Earnest",
|
||||||
"Easygoing",
|
"Easygoing",
|
||||||
"Ebullient",
|
"Ebullient",
|
||||||
"Effervescent",
|
|
||||||
"Empathetic",
|
|
||||||
"Enchanting",
|
|
||||||
"Endearing",
|
"Endearing",
|
||||||
"Energetic",
|
"Energetic",
|
||||||
"Engaging",
|
"Engaging",
|
||||||
"Enthusiastic",
|
|
||||||
"Exuberant",
|
"Exuberant",
|
||||||
"Fantastic",
|
"Fantastic",
|
||||||
"Fearless",
|
"Fearless",
|
||||||
@@ -77,28 +59,17 @@ const Dictionary = {
|
|||||||
"Genuine",
|
"Genuine",
|
||||||
"Gracious",
|
"Gracious",
|
||||||
"Grateful",
|
"Grateful",
|
||||||
"Harmonious",
|
|
||||||
"Heartwarming",
|
|
||||||
"Helpful",
|
"Helpful",
|
||||||
"Honest",
|
"Honest",
|
||||||
"Humble",
|
"Humble",
|
||||||
"Humorous",
|
"Humorous",
|
||||||
"Imaginative",
|
|
||||||
"Impeccable",
|
|
||||||
"Incisive",
|
"Incisive",
|
||||||
"Incredible",
|
|
||||||
"Independent",
|
|
||||||
"Industrious",
|
|
||||||
"Ingenious",
|
"Ingenious",
|
||||||
"Insightful",
|
|
||||||
"Intelligent",
|
|
||||||
"Intuitive",
|
"Intuitive",
|
||||||
"Invigorating",
|
|
||||||
"Jovial",
|
"Jovial",
|
||||||
"Jubilant",
|
"Jubilant",
|
||||||
"Just",
|
"Just",
|
||||||
"Kind",
|
"Kind",
|
||||||
"Knowledgeable",
|
|
||||||
"Likable",
|
"Likable",
|
||||||
"Lively",
|
"Lively",
|
||||||
"Lovable",
|
"Lovable",
|
||||||
@@ -110,24 +81,14 @@ const Dictionary = {
|
|||||||
"Masterful",
|
"Masterful",
|
||||||
"Mature",
|
"Mature",
|
||||||
"Merciful",
|
"Merciful",
|
||||||
"Methodical",
|
|
||||||
"Meticulous",
|
|
||||||
"Mindful",
|
"Mindful",
|
||||||
"Motivated",
|
"Motivated",
|
||||||
"Natural",
|
"Natural",
|
||||||
"Nurturing",
|
"Nurturing",
|
||||||
"Observant",
|
"Observant",
|
||||||
"Optimistic",
|
|
||||||
"Outgoing",
|
"Outgoing",
|
||||||
"Passionate",
|
|
||||||
"Patient",
|
"Patient",
|
||||||
"Peaceful",
|
"Peaceful",
|
||||||
"Perceptive",
|
|
||||||
"Perseverant",
|
|
||||||
"Persistent",
|
|
||||||
"Persuasive",
|
|
||||||
"Personable",
|
|
||||||
"Philanthropic",
|
|
||||||
"Placid",
|
"Placid",
|
||||||
"Playful",
|
"Playful",
|
||||||
"Pleasant",
|
"Pleasant",
|
||||||
@@ -136,20 +97,14 @@ const Dictionary = {
|
|||||||
"Powerful",
|
"Powerful",
|
||||||
"Pragmatic",
|
"Pragmatic",
|
||||||
"Proactive",
|
"Proactive",
|
||||||
"Proficient",
|
|
||||||
"Prudent",
|
"Prudent",
|
||||||
"Punctual",
|
"Punctual",
|
||||||
"Purposeful",
|
|
||||||
"Radiant",
|
"Radiant",
|
||||||
"Rational",
|
"Rational",
|
||||||
"Real",
|
"Real",
|
||||||
"Receptive",
|
"Receptive",
|
||||||
"Reflective",
|
|
||||||
"Reliable",
|
"Reliable",
|
||||||
"Resilient",
|
"Resilient",
|
||||||
"Resourceful",
|
|
||||||
"Respectful",
|
|
||||||
"Responsible",
|
|
||||||
"Robust",
|
"Robust",
|
||||||
"Sagacious",
|
"Sagacious",
|
||||||
"Serene",
|
"Serene",
|
||||||
@@ -159,33 +114,23 @@ const Dictionary = {
|
|||||||
"Sociable",
|
"Sociable",
|
||||||
"Spirited",
|
"Spirited",
|
||||||
"Splendid",
|
"Splendid",
|
||||||
"Spontaneous",
|
|
||||||
"Steady",
|
"Steady",
|
||||||
"Sterling",
|
"Sterling",
|
||||||
"Strong",
|
"Strong",
|
||||||
"Sublime",
|
"Sublime",
|
||||||
"Successful",
|
|
||||||
"Supportive",
|
|
||||||
"Sympathetic",
|
|
||||||
"Talented",
|
"Talented",
|
||||||
"Tenacious",
|
"Tenacious",
|
||||||
"Thoughtful",
|
|
||||||
"Tireless",
|
"Tireless",
|
||||||
"Tolerant",
|
"Tolerant",
|
||||||
"Tough",
|
"Tough",
|
||||||
"Tranquil",
|
"Tranquil",
|
||||||
"Trustworthy",
|
|
||||||
"Unassuming",
|
|
||||||
"Understanding",
|
|
||||||
"Unique",
|
"Unique",
|
||||||
"Unpretentious",
|
|
||||||
"Upbeat",
|
"Upbeat",
|
||||||
"Valiant",
|
"Valiant",
|
||||||
"Vibrant",
|
"Vibrant",
|
||||||
"Virtuous",
|
"Virtuous",
|
||||||
"Visionary",
|
"Visionary",
|
||||||
"Vivacious",
|
"Vivacious",
|
||||||
"Warmhearted",
|
|
||||||
"Welcoming",
|
"Welcoming",
|
||||||
"Wise",
|
"Wise",
|
||||||
"Witty",
|
"Witty",
|
||||||
@@ -198,7 +143,6 @@ const Dictionary = {
|
|||||||
"Elysium",
|
"Elysium",
|
||||||
"Horizon",
|
"Horizon",
|
||||||
"Catalyst",
|
"Catalyst",
|
||||||
"Luminescence",
|
|
||||||
"Utopia",
|
"Utopia",
|
||||||
"Eclipse",
|
"Eclipse",
|
||||||
"Nebula",
|
"Nebula",
|
||||||
@@ -220,7 +164,6 @@ const Dictionary = {
|
|||||||
"Vibrance",
|
"Vibrance",
|
||||||
"Astral",
|
"Astral",
|
||||||
"Jubilant",
|
"Jubilant",
|
||||||
"Ascendancy",
|
|
||||||
"Zen",
|
"Zen",
|
||||||
"Nebulous",
|
"Nebulous",
|
||||||
"Ecliptic",
|
"Ecliptic",
|
||||||
@@ -233,7 +176,6 @@ const Dictionary = {
|
|||||||
"Enigma",
|
"Enigma",
|
||||||
"Luminous",
|
"Luminous",
|
||||||
"Epoch",
|
"Epoch",
|
||||||
"Serendipity",
|
|
||||||
"Zenithal",
|
"Zenithal",
|
||||||
"Paragon",
|
"Paragon",
|
||||||
"Panorama",
|
"Panorama",
|
||||||
@@ -255,7 +197,6 @@ const Dictionary = {
|
|||||||
"Endeavor",
|
"Endeavor",
|
||||||
"Visionary",
|
"Visionary",
|
||||||
"Epoch",
|
"Epoch",
|
||||||
"Renaissance",
|
|
||||||
"Panache",
|
"Panache",
|
||||||
"Jubilee",
|
"Jubilee",
|
||||||
"Resonance",
|
"Resonance",
|
||||||
@@ -264,13 +205,11 @@ const Dictionary = {
|
|||||||
"Ethereal",
|
"Ethereal",
|
||||||
"Cascade",
|
"Cascade",
|
||||||
"Radiance",
|
"Radiance",
|
||||||
"Synchronicity",
|
|
||||||
"Nebula",
|
"Nebula",
|
||||||
"Equinox",
|
"Equinox",
|
||||||
"Pulsar",
|
"Pulsar",
|
||||||
"Apex",
|
"Apex",
|
||||||
"Ethos",
|
"Ethos",
|
||||||
"Wanderlust",
|
|
||||||
"Zenith",
|
"Zenith",
|
||||||
"Nebula",
|
"Nebula",
|
||||||
"Vertex",
|
"Vertex",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -76,6 +76,7 @@ export const KeyGroups = {
|
|||||||
},
|
},
|
||||||
Profile_Usernames: "profile-usernames",
|
Profile_Usernames: "profile-usernames",
|
||||||
PlatformAssociations: "platforms",
|
PlatformAssociations: "platforms",
|
||||||
|
AddressBans: "address-bans",
|
||||||
Profiles: {
|
Profiles: {
|
||||||
Root: "profiles",
|
Root: "profiles",
|
||||||
Username: "username",
|
Username: "username",
|
||||||
@@ -87,6 +88,7 @@ export const KeyGroups = {
|
|||||||
DeviceClass: "deviceClass",
|
DeviceClass: "deviceClass",
|
||||||
Xp: "xp",
|
Xp: "xp",
|
||||||
Bio: "bio",
|
Bio: "bio",
|
||||||
|
Rooms: "rooms",
|
||||||
Relationships: {
|
Relationships: {
|
||||||
Root: "relationships",
|
Root: "relationships",
|
||||||
IncomingFriendRequests: "incomingFriendRequests",
|
IncomingFriendRequests: "incomingFriendRequests",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { SocketHandoff } from "./socket/handoff.ts";
|
||||||
import { SignalRSocketHandler } from "./socket/socket.ts";
|
import { SignalRSocketHandler } from "./socket/socket.ts";
|
||||||
import Rooms from "./data/content/rooms.ts";
|
import Rooms from "./data/content/rooms.ts";
|
||||||
|
import { GameConfigs } from "./data/config.ts";
|
||||||
|
|
||||||
const instanceId = generateRandomString(64);
|
const instanceId = generateRandomString(64);
|
||||||
|
|
||||||
@@ -114,10 +115,6 @@ if (!(await Rooms.generateBuiltinRooms())) log.i(`Generated built-in rooms`);
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
/**
|
|
||||||
* Galvanic WebSocket Server
|
|
||||||
*/
|
|
||||||
|
|
||||||
type AuthResultBase = {
|
type AuthResultBase = {
|
||||||
valid: boolean
|
valid: boolean
|
||||||
}
|
}
|
||||||
@@ -133,10 +130,13 @@ try {
|
|||||||
const authHeader = req.headers.get('authorization');
|
const authHeader = req.headers.get('authorization');
|
||||||
if (!authHeader) return { valid: false } as AuthResult;
|
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;
|
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);
|
const schemaResult = ProfileTokenSchema.safeParse(decodedToken);
|
||||||
if (!schemaResult.success) return { valid: false } as AuthResult;
|
if (!schemaResult.success) return { valid: false } as AuthResult;
|
||||||
else return { token: decodedToken, valid: true } as AuthResult;
|
else return { token: decodedToken, valid: true } as AuthResult;
|
||||||
@@ -149,6 +149,14 @@ try {
|
|||||||
|
|
||||||
const abort = new AbortController();
|
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
|
// Galvanic WebSocket
|
||||||
Deno.serve({port: config.web.socket.port, hostname: config.web.socket.host, signal: abort.signal, onListen: addr => {
|
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}`);
|
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("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 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 => {
|
http.on('error', err => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 AccountRoute } from "./account/account.ts";
|
||||||
import { route as ParentalControlRoute } from "./account/parentalcontrol.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(AccountRoute.path, AccountRoute.router);
|
||||||
route.router.use(ParentalControlRoute.path, ParentalControlRoute.router);
|
route.router.use(ParentalControlRoute.path, ParentalControlRoute.router);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 express from "express";
|
||||||
import UnifiedProfile, { Profile } from "../../data/profiles.ts";
|
import UnifiedProfile, { Profile } from "../../data/profiles.ts";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { AuthType } from "../../data/users.ts";
|
||||||
|
|
||||||
export const route = APIUtils.createRouter("/account");
|
export const route = APIUtils.createRouter("/account");
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ const CreateAccountRequestBodySchema = z.object({
|
|||||||
deviceId: z.string()
|
deviceId: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
const rateLimit = new APIUtils.RateLimiter(25, 5);
|
const rateLimit = new APIUtils.RateLimiter();
|
||||||
|
|
||||||
route.router.post("/create",
|
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 {
|
interface BioFetchParams {
|
||||||
id?: string
|
id?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import { APIUtils } from "../../apiutils.ts";
|
import { APIUtils } from "../../apiutils.ts";
|
||||||
|
import { AuthType } from "../../data/users.ts";
|
||||||
|
|
||||||
export const route = APIUtils.createRouter("/challenge");
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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");
|
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) => {
|
route.router.get("/v2", rateLimit.middle(), (_rq, rs) => {
|
||||||
const config = GameConfigs.getConfig();
|
const config = GameConfigs.getConfig();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -27,4 +27,4 @@ route.router.get('/v2/getUnlocked',
|
|||||||
|
|
||||||
APIUtils.emptyArrayResponse
|
APIUtils.emptyArrayResponse
|
||||||
|
|
||||||
)
|
);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import { APIUtils } from "../../apiutils.ts";
|
import { APIUtils } from "../../apiutils.ts";
|
||||||
|
import { GameConfigs } from "../../data/config.ts";
|
||||||
|
|
||||||
export const route = APIUtils.createRouter("/gameconfigs");
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
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/>. */
|
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 { AuthType } from "../../data/users.ts";
|
||||||
|
import express from "express";
|
||||||
|
|
||||||
export const route = APIUtils.createRouter('/objectives');
|
export const route = APIUtils.createRouter('/objectives');
|
||||||
|
|
||||||
@@ -32,4 +34,28 @@ 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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -38,4 +38,16 @@ route.router.get('/v1/:id',
|
|||||||
rs.json(await UnifiedProfile.get(parsedPlayerId).Reputation.getReputation());
|
rs.json(await UnifiedProfile.get(parsedPlayerId).Reputation.getReputation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { APIUtils } from "../../apiutils.ts";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import UnifiedProfile from "../../data/profiles.ts";
|
import UnifiedProfile from "../../data/profiles.ts";
|
||||||
|
import { AuthType } from "../../data/users.ts";
|
||||||
|
|
||||||
const log = new Logging("ProgressionRoute");
|
const log = new Logging("ProgressionRoute");
|
||||||
|
|
||||||
const rateLimit = new APIUtils.RateLimiter(60, 2);
|
const rateLimit = new APIUtils.RateLimiter();
|
||||||
|
|
||||||
export const route = APIUtils.createRouter("/players");
|
export const route = APIUtils.createRouter("/players");
|
||||||
|
|
||||||
@@ -48,4 +49,15 @@ route.router.get('/v1/progression/:id',
|
|||||||
rs.json(res);
|
rs.json(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -66,7 +66,7 @@ route.router.get('/v1/hot',
|
|||||||
async (_rq, rs) => {
|
async (_rq, rs) => {
|
||||||
// temporary: return all public AG rooms for testing
|
// temporary: return all public AG rooms for testing
|
||||||
const rooms = await Rooms.getAllBuiltinRoomGenerations();
|
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());
|
const room = await Rooms.getByName(rq.params.name.trim());
|
||||||
if (!room || rq.params.name == 'DormRoom') {
|
if (room) {
|
||||||
rs.sendStatus(404);
|
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;
|
return;
|
||||||
} else {
|
} else {
|
||||||
rs.json(room.Room);
|
rs.sendStatus(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -118,4 +123,4 @@ route.router.post('/v1/roomRolePermissions',
|
|||||||
rs.sendStatus(200);
|
rs.sendStatus(200);
|
||||||
},
|
},
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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) => {
|
(rq: express.Request<NoBody, NoBody, SettingsSetBody>, rs: express.Response) => {
|
||||||
rs.locals.profile.Settings.setSettingRaw(rq.body.Key, rq.body.Value),
|
rs.locals.profile.Settings.setSettingRaw(rq.body.Key, rq.body.Value),
|
||||||
rs.json({
|
rs.sendStatus(200);
|
||||||
Succeeded: true,
|
log.d(`${rs.locals.profile.getId()} set settings key '${rq.body.Key}' to '${rq.body.Value}'`);
|
||||||
Error: "",
|
|
||||||
ShouldRetry: false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { APIUtils } from "../../apiutils.ts";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
|
import { AuthType } from "../../data/users.ts";
|
||||||
|
import { CurrencyType, StorefrontBalanceType } from "../../data/content/storefronts.ts";
|
||||||
|
|
||||||
export const route = APIUtils.createRouter('/storefronts');
|
export const route = APIUtils.createRouter('/storefronts');
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ interface StorefrontFetchParams {
|
|||||||
route.router.get('/v3/giftdropstore/:id',
|
route.router.get('/v3/giftdropstore/:id',
|
||||||
|
|
||||||
APIUtils.Authentication,
|
APIUtils.Authentication,
|
||||||
|
APIUtils.AuthenticationType(AuthType.Game),
|
||||||
|
|
||||||
(rq: express.Request<StorefrontFetchParams>, rs: express.Response) => {
|
(rq: express.Request<StorefrontFetchParams>, rs: express.Response) => {
|
||||||
if (!rq.params.id) {
|
if (!rq.params.id) {
|
||||||
@@ -39,4 +42,28 @@ 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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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");
|
export const route = APIUtils.createRouter("/versioncheck");
|
||||||
|
|
||||||
const validVersion = "20191120";
|
export const validVersions = [
|
||||||
|
"20200306"
|
||||||
|
];
|
||||||
|
|
||||||
enum VersionStatus {
|
enum VersionStatus {
|
||||||
ValidForPlay,
|
ValidForPlay,
|
||||||
@@ -35,10 +37,10 @@ route.router.get("/v4", (rq, rs) => {
|
|||||||
const requestedVer = rq.query["v"];
|
const requestedVer = rq.query["v"];
|
||||||
const pQuery = rq.query["p"];
|
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.statusCode = 400;
|
||||||
rs.json(APIUtils.genericResponseFormat(true, "One or more query parameters were not found."));
|
rs.json(APIUtils.genericResponseFormat(true, "One or more query parameters were not found or invalid."));
|
||||||
} else if (requestedVer !== validVersion) {
|
} else if (!validVersions.includes(requestedVer as string)) {
|
||||||
const res: ValidVersionResponse = {
|
const res: ValidVersionResponse = {
|
||||||
VersionStatus: VersionStatus.UpdateRequired,
|
VersionStatus: VersionStatus.UpdateRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { APIUtils } from "../apiutils.ts";
|
||||||
import { route as CachedLoginRoute } from "./auth/cachedlogin.ts";
|
import { route as CachedLoginRoute } from "./auth/cachedlogin.ts";
|
||||||
import { route as ConnectRoute } from "./auth/connect.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(CachedLoginRoute.path, CachedLoginRoute.router);
|
||||||
route.router.use(ConnectRoute.path, ConnectRoute.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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 { z } from "zod";
|
||||||
import { AuthType } from "../../data/users.ts";
|
import { AuthType } from "../../data/users.ts";
|
||||||
import { Redis } from "../../db.ts";
|
import { Redis } from "../../db.ts";
|
||||||
|
import { validVersions } from "../api/versioncheck.ts";
|
||||||
|
|
||||||
const config = Config.getConfig();
|
const config = Config.getConfig();
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ route.router.post("/token",
|
|||||||
const conditionsMet = ![
|
const conditionsMet = ![
|
||||||
rq.body.client_id === "recroom",
|
rq.body.client_id === "recroom",
|
||||||
rq.body.platform === "0",
|
rq.body.platform === "0",
|
||||||
rq.body.ver === '20191120',
|
validVersions.includes(rq.body.ver),
|
||||||
rq.body.device_class.length === 1,
|
rq.body.device_class.length === 1,
|
||||||
!isNaN(Number(rq.body.device_class)),
|
!isNaN(Number(rq.body.device_class)),
|
||||||
!(rq.body.device_id.length > 96),
|
!(rq.body.device_id.length > 96),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -36,6 +36,7 @@ interface ImageQueryOptions {
|
|||||||
cropSquare?: string;
|
cropSquare?: string;
|
||||||
width?: string;
|
width?: string;
|
||||||
height?: string;
|
height?: string;
|
||||||
|
sig?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
route.router.get(
|
route.router.get(
|
||||||
@@ -49,8 +50,6 @@ route.router.get(
|
|||||||
rq.path.substring(1, rq.path.length).replaceAll("%20", " "),
|
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;
|
let image: Image;
|
||||||
const imageSource = baseImages.includes(filename)
|
const imageSource = baseImages.includes(filename)
|
||||||
? BaseImages.getBaseImage(filename)
|
? BaseImages.getBaseImage(filename)
|
||||||
@@ -80,6 +79,23 @@ route.router.get(
|
|||||||
else height = num;
|
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) {
|
if (width && height) {
|
||||||
const targetWidth = width > image.width ? image.width : width;
|
const targetWidth = width > image.width ? image.width : width;
|
||||||
const targetHeight = height > image.height ? image.height : height;
|
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 (width) image.resize(width, Image.RESIZE_AUTO);
|
||||||
else if (height) image.resize(Image.RESIZE_AUTO, height);
|
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()));
|
rs.type("png").send(Buffer.from(await image.encode()));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -35,8 +35,9 @@ route.router.post('/room/:roomName',
|
|||||||
|
|
||||||
APIUtils.Authentication,
|
APIUtils.Authentication,
|
||||||
APIUtils.AuthenticationType(AuthType.Game),
|
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) {
|
if (!rq.params.roomName) {
|
||||||
log.d('Matchmake failed: No room specified');
|
log.d('Matchmake failed: No room specified');
|
||||||
rs.json({
|
rs.json({
|
||||||
@@ -45,22 +46,30 @@ route.router.post('/room/:roomName',
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName }));
|
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName }));
|
||||||
|
nxt();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
APIUtils.stopTimer
|
||||||
|
|
||||||
);
|
);
|
||||||
route.router.post('/room/:roomName/:subRoomName',
|
route.router.post('/room/:roomName/:subRoomName',
|
||||||
|
|
||||||
APIUtils.Authentication,
|
APIUtils.Authentication,
|
||||||
APIUtils.AuthenticationType(AuthType.Game),
|
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) {
|
if (!rq.params.roomName) {
|
||||||
|
log.d('Matchmake failed: No room specified');
|
||||||
rs.json({
|
rs.json({
|
||||||
errorCode: MatchmakingErrorCode.NoSuchRoom
|
errorCode: MatchmakingErrorCode.NoSuchRoom
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName, subRoomName: rq.params.subRoomName }));
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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 UnifiedProfile from "../../data/profiles.ts";
|
||||||
import { PlayerStatusVisibility, VRMovementMode } from "../../data/live/types.ts";
|
import { PlayerStatusVisibility, VRMovementMode } from "../../data/live/types.ts";
|
||||||
import { SettingKey } from "../../data/content/settings.ts";
|
import { SettingKey } from "../../data/content/settings.ts";
|
||||||
|
import Instances from "../../data/live/instances.ts";
|
||||||
|
|
||||||
const log = new Logging("MatchPlayerRoute");
|
const log = new Logging("MatchPlayerRoute");
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ route.router.post('/logout',
|
|||||||
APIUtils.validateRequestBody(LoginSchema),
|
APIUtils.validateRequestBody(LoginSchema),
|
||||||
|
|
||||||
(_rq, rs) => {
|
(_rq, rs) => {
|
||||||
Matchmaking.deleteLoginLock(rs.locals.profile);
|
Instances.removePlayerFromCurrentInstance(rs.locals.profile);
|
||||||
rs.sendStatus(200);
|
rs.sendStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,14 +111,14 @@ interface StatusVisibilityBody {
|
|||||||
statusVisibility: PlayerStatusVisibility
|
statusVisibility: PlayerStatusVisibility
|
||||||
}
|
}
|
||||||
const StatusVisibilitySchema = z.object({
|
const StatusVisibilitySchema = z.object({
|
||||||
statusVisibility: z.nativeEnum(PlayerStatusVisibility)
|
statusVisibility: z.enum(Object.values(PlayerStatusVisibility).map(String) as [string, ...string[]])
|
||||||
});
|
});
|
||||||
|
|
||||||
route.router.put('/statusvisibility',
|
route.router.put('/statusvisibility',
|
||||||
|
|
||||||
APIUtils.Authentication,
|
APIUtils.Authentication,
|
||||||
APIUtils.AuthenticationType(AuthType.Game),
|
APIUtils.AuthenticationType(AuthType.Game),
|
||||||
express.urlencoded({ extended: true }),
|
express.urlencoded({ extended: true }),
|
||||||
|
APIUtils.logBody,
|
||||||
APIUtils.validateRequestBody(StatusVisibilitySchema),
|
APIUtils.validateRequestBody(StatusVisibilitySchema),
|
||||||
|
|
||||||
async (rq: express.Request<NoBody, NoBody, StatusVisibilityBody>, rs: express.Response) => {
|
async (rq: express.Request<NoBody, NoBody, StatusVisibilityBody>, rs: express.Response) => {
|
||||||
@@ -148,4 +149,15 @@ route.router.put('/vrmovementmode',
|
|||||||
rs.sendStatus(200);
|
rs.sendStatus(200);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
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.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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");
|
export const route = APIUtils.createRouter("/ns");
|
||||||
|
|
||||||
type NameserverHosts = {
|
type NameserverHosts = {
|
||||||
|
Accounts: string;
|
||||||
Auth: string;
|
Auth: string;
|
||||||
API: string;
|
API: string;
|
||||||
WWW: string;
|
WWW: string;
|
||||||
@@ -38,6 +39,7 @@ type NameserverHosts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const nameserver: NameserverHosts = {
|
const nameserver: NameserverHosts = {
|
||||||
|
Accounts: `${protocol}://${config.web.api.publichost}/accounts`,
|
||||||
Auth: `${protocol}://${config.web.api.publichost}/auth`,
|
Auth: `${protocol}://${config.web.api.publichost}/auth`,
|
||||||
API: `${protocol}://${config.web.api.publichost}`,
|
API: `${protocol}://${config.web.api.publichost}`,
|
||||||
WWW: `${protocol}://${config.web.api.publichost}`,
|
WWW: `${protocol}://${config.web.api.publichost}`,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@@ -57,7 +57,7 @@ const AuthRequestRootSchema = z.object({
|
|||||||
pubkey: z.string(),
|
pubkey: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const rateLimit = new APIUtils.RateLimiter(60, 2);
|
const rateLimit = new APIUtils.RateLimiter();
|
||||||
|
|
||||||
route.router.post("/auth",
|
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) => {
|
route.router.get('/checkExpired', checkRateLimit.middle(), async (rq, rs) => {
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ route.router.get('/checkExpired', checkRateLimit.middle(), async (rq, rs) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const decodedToken = await decode<UserTokenFormat>(token, config.auth.secret, { algorithm: "HS512", leeway: 31536000 }); // 1 year leeway
|
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 {
|
} catch {
|
||||||
rs.json(true);
|
rs.json(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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();
|
#Targets: Map<string, SocketTarget> = new Map();
|
||||||
|
|
||||||
#PresenceUpdateId: number;
|
#PeriodicalId: number;
|
||||||
|
|
||||||
constructor(socket: WebSocket, player: Profile) {
|
constructor(socket: WebSocket, player: Profile) {
|
||||||
|
|
||||||
@@ -57,9 +57,12 @@ export class SignalRSocketHandler {
|
|||||||
|
|
||||||
this.#Targets.set('SubscribeToPlayers', new PlayerSocketSubscriptionTarget());
|
this.#Targets.set('SubscribeToPlayers', new PlayerSocketSubscriptionTarget());
|
||||||
|
|
||||||
this.#PresenceUpdateId = setInterval(async () => {
|
this.#PeriodicalId = setInterval(async () => {
|
||||||
const pres = await Presence.get(this.#profile);
|
if (this.#socket.readyState !== this.#socket.CLOSED) {
|
||||||
this.sendNotification("PresenceUpdate", await pres.export());
|
const pres = await Presence.get(this.#profile);
|
||||||
|
this.sendNotification("PresenceUpdate", await pres.export());
|
||||||
|
this.sendRaw({ type: 6 });
|
||||||
|
}
|
||||||
}, 8000);
|
}, 8000);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -83,7 +86,7 @@ export class SignalRSocketHandler {
|
|||||||
this.sendRaw({});
|
this.sendRaw({});
|
||||||
return;
|
return;
|
||||||
} else {
|
} 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
|
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
|
const res = await this.#dispatchTarget(message.data.target, message.data.arguments[0]); // rec room only uses the first index
|
||||||
if (res.type == TargetResultType.Success) {
|
if (res.type == TargetResultType.Success) {
|
||||||
@@ -145,18 +148,19 @@ export class SignalRSocketHandler {
|
|||||||
|
|
||||||
destroy(sock: SignalRSocketHandler) {
|
destroy(sock: SignalRSocketHandler) {
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(sock.#PresenceUpdateId);
|
clearInterval(sock.#PeriodicalId);
|
||||||
sock.sendRaw({ type: 7, error: "Socket closed" });
|
sock.sendRaw({ type: 7, error: "Socket closed" });
|
||||||
sock.#socket.close();
|
sock.#socket.close();
|
||||||
sock.#log.i(`Closed hub socket`);
|
sock.#log.i(`Closed socket`);
|
||||||
|
sock.#profile.clearSocketHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRaw(data: object) {
|
sendRaw(data: object) {
|
||||||
this.#socket.send(`${JSON.stringify(data)}\u001e`);
|
this.#socket.send(`${JSON.stringify(data)}\u001e`);
|
||||||
// todo sometime: make this less confusing
|
// todo sometime: make the below less confusing
|
||||||
const type = `Type: ${JSON.stringify(data) == '{}' ? 'Protocol Message' : `${(data as SignalRMessage).type} (${SignalMessageType[(data as SignalRMessage).type]})`}`;
|
//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)}`);
|
//this.#log.d(`SERVER MESSAGE\n ${type}\n ${JSON.stringify(data as SignalRMessage)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNotification(id: PushNotificationId | string, args: object) {
|
sendNotification(id: PushNotificationId | string, args: object) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Galvanic Corrosion - Rec Room custom server for communities.
|
/* 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)
|
Copyright (C) 2025 @zombieb (Discord / proxnet Gitea)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
Reference in New Issue
Block a user