forked from zombieb/galvanic-corrosion-rewrite
roooooms 2
This commit is contained in:
@@ -1,17 +1,17 @@
|
||||
import Logging from "@proxnet/undead-logging";
|
||||
import type KV from "../../persistence/kv.ts";
|
||||
import { type ServerBase } from "../../server.ts";
|
||||
import { DatabaseRoom, FactoryMode, GalvanicTagDTO, RoomDataTypes, TagDTO, TagType, WriteMode } from "./RoomDataTypes.ts";
|
||||
import { DatabaseRoom, FactoryMode, GalvanicTagDTO, HardwareSupports, RoomAccessibility, RoomDataTypes, RoomState, TagDTO, TagType, WriteMode } from "./RoomDataTypes.ts";
|
||||
import { SubroomFactory } from "./SubroomFactory.ts";
|
||||
import { ServerRoomsBase } from "../base.ts";
|
||||
|
||||
const log = new Logging("RoomFactory");
|
||||
|
||||
const roomDebug = true;
|
||||
const roomDebug = false;
|
||||
|
||||
interface FactoryOptionsBase {
|
||||
mode: FactoryMode,
|
||||
id?: number,
|
||||
id: number,
|
||||
name?: string
|
||||
}
|
||||
export interface WriteFactoryOptions extends FactoryOptionsBase {
|
||||
@@ -36,6 +36,7 @@ export class RoomFactory {
|
||||
writeMode: WriteMode = WriteMode.WriteIfFree;
|
||||
|
||||
#obj: DatabaseRoom | null = null;
|
||||
#subrooms: Set<number> | null = null;
|
||||
#hardwareSupport: Set<RoomDataTypes.HardwareSupport> | null = null;
|
||||
#tags: Set<string> | null = null;
|
||||
|
||||
@@ -49,6 +50,22 @@ export class RoomFactory {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the factory. Retrieves the room from the database and populates factory values.
|
||||
*
|
||||
* Does not fetch subroom content, only available subroom IDs.
|
||||
*
|
||||
* When using write mode, values are initialized to defaults.
|
||||
*
|
||||
* Defaults:
|
||||
* - All hardware is supported
|
||||
* - Cloning is not allowed
|
||||
* - Room is not AG or dorm
|
||||
* - State is Moderation_Closed
|
||||
* - Accessibility is Unlisted
|
||||
* - CreatorPlayerId is 1 (Coach)
|
||||
* - Name and Description are empty strings
|
||||
*/
|
||||
async init(options: FactoryOptions) {
|
||||
if (typeof options.id == 'undefined' && typeof options.name == 'undefined')
|
||||
throw new Error("Must specify a room ID or a room name");
|
||||
@@ -63,11 +80,38 @@ export class RoomFactory {
|
||||
}
|
||||
|
||||
const obj = await this.#kv.getKv().get<DatabaseRoom>([RoomFactory.roomsKey, this.#roomId, 'meta']);
|
||||
if (obj.value == null) return null;
|
||||
else this.#obj = obj.value;
|
||||
if (options.mode == FactoryMode.Fetch && obj.value == null) return null;
|
||||
else this.#obj = options.mode == FactoryMode.Fetch ? obj.value : {
|
||||
Hardware: new Set(HardwareSupports),
|
||||
Tags: new Set(),
|
||||
CoOwners: new Set(),
|
||||
InvitedCoOwners: new Set(),
|
||||
Hosts: new Set(),
|
||||
InvitedHosts: new Set(),
|
||||
Room: {
|
||||
Name: "",
|
||||
Description: "",
|
||||
CreatorPlayerId: 1,
|
||||
ImageName: "",
|
||||
State: RoomState.Moderation_Closed,
|
||||
Accessibility: RoomAccessibility.Unlisted,
|
||||
SupportsLevelVoting: false,
|
||||
IsAGRoom: false,
|
||||
IsDormRoom: false,
|
||||
CloningAllowed: false,
|
||||
AllowsJuniors: true,
|
||||
RoomWarningMask: 0,
|
||||
CustomRoomWarning: "",
|
||||
DisableMicAutoMute: null
|
||||
}
|
||||
};
|
||||
|
||||
const subrooms = await this.#kv.getKv().get<Set<number>>([RoomFactory.roomsKey, this.#roomId, "subrooms"]);
|
||||
if (options.mode == FactoryMode.Write || subrooms.value == null) this.#subrooms = new Set();
|
||||
else this.#subrooms = subrooms.value;
|
||||
|
||||
const hardwareSupport = await this.#kv.getKv().get<Set<RoomDataTypes.HardwareSupport>>([RoomFactory.roomsKey, this.#roomId, 'hardware']);
|
||||
if (hardwareSupport.value == null) return null;
|
||||
if (hardwareSupport.value == null) this.#hardwareSupport = new Set(HardwareSupports);
|
||||
else this.#hardwareSupport = hardwareSupport.value;
|
||||
|
||||
const tags = await this.#kv.getKv().get<Set<string>>([RoomFactory.roomsKey, this.#roomId, 'tags']);
|
||||
@@ -102,7 +146,7 @@ export class RoomFactory {
|
||||
|
||||
const key = [RoomFactory.roomsKey, this.#roomId, 'meta'];
|
||||
const val = await this.#kv.getKv().get(key);
|
||||
if (val == null) await w();
|
||||
if (val.value == null) await w();
|
||||
else {
|
||||
if (this.writeMode == WriteMode.Overwrite) await w();
|
||||
else throw new Error("Room already exists");
|
||||
@@ -117,7 +161,7 @@ export class RoomFactory {
|
||||
const galvTags = this.getGalvanicTags();
|
||||
|
||||
const subroomExports = (await Promise.all(
|
||||
this.getSubrooms().map(subroom => this.getSubroom(subroom))
|
||||
this.getSubrooms().values().map(subroom => this.getSubroom(subroom))
|
||||
)).map(factory => factory.export());
|
||||
|
||||
return {
|
||||
@@ -154,14 +198,36 @@ export class RoomFactory {
|
||||
VisitCount: await this.getVisitCount()
|
||||
}
|
||||
}
|
||||
setRoomProperties(props: RoomDataTypes.DatabaseRoomContent) {
|
||||
Object.assign(this, props);
|
||||
}
|
||||
|
||||
getRoomId() {
|
||||
if (!this.#roomId) throw this.#cannotAccessBeforeInitError;
|
||||
return this.#roomId;
|
||||
}
|
||||
|
||||
getSubrooms() {
|
||||
if (!this.#obj) throw this.#cannotAccessBeforeInitError;
|
||||
return this.#obj.Subrooms;
|
||||
if (!this.#subrooms) throw this.#cannotAccessBeforeInitError;
|
||||
return this.#subrooms;
|
||||
}
|
||||
async getSubroom(id: number) {
|
||||
if (!this.#subrooms) throw this.#cannotAccessBeforeInitError;
|
||||
if (!this.#subrooms.has(id)) throw new Error("Subroom not available to this room");
|
||||
return await new SubroomFactory(this.#server, this.#kv).init({ mode: FactoryMode.Fetch, writeMode: WriteMode.WriteIfFree, id });
|
||||
}
|
||||
getAvailableSubroomId() {
|
||||
let id = Math.round(Math.random() * Math.pow(2, 31));
|
||||
if (this.getSubrooms().has(id)) id = this.getAvailableSubroomId();
|
||||
return id;
|
||||
}
|
||||
async newSubroom(mode?: WriteMode) {
|
||||
return await new SubroomFactory(this.#server, this.#kv).init({ mode: FactoryMode.Write, writeMode: mode ? mode : WriteMode.WriteIfFree, id: this.getAvailableSubroomId() });
|
||||
}
|
||||
addSubroom(id: number) {
|
||||
if (!this.#subrooms) throw this.#cannotAccessBeforeInitError;
|
||||
this.#subrooms.add(id);
|
||||
}
|
||||
|
||||
get Name() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Room.Name }
|
||||
set Name(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; this.#obj.Room.Name = data }
|
||||
@@ -178,8 +244,8 @@ export class RoomFactory {
|
||||
get State() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Room.State }
|
||||
set State(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; this.#obj.Room.State = data }
|
||||
|
||||
get RoomAccessibility() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Room.Accessibility }
|
||||
set RoomAccessibility(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; this.#obj.Room.Accessibility = data }
|
||||
get Accessibility() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Room.Accessibility }
|
||||
set Accessibility(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; this.#obj.Room.Accessibility = data }
|
||||
|
||||
get SupportsLevelVoting() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Room.SupportsLevelVoting }
|
||||
set SupportsLevelVoting(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; this.#obj.Room.SupportsLevelVoting = data }
|
||||
@@ -229,6 +295,20 @@ export class RoomFactory {
|
||||
this.#hardwareSupport.delete(hardware);
|
||||
await this.#saveHardwareSupport();
|
||||
}
|
||||
/**
|
||||
* Removes support for every hardware type in the room. When saving immediately after this, no client can legally join the room.
|
||||
*
|
||||
* In production, ensure at least one hardware type is supported.
|
||||
*/
|
||||
removeAllHardwareSupport() {
|
||||
this.#hardwareSupport = new Set();
|
||||
}
|
||||
/**
|
||||
* Adds support for every hardware type in the room.
|
||||
*/
|
||||
addAllHardwareSupport() {
|
||||
this.#hardwareSupport = new Set(HardwareSupports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits are fetched during every access, not during init
|
||||
@@ -252,8 +332,8 @@ export class RoomFactory {
|
||||
const tags: GalvanicTagDTO[] = [];
|
||||
|
||||
if (this.IsAGRoom) tags.push({ Tag: "recroomoriginal", Type: TagType.AGOnly });
|
||||
if (this.IsDormRoom) tags.push({ Tag: "dormroom", Type: TagType.Auto });
|
||||
if (this.Name === "Paintball" || this.Name === "PaintballVR") tags.push({ Tag: "paintball", Type: TagType.Auto });
|
||||
if (this.IsDormRoom) tags.push({ Tag: "dormroom", Type: TagType.AGOnly });
|
||||
if (this.Name === "Paintball" || this.Name === "PaintballVR") tags.push({ Tag: "paintball", Type: TagType.AGOnly });
|
||||
const hardwareSupport = this.getHardwareSupport();
|
||||
if (hardwareSupport.has('screens')) tags.push({ Tag: "screen", Type: TagType.Auto });
|
||||
if (hardwareSupport.has('walk_vr')) tags.push({ Tag: "walkvr", Type: TagType.Auto });
|
||||
|
||||
Reference in New Issue
Block a user