rooooms
This commit is contained in:
121
src/server/rooms/internal/SubroomFactory.ts
Normal file
121
src/server/rooms/internal/SubroomFactory.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import type KV from "../../persistence/kv.ts";
|
||||
import { type ServerBase } from "../../server.ts";
|
||||
import { DatabaseSubroom, FactoryMode, RoomDataTypes, RoomSave, WriteMode } from "./RoomDataTypes.ts";
|
||||
|
||||
export interface SubroomFactoryOptions {
|
||||
mode: FactoryMode,
|
||||
writeMode: WriteMode
|
||||
id: number
|
||||
}
|
||||
|
||||
export class SubroomFactory {
|
||||
|
||||
#server: ServerBase;
|
||||
#kv: KV;
|
||||
|
||||
#subroomId: number | null = null;
|
||||
|
||||
factoryMode: FactoryMode = FactoryMode.Fetch;
|
||||
writeMode: WriteMode = WriteMode.WriteIfFree;
|
||||
|
||||
#obj: DatabaseSubroom | null = null;
|
||||
#saves: RoomSave[] | null = null;
|
||||
|
||||
#cannotAccessBeforeInitError = new Error("Cannot access properties before initialization");
|
||||
#cannotWriteBeforeInitError = new Error("Cannot write before initialization");
|
||||
|
||||
constructor(server: ServerBase, kv: KV) {
|
||||
|
||||
this.#server = server;
|
||||
this.#kv = kv;
|
||||
|
||||
}
|
||||
|
||||
async init(options: SubroomFactoryOptions) {
|
||||
const data = await this.#kv.getKv().get<DatabaseSubroom>([options.id, 'meta']);
|
||||
if (data == null && this.factoryMode == FactoryMode.Fetch) throw new Error("No such subroom");
|
||||
|
||||
const saves = await this.#kv.getKv().get<RoomSave[]>([options.id, 'saves']);
|
||||
this.#saves = saves.value;
|
||||
|
||||
this.#obj = data.value;
|
||||
this.#subroomId = options.id;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
async write() {
|
||||
if (!this.#obj) throw this.#cannotWriteBeforeInitError;
|
||||
if (!this.#subroomId) throw new Error("No RoomSceneId set");
|
||||
|
||||
await this.#kv.getKv().set([this.#subroomId, 'meta'], this.#obj);
|
||||
await this.#kv.getKv().set([this.#subroomId, 'saves'], this.#saves);
|
||||
this.#server.emit('room.subroom.updated', { subroom: this });
|
||||
}
|
||||
|
||||
export(): RoomDataTypes.RoomScene {
|
||||
if (!this.#subroomId) throw this.#cannotAccessBeforeInitError;
|
||||
const save = this.getLatestSave();
|
||||
if (!save) throw new Error("No save to export");
|
||||
|
||||
return {
|
||||
RoomId: this.RoomId,
|
||||
RoomSceneId: this.#subroomId,
|
||||
RoomSceneLocationId: this.RoomSceneLocationId,
|
||||
Name: this.Name,
|
||||
IsSandbox: this.IsSandbox,
|
||||
MaxPlayers: this.MaxPlayers,
|
||||
CanMatchmakeInto: this.CanMatchmakeInto,
|
||||
DataModifiedAt: save.SavedAt,
|
||||
DataBlobName: save.DataBlobName
|
||||
}
|
||||
}
|
||||
|
||||
get RoomId() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.RoomId; }
|
||||
set RoomId(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.RoomId = data }
|
||||
|
||||
get RoomSceneId() { if (!this.#subroomId) throw this.#cannotAccessBeforeInitError; else return this.#subroomId; }
|
||||
|
||||
get RoomSceneLocationId() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.RoomSceneLocationId; }
|
||||
set RoomSceneLocationId(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.RoomSceneLocationId = data }
|
||||
|
||||
get Name() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.Name; }
|
||||
set Name(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.Name = data }
|
||||
|
||||
get IsSandbox() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.IsSandbox; }
|
||||
set IsSandbox(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.IsSandbox = data }
|
||||
|
||||
get MaxPlayers() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.MaxPlayers; }
|
||||
set MaxPlayers(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.MaxPlayers = data }
|
||||
|
||||
get CanMatchmakeInto() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.CanMatchmakeInto; }
|
||||
set CanMatchmakeInto(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.CanMatchmakeInto = data }
|
||||
|
||||
get LatestSaveId() { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else return this.#obj.LatestSaveId; }
|
||||
set LatestSaveId(data) { if (!this.#obj) throw this.#cannotAccessBeforeInitError; else this.#obj.LatestSaveId = data }
|
||||
|
||||
#getAvailableSaveId() {
|
||||
if (!this.#saves) throw this.#cannotAccessBeforeInitError;
|
||||
|
||||
let newId = Math.round(Math.random() * Math.pow(2, 31));
|
||||
while (this.#saves.some(save => save.SaveId == newId)) newId = this.#getAvailableSaveId();
|
||||
return newId;
|
||||
}
|
||||
addSave(dataBlobName: string) {
|
||||
if (!this.#saves) throw this.#cannotAccessBeforeInitError;
|
||||
this.#saves.push({
|
||||
SaveId: this.#getAvailableSaveId(),
|
||||
DataBlobName: dataBlobName,
|
||||
SavedAt: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
getSaves() {
|
||||
if (!this.#saves) throw this.#cannotAccessBeforeInitError;
|
||||
return this.#saves;
|
||||
}
|
||||
getLatestSave() {
|
||||
if (!this.#saves) throw this.#cannotAccessBeforeInitError;
|
||||
return this.#saves.find(save => save.SaveId == this.LatestSaveId);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user