duhhhhhhhh

This commit is contained in:
2025-09-11 13:47:30 -04:00
parent eef3667618
commit 317da3aaf7
53 changed files with 1395 additions and 212 deletions

View File

@@ -1,7 +1,121 @@
import Logging from "@proxnet/undead-logging";
import { ServerContentBase } from "../ContentBase.ts";
import { Instance } from "../instances/Instance.ts";
import { type RoomInstance } from "../instances/types.ts";
import type Profile from "../profiles/profile.ts";
import { RoomDataTypes } from "../rooms/internal/RoomDataTypes.ts";
import { type RoomFactory } from "../rooms/internal/RoomFactory.ts";
import { MatchmakingErrorCode } from "./types.ts";
const log = new Logging("Matchmaking");
export interface MatchmakingOptions {
roomName: string,
subRoomName?: string,
private?: boolean,
instanceId?: number,
profile: Profile
}
export interface InternalMatchmakingResponse {
errorCode: MatchmakingErrorCode,
roomInstance?: Instance
}
export interface MatchmakingResponse {
errorCode: MatchmakingErrorCode,
roomInstance?: RoomInstance
}
export class ServerMatchmakingBase extends ServerContentBase {
async matchmake(options: MatchmakingOptions): Promise<InternalMatchmakingResponse | null> {
function getInstanceName() {
if (options.roomName === 'DormRoom')
return `@${options.profile.getUsername()}'s Dorm`;
else {
if (options.subRoomName || options.subRoomName !== "Home") return `^${options.roomName}.${options.subRoomName}`;
else return `^${options.roomName}`;
}
}
if (options.instanceId) {
const instance = this.server.Instances.getInstance(options.instanceId);
if (instance) {
if (instance.hasPlayer(options.profile)) return { errorCode: MatchmakingErrorCode.AlreadyInTargetInstance }
else {
if (instance.isFull) return { errorCode: MatchmakingErrorCode.InsufficientSpace }
else if (instance.isPrivate) return { errorCode: MatchmakingErrorCode.RoomInstanceIsPrivate }
options.profile.updateInstance(instance);
await this.server.Instances.clearEmptyInstances();
return { errorCode: MatchmakingErrorCode.Success, roomInstance: instance };
}
} else return { errorCode: MatchmakingErrorCode.NoSuchGame };
} else {
let targetRoom: RoomFactory | null = null;
if (options.roomName == 'DormRoom') targetRoom = await this.server.Rooms.getPlayerDorm(options.profile);
else targetRoom = await this.server.Rooms.getByName(options.roomName);
if (!targetRoom) return { errorCode: MatchmakingErrorCode.NoSuchRoom };
if (targetRoom.Accessibility == RoomDataTypes.RoomAccessibility.Private && targetRoom.CreatorPlayerId !== options.profile.getId())
return { errorCode: MatchmakingErrorCode.RoomIsPrivate };
if (targetRoom.State !== RoomDataTypes.RoomState.Active) return { errorCode: MatchmakingErrorCode.RoomIsNotActive };
await this.server.Instances.clearEmptyInstances();
let allInstances = this.server.Instances.getAllInstances();
const subroom = (await targetRoom.getAllSubrooms()).values().find(factory => factory.Name == options.subRoomName);
// if a subroom was specified, filter instances that
if (subroom) allInstances = new Set(allInstances.values().filter(inst => inst.subRoomId == subroom.RoomSceneId));
// filter out instances that are in progress and do not support joininprogress
allInstances = new Set(allInstances.values().filter(inst => !(inst.isInProgress && !inst.supportsJoinInProgress)));
// sort instances
allInstances = new Set(allInstances.values().toArray().sort((a, b) => a.size + b.size));
const foundInstance = allInstances.values().toArray()[0];
if (!foundInstance) {
const matchmakeableSubrooms = (await targetRoom.getAllSubrooms()).values().filter(scene => scene.CanMatchmakeInto).toArray();
const index = Math.floor(Math.random() * matchmakeableSubrooms.length);
log.d(`Scene ${matchmakeableSubrooms[index].RoomSceneId} was chosen for matchmaking into new instance of room ${targetRoom.getRoomId()}`);
const newInst = this.server.Instances.createInstance({
room: targetRoom,
subroom: matchmakeableSubrooms[index],
private: options.private,
name: getInstanceName()
});
options.profile.updateInstance(newInst);
this.server.Instances.clearEmptyInstances();
return { errorCode: MatchmakingErrorCode.Success, roomInstance: newInst };
} else {
const currentInst = options.profile.getInstance();
if (currentInst?.instanceId === foundInstance.instanceId)
return { errorCode: MatchmakingErrorCode.AlreadyInBestInstance };
options.profile.updateInstance(foundInstance);
this.server.Instances.clearEmptyInstances();
return { errorCode: MatchmakingErrorCode.Success, roomInstance: foundInstance };
}
}
}
}

View File

@@ -1,4 +1,4 @@
enum MatchmakingErrorCode {
export enum MatchmakingErrorCode {
Success,
NoSuchGame,
PlayerNotOnline,