Instancing (currently unused)
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
import Profile from "../profiles.ts";
|
||||
|
||||
const log = new Logging("Instances");
|
||||
|
||||
enum IntegratedRoomScene {
|
||||
Calibration = "f5fbd9c9-e853-4036-9d48-5f68e861af04",
|
||||
DormRoom = "76d98498-60a1-430c-ab76-b54a29b7a163",
|
||||
@@ -48,7 +51,7 @@ enum IntegratedRoomScene {
|
||||
DodgeballVR = "3d474b26-26f7-45e9-9a36-9b02847d5e6f",
|
||||
}
|
||||
|
||||
interface RoomInstance {
|
||||
export interface RoomInstance {
|
||||
|
||||
roomInstanceId: number,
|
||||
roomId: number,
|
||||
@@ -67,21 +70,98 @@ interface RoomInstance {
|
||||
}
|
||||
|
||||
const instancePlayers: Map<RoomInstance, Set<Profile>> = new Map();
|
||||
/**
|
||||
* `Map<roomId (number), RoomInstance>`
|
||||
*/
|
||||
const instanceMap: Map<number, Set<RoomInstance>> = new Map();
|
||||
|
||||
class InstancesBase {
|
||||
|
||||
async #ensureSubSet(roomId: number) {
|
||||
const subMap = instanceMap.get(roomId);
|
||||
if (!subMap) instanceMap.set(roomId, new Set());
|
||||
getAllInstances() {
|
||||
return new Set([...instanceMap.values()].flatMap(set => [...set]));
|
||||
}
|
||||
|
||||
// get all instances
|
||||
// get all instances for a room
|
||||
// do not put instance categorization here (instance searching, or "matchmaking"); put that in MatchmakingBase
|
||||
getAllRoomInstances(roomId: number) {
|
||||
let instances = instanceMap.get(roomId);
|
||||
if (!instances) {
|
||||
instances = new Set();
|
||||
instanceMap.set(roomId, instances);
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
getInstancePlayers(instance: RoomInstance): Set<Profile> {
|
||||
let players = instancePlayers.get(instance);
|
||||
if (!players) {
|
||||
players = new Set();
|
||||
instancePlayers.set(instance, players);
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
clearEmptyInstances(instances: Set<RoomInstance>, roomId?: number) {
|
||||
const beforeCount = instances.size;
|
||||
for (const instance of instances) {
|
||||
const profiles = this.getInstancePlayers(instance);
|
||||
if (profiles.size === 0) {
|
||||
log.i(`Instance ${instance.roomInstanceId} empty, deleting`);
|
||||
instancePlayers.delete(instance);
|
||||
this.getAllRoomInstances(instance.roomId).delete(instance);
|
||||
}
|
||||
}
|
||||
|
||||
const afterCount = instances.size;
|
||||
log.d(`Cleared ${roomId !== undefined ? `room ${roomId}` : 'all'} empty instances.\n Instances before: ${beforeCount}\n Instances after: ${afterCount}`);
|
||||
}
|
||||
|
||||
clearAllEmptyInstances() {
|
||||
this.clearEmptyInstances(this.getAllInstances());
|
||||
}
|
||||
|
||||
clearAllRoomEmptyInstances(roomId: number) {
|
||||
this.clearEmptyInstances(this.getAllRoomInstances(roomId), roomId);
|
||||
}
|
||||
|
||||
updateGlobalInstancesIsFull() {
|
||||
for (const instance of this.getAllInstances()) {
|
||||
instance.isFull = this.getInstancePlayers(instance).size >= instance.maxCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
updateSingleInstanceIsFull(instance: RoomInstance) {
|
||||
const profiles = this.getInstancePlayers(instance);
|
||||
if (profiles.size >= instance.maxCapacity) instance.isFull = true;
|
||||
else instance.isFull = false;
|
||||
}
|
||||
|
||||
instanceCanFitPlayer(instance: RoomInstance) {
|
||||
return this.getInstancePlayers(instance).size < instance.maxCapacity;
|
||||
}
|
||||
|
||||
// add, remove, check for, get profile(s) in instances
|
||||
// synchronize profile.#instance with the profile's current instance (profile.setInstance(RoomInstance)?)
|
||||
setPlayerInstance(player: Profile, instance: RoomInstance) {
|
||||
const currentInstance = player.getInstance();
|
||||
if (currentInstance === instance) return;
|
||||
|
||||
if (currentInstance) {
|
||||
this.getInstancePlayers(currentInstance).delete(player);
|
||||
this.updateSingleInstanceIsFull(currentInstance);
|
||||
}
|
||||
|
||||
if (this.instanceCanFitPlayer(instance)) {
|
||||
this.getInstancePlayers(instance).add(player);
|
||||
player.setInstance(instance);
|
||||
this.updateSingleInstanceIsFull(instance);
|
||||
} else log.w(`Instance ${instance.roomInstanceId} is full. Cannot add player ${player.getId()}`);
|
||||
}
|
||||
|
||||
playerIsInInstance(player: Profile, instance: RoomInstance) {
|
||||
|
||||
const profiles = this.getInstancePlayers(instance);
|
||||
return profiles.has(player);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Config } from "../config.ts";
|
||||
import { AuthType } from "./users.ts";
|
||||
import * as JsonWebToken from "@gz/jwt";
|
||||
import { TokenBaseFormat } from "../apiutils.ts";
|
||||
import { RoomInstance } from "./live/instances.ts";
|
||||
|
||||
const config = Config.getConfig();
|
||||
|
||||
@@ -180,15 +181,25 @@ class Profile {
|
||||
|
||||
#id: number;
|
||||
|
||||
#instance: RoomInstance | null = null;
|
||||
|
||||
constructor(id: number) {
|
||||
this.#id = id;
|
||||
}
|
||||
|
||||
setInstance(instance: RoomInstance) {
|
||||
this.#instance = instance;
|
||||
}
|
||||
|
||||
getInstance() {
|
||||
return this.#instance;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.#id;
|
||||
}
|
||||
|
||||
async getIsDev() {
|
||||
async getIsOperator() {
|
||||
return (await Redis.Database.sismember(Redis.buildKey(Redis.KeyGroups.Operators), this.#id.toString())) >= 1;
|
||||
}
|
||||
|
||||
@@ -203,7 +214,7 @@ class Profile {
|
||||
const payload: ProfileTokenFormat = {
|
||||
iss: config.web.publichost,
|
||||
sub: this.#id,
|
||||
role: (await this.getIsDev()) ? 'developer' : 'user',
|
||||
role: (await this.getIsOperator()) ? 'developer' : 'user',
|
||||
exp: Math.round(Date.now() / 1000) + Math.round(config.auth.timeout * 60 * 60),
|
||||
typ: AuthType.Game
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user