wer
This commit is contained in:
14
src/main.ts
14
src/main.ts
@@ -12,6 +12,7 @@ import { PushNotificationId } from "./server/socket/signalr/types.ts";
|
|||||||
import { genericResponse } from "./util/api.ts";
|
import { genericResponse } from "./util/api.ts";
|
||||||
import { getNetConfig } from "./net.ts";
|
import { getNetConfig } from "./net.ts";
|
||||||
import { TokenFormat, TokenType } from "./server/platforms/types.ts";
|
import { TokenFormat, TokenType } from "./server/platforms/types.ts";
|
||||||
|
import { Context } from "node:vm";
|
||||||
|
|
||||||
LoggingConfiguration.resetTimeFormat = TimeFormat.Unix;
|
LoggingConfiguration.resetTimeFormat = TimeFormat.Unix;
|
||||||
LoggingConfiguration.resetLogTiming = LogTiming.Microtask;
|
LoggingConfiguration.resetLogTiming = LogTiming.Microtask;
|
||||||
@@ -48,7 +49,7 @@ await routeImporter(AppRoot.app, 'src/', [
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// deno-lint-ignore require-await
|
// deno-lint-ignore require-await
|
||||||
AppRoot.app.use('*', async c => {
|
AppRoot.app.use('*', async (c: Context) => {
|
||||||
return c.json(genericResponse(false, "Resource Not Found"), 404);
|
return c.json(genericResponse(false, "Resource Not Found"), 404);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,7 +61,11 @@ const onListen = async () => {
|
|||||||
await Deno.mkdir('persist');
|
await Deno.mkdir('persist');
|
||||||
|
|
||||||
await Promise.all(Object.values(Server).map(base => ((base as ServerContentBase).kvInit ? (base as ServerContentBase).kvInit() : undefined)));
|
await Promise.all(Object.values(Server).map(base => ((base as ServerContentBase).kvInit ? (base as ServerContentBase).kvInit() : undefined)));
|
||||||
Server.emit('server.start', undefined);
|
if (typeof Server == 'undefined') {
|
||||||
|
log.e(`SERVER LOCKUP: Server is undefined!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Server.emit('server.start', { server: Server });
|
||||||
}
|
}
|
||||||
|
|
||||||
const netConfig = getNetConfig();
|
const netConfig = getNetConfig();
|
||||||
@@ -92,7 +97,7 @@ const server = Deno.serve({
|
|||||||
const splitHeader = authHeader.split(' ')[1];
|
const splitHeader = authHeader.split(' ')[1];
|
||||||
if (!splitHeader) return unauthRes;
|
if (!splitHeader) return unauthRes;
|
||||||
|
|
||||||
const secret = Deno.env.get('secret');
|
const secret = Deno.env.get('SECRET');
|
||||||
if (!secret) {
|
if (!secret) {
|
||||||
log.w(`No secret set!`);
|
log.w(`No secret set!`);
|
||||||
return unauthRes;
|
return unauthRes;
|
||||||
@@ -140,6 +145,7 @@ const server = Deno.serve({
|
|||||||
formatHeader(req.headers, 'Content-Type'),
|
formatHeader(req.headers, 'Content-Type'),
|
||||||
formatHeader(req.headers, 'Connection'),
|
formatHeader(req.headers, 'Connection'),
|
||||||
formatHeader(req.headers, 'User-Agent'),
|
formatHeader(req.headers, 'User-Agent'),
|
||||||
|
formatHeader(req.headers, 'Accept-Encoding')
|
||||||
]);
|
]);
|
||||||
if (!logBlacklist.includes(url.pathname)) {
|
if (!logBlacklist.includes(url.pathname)) {
|
||||||
if (res.status === 404) log.e(netlog);
|
if (res.status === 404) log.e(netlog);
|
||||||
@@ -163,7 +169,7 @@ Deno.addSignalListener('SIGINT', () => {
|
|||||||
for (const socket of consoleSockets) socket.destroy();
|
for (const socket of consoleSockets) socket.destroy();
|
||||||
for (const socket of gameSockets) socket.sendNotification(PushNotificationId.ModerationQuitGame);
|
for (const socket of gameSockets) socket.sendNotification(PushNotificationId.ModerationQuitGame);
|
||||||
|
|
||||||
Server.emit('server.destroy', undefined);
|
Server.emit('server.destroy', { server: Server });
|
||||||
});
|
});
|
||||||
|
|
||||||
Server.Commands.addRootCommand(new Command({
|
Server.Commands.addRootCommand(new Command({
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
export function getNetConfig() {
|
export function getNetConfig() {
|
||||||
return {
|
return {
|
||||||
host: "10.0.1.39",
|
host: "127.0.0.1",
|
||||||
port: 13370,
|
port: 13370,
|
||||||
publicHost: "10.0.1.39:13370",
|
publicHost: "127.0.0.1:13370",
|
||||||
securePublicHost: false
|
securePublicHost: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
import { createHonoRoute } from "../../../util/import.ts";
|
import { createHonoRoute } from "../../../util/import.ts";
|
||||||
|
|
||||||
export const route = createHonoRoute("/messages");
|
export const route = createHonoRoute("/messages");
|
||||||
|
|
||||||
|
route.app.get('/v2/get', c => {
|
||||||
|
return c.json([]);
|
||||||
|
});
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
|
import z from "zod";
|
||||||
import { createHonoRoute } from "../../../util/import.ts";
|
import { createHonoRoute } from "../../../util/import.ts";
|
||||||
|
import { authenticate } from "../../../util/api.ts";
|
||||||
|
import { typedZValidator } from "../../../util/validators.ts";
|
||||||
|
|
||||||
export const route = createHonoRoute("/players");
|
export const route = createHonoRoute("/players");
|
||||||
|
|
||||||
route.app.get('/v2/progression/bulk', c => {
|
route.app.get('/v2/progression/bulk', c => {
|
||||||
return c.json([]); // todo: progression
|
return c.json([]); // todo: progression
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getProgParamSchema = z.object({
|
||||||
|
id: z.coerce.number()
|
||||||
|
});
|
||||||
|
route.app.get('/v1/progression/:id', authenticate, typedZValidator('param', getProgParamSchema), async c => {
|
||||||
|
return c.json(await c.get('profile').Reputation.export());
|
||||||
|
});
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { authenticate, genericResponse } from "../../../util/api.ts";
|
import { authenticate, genericResponse } from "../../../util/api.ts";
|
||||||
import { createHonoRoute } from "../../../util/import.ts";
|
import { createHonoRoute } from "../../../util/import.ts";
|
||||||
import { transformStringToEnum, typedZValidator } from "../../../util/validators.ts";
|
import { typedZValidator } from "../../../util/validators.ts";
|
||||||
import { ProfileSetting } from "../../../server/profiles/content/Settings.ts";
|
|
||||||
import { HonoEnv } from "../../../util/types.ts";
|
import { HonoEnv } from "../../../util/types.ts";
|
||||||
import { Context } from "@hono/hono";
|
import { Context } from "@hono/hono";
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ route.app.get('/v2/', getSettingsMiddleware);
|
|||||||
route.app.get('/v2', getSettingsMiddleware);
|
route.app.get('/v2', getSettingsMiddleware);
|
||||||
|
|
||||||
const settingsSetSchema = z.object({
|
const settingsSetSchema = z.object({
|
||||||
Key: z.string().transform(transformStringToEnum<ProfileSetting>(ProfileSetting, true)),
|
Key: z.string(),
|
||||||
Value: z.string()
|
Value: z.string()
|
||||||
});
|
});
|
||||||
route.app.post('/v2/set', typedZValidator('json', settingsSetSchema), async c => {
|
route.app.post('/v2/set', typedZValidator('json', settingsSetSchema), async c => {
|
||||||
|
|||||||
@@ -9,8 +9,12 @@ export class ServerContentBase {
|
|||||||
this.server = server;
|
this.server = server;
|
||||||
this.kv = new KV(id, kv);
|
this.kv = new KV(id, kv);
|
||||||
|
|
||||||
server.on('server.start', this.start);
|
server.on('server.start', _ev => {
|
||||||
server.on('server.destroy', this.destroy);
|
this.start();
|
||||||
|
});
|
||||||
|
server.on('server.destroy', _ev => {
|
||||||
|
this.destroy();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async kvInit() {
|
async kvInit() {
|
||||||
|
|||||||
@@ -2,6 +2,14 @@ import { CloudRegionCode } from "../../util/photon.ts";
|
|||||||
import type Profile from "../profiles/profile.ts";
|
import type Profile from "../profiles/profile.ts";
|
||||||
import { RoomInstance, RoomLocation } from "./base.ts";
|
import { RoomInstance, RoomLocation } from "./base.ts";
|
||||||
|
|
||||||
|
export interface InstanceCreationOptions {
|
||||||
|
roomId: number,
|
||||||
|
subRoomId: number,
|
||||||
|
name: string,
|
||||||
|
maxCapacity: number,
|
||||||
|
private?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export class Instance {
|
export class Instance {
|
||||||
|
|
||||||
#createdAt = new Date();
|
#createdAt = new Date();
|
||||||
@@ -9,40 +17,42 @@ export class Instance {
|
|||||||
#players: Set<Profile> = new Set();
|
#players: Set<Profile> = new Set();
|
||||||
|
|
||||||
#instanceId: number;
|
#instanceId: number;
|
||||||
//#roomId: number;
|
#roomId: number;
|
||||||
//#subRoomId: number;
|
#subRoomId: number;
|
||||||
#location: RoomLocation;
|
#location: RoomLocation;
|
||||||
//#name: string;
|
#name: string;
|
||||||
//#maxCapacity: number;
|
#maxCapacity: number;
|
||||||
#isFull: boolean = false;
|
#isFull: boolean = false;
|
||||||
//#isPrivate: boolean;
|
#isPrivate: boolean;
|
||||||
#isInProgress: boolean = false;
|
#isInProgress: boolean = false;
|
||||||
#photonRegionId: string = CloudRegionCode.us;
|
#photonRegionId: string = CloudRegionCode.us;
|
||||||
//#photonRoomId: string;
|
#photonRoomId: string;
|
||||||
#dataBlob?: string;
|
#dataBlob?: string;
|
||||||
#eventId?: string
|
#eventId?: number
|
||||||
|
|
||||||
constructor(options: {
|
constructor(id: number, location: RoomLocation, options: InstanceCreationOptions) {
|
||||||
id: number,
|
this.#instanceId = id;
|
||||||
location: RoomLocation,
|
this.#location = location;
|
||||||
}
|
|
||||||
) {
|
this.#roomId = options.roomId;
|
||||||
this.#instanceId = options.id;
|
this.#subRoomId = options.subRoomId;
|
||||||
this.#location = options.location;
|
this.#isPrivate = typeof options.private == 'boolean' ? options.private : false;
|
||||||
|
this.#name = options.name;
|
||||||
|
this.#maxCapacity = options.maxCapacity;
|
||||||
|
this.#photonRoomId = `GCR-${this.#instanceId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlayers() {
|
getPlayers() {
|
||||||
return this.#players.values().toArray();
|
return this.#players.values().toArray();
|
||||||
}
|
}
|
||||||
playerIsHere(profile: Profile) {
|
playerIsHere(profile: Profile) {
|
||||||
return this.getPlayers().find(prof => prof.same(profile)) ? true : false;
|
return Boolean(this.getPlayers().find(prof => prof.same(profile)));
|
||||||
}
|
}
|
||||||
removePlayer(profile: Profile) {
|
removePlayer(profile: Profile) {
|
||||||
this.#players.delete(profile);
|
this.#players.delete(profile);
|
||||||
}
|
}
|
||||||
addPlayer(profile: Profile) {
|
addPlayer(profile: Profile) {
|
||||||
this.#players.add(profile);
|
this.#players.add(profile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreatedAt() {
|
getCreatedAt() {
|
||||||
@@ -50,10 +60,22 @@ export class Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export() {
|
export() {
|
||||||
/*const inst: RoomInstance = {
|
const inst: RoomInstance = {
|
||||||
roomInstanceId: this.#instanceId,
|
roomInstanceId: this.#instanceId,
|
||||||
|
roomId: this.#roomId,
|
||||||
}*/
|
subRoomId: this.#subRoomId,
|
||||||
|
location: this.#location,
|
||||||
|
name: this.#name,
|
||||||
|
maxCapacity: this.#maxCapacity,
|
||||||
|
isFull: this.#isFull,
|
||||||
|
isPrivate: this.#isPrivate,
|
||||||
|
isInProgress: this.#isInProgress,
|
||||||
|
photonRegionId: this.#photonRegionId,
|
||||||
|
photonRoomId: this.#photonRoomId,
|
||||||
|
dataBlob: this.#dataBlob,
|
||||||
|
eventId: this.#eventId
|
||||||
|
};
|
||||||
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
5
src/server/profiles/content/Progression.ts
Normal file
5
src/server/profiles/content/Progression.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import ProfileContentManager from "./base.ts";
|
||||||
|
|
||||||
|
export class ProfileProgressionManager extends ProfileContentManager {
|
||||||
|
|
||||||
|
} // do this soon:tm:
|
||||||
@@ -1,5 +1,33 @@
|
|||||||
import ProfileContentManager from "./base.ts";
|
import ProfileContentManager from "./base.ts";
|
||||||
|
|
||||||
|
interface ProfileReputation {
|
||||||
|
AccountId: number,
|
||||||
|
Noteriety: number,
|
||||||
|
CheerGeneral: number,
|
||||||
|
CheerHelpful: number,
|
||||||
|
CheerGreatHost: number,
|
||||||
|
CheerSportsman: number,
|
||||||
|
CheerCreative: number,
|
||||||
|
CheerCredit: number,
|
||||||
|
SubscriberCount: number,
|
||||||
|
SubscribedCount: number,
|
||||||
|
}
|
||||||
|
|
||||||
export class ProfileReputationManager extends ProfileContentManager {
|
export class ProfileReputationManager extends ProfileContentManager {
|
||||||
|
|
||||||
|
async export(): Promise<ProfileReputation> {
|
||||||
|
return {
|
||||||
|
AccountId: this.profile.getId(),
|
||||||
|
Noteriety: 0.0,
|
||||||
|
CheerGeneral: 0.0,
|
||||||
|
CheerHelpful: 0.0,
|
||||||
|
CheerGreatHost: 0.0,
|
||||||
|
CheerSportsman: 0.0,
|
||||||
|
CheerCreative: 0.0,
|
||||||
|
CheerCredit: 0.0,
|
||||||
|
SubscribedCount: 0,
|
||||||
|
SubscriberCount: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ export class ProfileSettingsManager extends ProfileContentManager {
|
|||||||
await this.kv.getKv().set(this.#key, settings);
|
await this.kv.getKv().set(this.#key, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSetting(Key: ProfileSetting, Value: string) {
|
async setSetting(Key: string, Value: string) {
|
||||||
const settings = await this.getAllSettings();
|
const settings = await this.getAllSettings();
|
||||||
const s = settings.find(setting => setting.Key === Key);
|
const s = settings.find(setting => setting.Key === Key);
|
||||||
if (!s) settings.push({ Key, Value });
|
if (!s) settings.push({ Key, Value });
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class ProfileManagerBase extends ServerContentBase {
|
|||||||
exec: async (id: number) => {
|
exec: async (id: number) => {
|
||||||
const prof = await this.get(id);
|
const prof = await this.get(id);
|
||||||
if (!prof) return prof;
|
if (!prof) return prof;
|
||||||
else return await prof.export();
|
else return prof.export();
|
||||||
},
|
},
|
||||||
zod: z.tuple([
|
zod: z.tuple([
|
||||||
z.string().transform(Number)
|
z.string().transform(Number)
|
||||||
|
|||||||
26
src/server/rooms/base.ts
Normal file
26
src/server/rooms/base.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { ServerContentBase } from "../ContentBase.ts";
|
||||||
|
|
||||||
|
export class ServerRoomsBase extends ServerContentBase {
|
||||||
|
|
||||||
|
#roomsKey = "rooms";
|
||||||
|
#roomNamesKey = "room_names"
|
||||||
|
|
||||||
|
getKv() {
|
||||||
|
return this.kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getIdFromName(name: string) {
|
||||||
|
const id = await this.kv.getKv().get<number>([this.#roomsKey, name]);
|
||||||
|
if (id.value == null) return null;
|
||||||
|
return id.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFromName(name: string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(id: number) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
178
src/server/rooms/internal/DataTypes.ts
Normal file
178
src/server/rooms/internal/DataTypes.ts
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
import { RoomLocation } from "../../instances/base.ts";
|
||||||
|
import { RoomFactory } from "./RoomFactory.ts";
|
||||||
|
import { SubroomFactory } from "./SubroomFactory.ts";
|
||||||
|
|
||||||
|
export enum WriteMode {
|
||||||
|
Overwrite = "overwrite",
|
||||||
|
WriteIfFree = "if_free"
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FactoryMode {
|
||||||
|
Fetch = 'fetch',
|
||||||
|
Write = 'write'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HardwareSupport = "screens" | "walk_vr" | "teleport_vr" | "low_vr" | "mobile";
|
||||||
|
export const HardwareSupportStrings = ["screens", "walk_vr", "teleport_vr", "low_vr", "mobile"];
|
||||||
|
|
||||||
|
export enum RoomState {
|
||||||
|
Active,
|
||||||
|
PendingJunior = 11,
|
||||||
|
Moderation_PendingReview = 100,
|
||||||
|
Moderation_Closed,
|
||||||
|
MarkedForDelete = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RoomAccessibility {
|
||||||
|
Private,
|
||||||
|
Public,
|
||||||
|
Unlisted
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuiltinScene {
|
||||||
|
Name: string,
|
||||||
|
RoomSceneLocationId: RoomLocation,
|
||||||
|
IsSandbox: boolean,
|
||||||
|
CanMatchmakeInto: boolean,
|
||||||
|
SupportsJoinInProgress: boolean,
|
||||||
|
UseLevelBasedMatchmaking: boolean,
|
||||||
|
UseAgeBasedMatchmaking: boolean,
|
||||||
|
UseRecRoyaleMatchmaking: boolean,
|
||||||
|
MaxPlayers: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuiltinRoom {
|
||||||
|
Name: string,
|
||||||
|
Description: string,
|
||||||
|
Accessibility: RoomAccessibility,
|
||||||
|
SupportsLevelVoting: boolean,
|
||||||
|
CloningAllowed: boolean,
|
||||||
|
SupportsScreens: boolean,
|
||||||
|
SupportsWalkVR: boolean,
|
||||||
|
SupportsTeleportVR: boolean,
|
||||||
|
Scenes: BuiltinScene[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoomScene {
|
||||||
|
RoomSceneId: number,
|
||||||
|
RoomId: number,
|
||||||
|
RoomSceneLocationId: string,
|
||||||
|
Name: string,
|
||||||
|
IsSandbox: boolean,
|
||||||
|
DataBlobName: string,
|
||||||
|
MaxPlayers: number,
|
||||||
|
CanMatchmakeInto?: boolean,
|
||||||
|
DataModifiedAt: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Room {
|
||||||
|
RoomId: number,
|
||||||
|
Name: string,
|
||||||
|
Description: string,
|
||||||
|
CreatorPlayerId: number,
|
||||||
|
ImageName: string,
|
||||||
|
State: RoomState,
|
||||||
|
Accessibility: RoomAccessibility,
|
||||||
|
SupportsLevelVoting: boolean,
|
||||||
|
IsAGRoom: boolean,
|
||||||
|
IsDormRoom?: boolean,
|
||||||
|
CloningAllowed: boolean,
|
||||||
|
SupportsScreens: boolean,
|
||||||
|
SupportsWalkVR: boolean,
|
||||||
|
SupportsTeleportVR: boolean,
|
||||||
|
AllowsJuniors: boolean,
|
||||||
|
RoomWarningMask: number,
|
||||||
|
CustomRoomWarning: string,
|
||||||
|
DisableMicAutoMute?: boolean | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RoomWarningMask {
|
||||||
|
None,
|
||||||
|
Scary,
|
||||||
|
Mature = 2,
|
||||||
|
FlashingLights = 4,
|
||||||
|
IntenseMotion = 8,
|
||||||
|
Violence = 16,
|
||||||
|
Custom = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TagType {
|
||||||
|
General,
|
||||||
|
Auto,
|
||||||
|
AGOnly,
|
||||||
|
Banned
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TagDTO {
|
||||||
|
Tag: string,
|
||||||
|
Type: TagType
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoomDetails {
|
||||||
|
Room: Room,
|
||||||
|
Scenes: RoomScene[],
|
||||||
|
CoOwners: number[],
|
||||||
|
InvitedCoOwners: number[],
|
||||||
|
Moderators?: number[],
|
||||||
|
InvitedModerators?: number[],
|
||||||
|
Hosts: number[],
|
||||||
|
InvitedHosts: number[],
|
||||||
|
CheerCount: number,
|
||||||
|
FavoriteCount: number,
|
||||||
|
VisitCount: number,
|
||||||
|
Tags: TagDTO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CreateModifyRoomStatus {
|
||||||
|
Success,
|
||||||
|
Unknown,
|
||||||
|
PermissionDenied,
|
||||||
|
RoomNotActive,
|
||||||
|
RoomDoesNotExist,
|
||||||
|
RoomHasNoDataBlob,
|
||||||
|
DuplicateName = 10,
|
||||||
|
ReservedName,
|
||||||
|
InappropriateName,
|
||||||
|
InappropriateDescription,
|
||||||
|
TooManyRooms = 20,
|
||||||
|
InvalidMaxPlayers = 30,
|
||||||
|
DataHistoryDoesNotExist = 40,
|
||||||
|
DataHistoryAlreadyActive,
|
||||||
|
InvalidTags = 50,
|
||||||
|
NoStartingRoomScene = 55,
|
||||||
|
RoomUnderModerationReview = 100,
|
||||||
|
PlayerHasRoomUnderModerationReview,
|
||||||
|
AccessibilityUnderModerationLock,
|
||||||
|
JuniorStatusFail = 200,
|
||||||
|
InappropriateCustomWarning = 300,
|
||||||
|
PartialBanSuccessBanPower = 400,
|
||||||
|
TargetHasBanPower,
|
||||||
|
PlayerIsRoomBanned = 410
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DatabaseRoom {
|
||||||
|
Visits: number,
|
||||||
|
Hardware: Set<HardwareSupport>,
|
||||||
|
Subrooms: number[],
|
||||||
|
Tags: Set<string>,
|
||||||
|
CoOwners: Set<number>,
|
||||||
|
InvitedCoOwners: Set<number>,
|
||||||
|
Hosts: Set<number>,
|
||||||
|
InvitedHosts: Set<number>,
|
||||||
|
Favorites: Set<number>,
|
||||||
|
Cheers: Set<number>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DatabaseSubroom {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoomUpdatedEvent {
|
||||||
|
room: RoomFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubroomUpdatedEvent {
|
||||||
|
subroom: SubroomFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
export * as RoomDataTypes from "./DataTypes.ts";
|
||||||
53
src/server/rooms/internal/RoomFactory.ts
Normal file
53
src/server/rooms/internal/RoomFactory.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import type KV from "../../persistence/kv.ts";
|
||||||
|
import { type ServerBase } from "../../server.ts";
|
||||||
|
import { DatabaseRoom, RoomDataTypes } from "./DataTypes.ts";
|
||||||
|
|
||||||
|
export interface RoomFactoryOptions {
|
||||||
|
id?: number,
|
||||||
|
name?: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RoomFactory {
|
||||||
|
|
||||||
|
#server: ServerBase;
|
||||||
|
#kv: KV;
|
||||||
|
|
||||||
|
#roomId: number | undefined;
|
||||||
|
#name: string | undefined;
|
||||||
|
#description: string | undefined;
|
||||||
|
#creatorPlayerId: number | undefined;
|
||||||
|
#imageName: string | undefined;
|
||||||
|
#state: RoomDataTypes.RoomScene | undefined;
|
||||||
|
#accessibility: RoomDataTypes.RoomAccessibility | undefined;
|
||||||
|
#supportsLevelVoting: boolean | undefined;
|
||||||
|
#isAGRoom: boolean | undefined;
|
||||||
|
#isDormRoom: boolean | undefined;
|
||||||
|
#cloningAllowed: boolean | undefined;
|
||||||
|
#supportsScreens: boolean | undefined;
|
||||||
|
#supportsWalkVR: boolean | undefined;
|
||||||
|
#supportsTeleportVR: boolean | undefined;
|
||||||
|
#allowsJuniors: boolean | undefined;
|
||||||
|
#roomWarningMask: number | undefined;
|
||||||
|
#customRoomWarning: string | undefined;
|
||||||
|
#disableMicAutoMute: boolean | undefined;
|
||||||
|
|
||||||
|
#dbMeta: DatabaseRoom | null = null;
|
||||||
|
|
||||||
|
#visits: number | undefined;
|
||||||
|
#hardware
|
||||||
|
|
||||||
|
constructor(server: ServerBase, kv: KV) {
|
||||||
|
|
||||||
|
this.#server = server;
|
||||||
|
this.#kv = kv;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(options: RoomFactoryOptions) {
|
||||||
|
if (typeof options.id == 'undefined' && typeof options.name == 'undefined')
|
||||||
|
throw new Error("Must specify a room ID or a room name");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ServerUpdateEvent } from "../serverevents.ts";
|
||||||
import { AvatarContentBase } from "./avatars/base.ts";
|
import { AvatarContentBase } from "./avatars/base.ts";
|
||||||
import { EventManager } from "./baseevent.ts";
|
import { EventManager } from "./baseevent.ts";
|
||||||
import { CommandsBase } from "./commands/commands.ts";
|
import { CommandsBase } from "./commands/commands.ts";
|
||||||
@@ -9,13 +10,17 @@ import { type PresenceUpdateEvent } from "./presence/events/PresenceUpdateEvent.
|
|||||||
import { type ProfileUpdateEvent } from "./profiles/events/ProfileUpdate.ts";
|
import { type ProfileUpdateEvent } from "./profiles/events/ProfileUpdate.ts";
|
||||||
import { type RoleUpdateEvent } from "./profiles/events/RoleUpdate.ts";
|
import { type RoleUpdateEvent } from "./profiles/events/RoleUpdate.ts";
|
||||||
import ProfileManagerBase from "./profiles/manager.ts";
|
import ProfileManagerBase from "./profiles/manager.ts";
|
||||||
|
import { ServerRoomsBase } from "./rooms/base.ts";
|
||||||
|
import { RoomUpdatedEvent, SubroomUpdatedEvent } from "./rooms/internal/DataTypes.ts";
|
||||||
|
|
||||||
interface ServerEvents {
|
interface ServerEvents {
|
||||||
'profile.roleupdate': RoleUpdateEvent,
|
'profile.roleupdate': RoleUpdateEvent,
|
||||||
'profile.update': ProfileUpdateEvent,
|
'profile.update': ProfileUpdateEvent,
|
||||||
'presence.update': PresenceUpdateEvent,
|
'presence.update': PresenceUpdateEvent,
|
||||||
'server.start': undefined,
|
'server.start': ServerUpdateEvent,
|
||||||
'server.destroy': undefined,
|
'server.destroy': ServerUpdateEvent,
|
||||||
|
'room.updated': RoomUpdatedEvent,
|
||||||
|
'room.subroom.updated': SubroomUpdatedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerBase extends EventManager<ServerEvents> {
|
class ServerBase extends EventManager<ServerEvents> {
|
||||||
@@ -26,6 +31,7 @@ class ServerBase extends EventManager<ServerEvents> {
|
|||||||
Avatars = new AvatarContentBase(this, 'avatars');
|
Avatars = new AvatarContentBase(this, 'avatars');
|
||||||
Instances = new InstanceManager(this, 'instances');
|
Instances = new InstanceManager(this, 'instances');
|
||||||
Content = new ServerContentManager(this, "content");
|
Content = new ServerContentManager(this, "content");
|
||||||
|
Rooms = new ServerRoomsBase(this, 'rooms', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Server = new ServerBase();
|
const Server = new ServerBase();
|
||||||
|
|||||||
5
src/serverevents.ts
Normal file
5
src/serverevents.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { ServerBase } from "./server/server.ts";
|
||||||
|
|
||||||
|
export interface ServerUpdateEvent {
|
||||||
|
server: ServerBase
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user