- 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
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
/* 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/>. */
|
|
|
|
const handoffs: Set<SocketHandoff> = new Set();
|
|
|
|
function randomId(length: number) {
|
|
let result = '';
|
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
let counter = 0;
|
|
while (counter < length) {
|
|
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
|
counter += 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reserve `connectionId`s for each connected client, hand off to socket handler when complete or timed out
|
|
*/
|
|
export class SocketHandoff {
|
|
|
|
static all() {
|
|
return Array.from(handoffs.values());
|
|
}
|
|
static generateId() {
|
|
let id = randomId(48);
|
|
while (handoffs.values().find(handoff => handoff.id == id)) id = randomId(48);
|
|
return id;
|
|
}
|
|
static find(id: string) {
|
|
return handoffs.values().find(handoff => handoff.id === id);
|
|
}
|
|
|
|
id: string;
|
|
|
|
#timeout: number;
|
|
|
|
constructor() {
|
|
this.id = SocketHandoff.generateId();
|
|
|
|
this.#timeout = setTimeout(() => {
|
|
this.complete();
|
|
});
|
|
|
|
handoffs.add(this);
|
|
}
|
|
|
|
complete() {
|
|
clearTimeout(this.#timeout);
|
|
handoffs.delete(this);
|
|
}
|
|
|
|
} |