Rooms and matchmaking debugging
* Dorm is not properly cloned (fix this) * Basic matchmaking implementation * Goto route * Goto DormRoom
This commit is contained in:
@@ -15,11 +15,14 @@ GNU Affero General Public License for more details.
|
|||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import { it } from "node:test";
|
|
||||||
import { Redis } from "../../db.ts";
|
import { Redis } from "../../db.ts";
|
||||||
import { RootPath } from "./baseimages.ts";
|
import { RootPath } from "./baseimages.ts";
|
||||||
import { BuiltinRoom, RoomState } from "./roomtypes.ts";
|
import { BuiltinRoom, RoomDetails, RoomState } from "./roomtypes.ts";
|
||||||
import { RoomFetch } from "./room.ts";
|
import { RoomFetch } from "./room.ts";
|
||||||
|
import { Profile } from "../profiles.ts";
|
||||||
|
import Logging from "@proxnet/undead-logging";
|
||||||
|
|
||||||
|
const log = new Logging("Rooms");
|
||||||
|
|
||||||
const rooms = JSON.parse(Deno.readTextFileSync(`${RootPath}/res/rooms.json`)) as BuiltinRoom[];
|
const rooms = JSON.parse(Deno.readTextFileSync(`${RootPath}/res/rooms.json`)) as BuiltinRoom[];
|
||||||
|
|
||||||
@@ -119,42 +122,36 @@ class RoomsBase {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateBuiltinRooms() {
|
async #setRoom(details: RoomDetails) {
|
||||||
|
const rootKey = Redis.buildKey(Redis.KeyGroups.Rooms.Root, details.Room.RoomId.toString());
|
||||||
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
|
||||||
for (const builtinRoom of rooms) {
|
|
||||||
const newId = await this.#getAvailableRoomId();
|
|
||||||
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
|
||||||
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Room_Names, builtinRoom.Name), newId);
|
|
||||||
const rootKey = Redis.buildKey(Redis.KeyGroups.Rooms.Root, newId.toString());
|
|
||||||
|
|
||||||
const roomMetaRootKey = Redis.buildKey(rootKey, this.roomRootKeys.Meta);
|
const roomMetaRootKey = Redis.buildKey(rootKey, this.roomRootKeys.Meta);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomId, newId),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomId, details.Room.RoomId),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Name, builtinRoom.Name),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Name, details.Room.Name),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Description, builtinRoom.Description),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Description, details.Room.Description),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CreatorPlayerId, `1`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CreatorPlayerId, details.Room.CreatorPlayerId),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.ImageName, `${builtinRoom.Name}.png`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.ImageName, `DefaultProfileImage.png`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.State, `${RoomState.Active}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.State, details.Room.State),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Accessibility, `${builtinRoom.Accessibility}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.Accessibility, details.Room.Accessibility),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsLevelVoting, `${builtinRoom.SupportsLevelVoting}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsLevelVoting, `${details.Room.SupportsLevelVoting}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsAGRoom, "true"),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsAGRoom, `${details.Room.IsAGRoom}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsDormRoom, "false"),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.IsDormRoom, `${details.Room.IsDormRoom}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CloningAllowed, `${builtinRoom.CloningAllowed}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CloningAllowed, `${details.Room.CloningAllowed}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsScreens, `${builtinRoom.SupportsScreens}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsScreens, `${details.Room.SupportsScreens}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsWalkVR, `${builtinRoom.SupportsWalkVR}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsWalkVR, `${details.Room.SupportsWalkVR}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsTeleportVR, `${builtinRoom.SupportsTeleportVR}`),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.SupportsTeleportVR, `${details.Room.SupportsTeleportVR}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.AllowsJuniors, "true"),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.AllowsJuniors, `${details.Room.AllowsJuniors}`),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomWarningMask, 0),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.RoomWarningMask, details.Room.RoomWarningMask),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CustomRoomWarning, ""),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.CustomRoomWarning, details.Room.CustomRoomWarning),
|
||||||
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.DisableMicAutoMute, "false"),
|
Redis.Database.hset(roomMetaRootKey, this.roomMetaKeys.DisableMicAutoMute, `${details.Room.DisableMicAutoMute}`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const subroom of builtinRoom.Scenes) {
|
for (const subroom of details.Scenes) {
|
||||||
const newSubId = await this.#getAvailableSubRoomId(newId);
|
const newSubId = await this.#getAvailableSubRoomId(details.Room.RoomId);
|
||||||
const subRootMetaKey = Redis.buildKey(
|
const subRootMetaKey = Redis.buildKey(
|
||||||
Redis.KeyGroups.Rooms.Root,
|
Redis.KeyGroups.Rooms.Root,
|
||||||
newId.toString(),
|
details.Room.RoomId.toString(),
|
||||||
this.roomRootKeys.Subrooms,
|
this.roomRootKeys.Subrooms,
|
||||||
newSubId.toString(),
|
newSubId.toString(),
|
||||||
this.subroomRootKeys.Meta
|
this.subroomRootKeys.Meta
|
||||||
@@ -164,14 +161,128 @@ class RoomsBase {
|
|||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.RoomSceneLocationId, subroom.RoomSceneLocationId),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.RoomSceneLocationId, subroom.RoomSceneLocationId),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.Name, subroom.RoomSceneLocationId),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.Name, subroom.RoomSceneLocationId),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.IsSandbox, `${subroom.IsSandbox}`),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.IsSandbox, `${subroom.IsSandbox}`),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataBlobName, ""),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataBlobName, subroom.DataBlobName),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.MaxPlayers, subroom.MaxPlayers),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.MaxPlayers, subroom.MaxPlayers),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.CanMatchmakeInto, `${subroom.CanMatchmakeInto}`),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.CanMatchmakeInto, `${subroom.CanMatchmakeInto}`),
|
||||||
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataModifiedAt, new Date().toISOString()),
|
Redis.Database.hset(subRootMetaKey, this.subroomMetaKeys.DataModifiedAt, new Date().toISOString()),
|
||||||
]);
|
]);
|
||||||
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, newId.toString(), this.roomRootKeys.Subrooms), newSubId);
|
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, details.Room.RoomId.toString(), this.roomRootKeys.Subrooms), newSubId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async cloneRoom(roomid: number, newname: string, newowner: Profile, dorm?: boolean) {
|
||||||
|
const canBeClonedRaw = await Redis.Database.hget(Redis.buildKey(
|
||||||
|
Redis.KeyGroups.Rooms.Root,
|
||||||
|
roomid.toString(),
|
||||||
|
Rooms.roomRootKeys.Meta
|
||||||
|
), Rooms.roomMetaKeys.CloningAllowed);
|
||||||
|
if (!canBeClonedRaw) return null;
|
||||||
|
let canBeCloned = null;
|
||||||
|
try {
|
||||||
|
canBeCloned = JSON.parse(canBeClonedRaw) as boolean;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!canBeCloned) return null;
|
||||||
|
const beforeRoom = await Rooms.get(roomid); // room must exist
|
||||||
|
if (!beforeRoom || !beforeRoom.Room.CloningAllowed) return null; // room must be cloneable
|
||||||
|
if (await Rooms.getByName(newname)) return null; // room name cannot be taken
|
||||||
|
|
||||||
|
const newId = await this.#getAvailableRoomId();
|
||||||
|
beforeRoom.Room.CreatorPlayerId = newowner.getId();
|
||||||
|
beforeRoom.Room.RoomId = newId;
|
||||||
|
for (const subroom of beforeRoom.Scenes) subroom.RoomId = newId;
|
||||||
|
if (dorm) {
|
||||||
|
beforeRoom.Room.IsAGRoom = true;
|
||||||
|
beforeRoom.Room.IsDormRoom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Room_Names, newname), newId);
|
||||||
|
await Rooms.#setRoom(beforeRoom);
|
||||||
|
return beforeRoom;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProfileDormDefault(player: Profile) {
|
||||||
|
const unparsedId = await Redis.Database.hget(Redis.buildKey(
|
||||||
|
Redis.KeyGroups.Rooms.Root,
|
||||||
|
Redis.KeyGroups.Rooms.PlayerDorms
|
||||||
|
), player.getId().toString());
|
||||||
|
if (unparsedId) {
|
||||||
|
const parsedId = parseInt(unparsedId);
|
||||||
|
if (!isNaN(parsedId)) return await Rooms.get(parsedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseDorm = await Rooms.getByName("DormRoom");
|
||||||
|
|
||||||
|
log.d('got base dorm');
|
||||||
|
if (!baseDorm) return null;
|
||||||
|
log.d('base dorm is not null');
|
||||||
|
const newDorm = await this.cloneRoom(baseDorm.Room.RoomId, "DormRoom", player, true);
|
||||||
|
await Redis.Database.hset(Redis.buildKey(
|
||||||
|
Redis.KeyGroups.Rooms.Root,
|
||||||
|
Redis.KeyGroups.Rooms.PlayerDorms
|
||||||
|
), player.getId().toString(), baseDorm.Room.RoomId);
|
||||||
|
log.d('got new dorm');
|
||||||
|
if (!newDorm) return null;
|
||||||
|
log.d('new dorm is not null');
|
||||||
|
return newDorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateBuiltinRooms() {
|
||||||
|
|
||||||
|
if ((await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated))) !== null) return true;
|
||||||
|
for (const builtinRoom of rooms) {
|
||||||
|
const newId = await this.#getAvailableRoomId();
|
||||||
|
await Redis.Database.sadd(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.AGRooms), newId);
|
||||||
|
const roomDets: RoomDetails = {
|
||||||
|
Room: {
|
||||||
|
Name: builtinRoom.Name,
|
||||||
|
RoomId: newId,
|
||||||
|
Description: builtinRoom.Description,
|
||||||
|
CreatorPlayerId: 1,
|
||||||
|
ImageName: `${builtinRoom.Name}.png`,
|
||||||
|
State: RoomState.Active,
|
||||||
|
Accessibility: builtinRoom.Accessibility,
|
||||||
|
SupportsLevelVoting: builtinRoom.SupportsLevelVoting,
|
||||||
|
IsAGRoom: true,
|
||||||
|
IsDormRoom: builtinRoom.Name == 'DormRoom',
|
||||||
|
CloningAllowed: builtinRoom.CloningAllowed,
|
||||||
|
SupportsScreens: builtinRoom.SupportsScreens,
|
||||||
|
SupportsWalkVR: builtinRoom.SupportsWalkVR,
|
||||||
|
SupportsTeleportVR: builtinRoom.SupportsTeleportVR,
|
||||||
|
AllowsJuniors: true,
|
||||||
|
RoomWarningMask: 0,
|
||||||
|
CustomRoomWarning: ""
|
||||||
|
},
|
||||||
|
Scenes: [],
|
||||||
|
CoOwners: [],
|
||||||
|
InvitedCoOwners: [],
|
||||||
|
Hosts: [],
|
||||||
|
InvitedHosts: [],
|
||||||
|
CheerCount: 0,
|
||||||
|
FavoriteCount: 0,
|
||||||
|
VisitCount: 0,
|
||||||
|
Tags: []
|
||||||
|
}
|
||||||
|
for (const subroom of builtinRoom.Scenes) {
|
||||||
|
const newSubroomId = await this.#getAvailableSubRoomId(newId);
|
||||||
|
roomDets.Scenes.push({
|
||||||
|
RoomSceneId: newSubroomId,
|
||||||
|
RoomId: newId,
|
||||||
|
RoomSceneLocationId: subroom.RoomSceneLocationId,
|
||||||
|
Name: subroom.Name,
|
||||||
|
IsSandbox: subroom.IsSandbox,
|
||||||
|
DataBlobName: "",
|
||||||
|
MaxPlayers: subroom.MaxPlayers,
|
||||||
|
CanMatchmakeInto: subroom.CanMatchmakeInto ? subroom.CanMatchmakeInto : true,
|
||||||
|
DataModifiedAt: new Date().toISOString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await this.#setRoom(roomDets);
|
||||||
|
}
|
||||||
Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated), "1");
|
Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Rooms.Root, this.miscKeys.BuiltinGenerated), "1");
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,18 @@ export interface BuiltinRoom {
|
|||||||
Scenes: BuiltinScene[]
|
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 {
|
export interface Room {
|
||||||
RoomId: number,
|
RoomId: number,
|
||||||
Name: string,
|
Name: string,
|
||||||
@@ -144,18 +156,6 @@ export interface TagDTO {
|
|||||||
Type: TagType
|
Type: TagType
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RoomScene {
|
|
||||||
RoomSceneId: number,
|
|
||||||
RoomId: number,
|
|
||||||
RoomSceneLocationId: string,
|
|
||||||
Name: string,
|
|
||||||
IsSandbox: boolean,
|
|
||||||
DataBlobName: string,
|
|
||||||
MaxPlayers: number,
|
|
||||||
CanMatchmakeInto?: boolean,
|
|
||||||
DataModifiedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RoomDetails {
|
export interface RoomDetails {
|
||||||
Room: Room,
|
Room: Room,
|
||||||
Scenes: RoomScene[],
|
Scenes: RoomScene[],
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ GNU Affero General Public License for more details.
|
|||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
import Rooms from "../content/rooms.ts";
|
||||||
|
import { RoomAccessibility, RoomState } from "../content/roomtypes.ts";
|
||||||
import { Profile } from "../profiles.ts";
|
import { Profile } from "../profiles.ts";
|
||||||
import Instances from "./instances.ts";
|
import Instances from "./instances.ts";
|
||||||
import { MatchmakingErrorCode, RoomInstance } from "./types.ts";
|
import { MatchmakingErrorCode, RoomInstance } from "./types.ts";
|
||||||
@@ -25,7 +27,7 @@ interface MatchmakingOptions {
|
|||||||
roomName: string,
|
roomName: string,
|
||||||
subRoomName?: string,
|
subRoomName?: string,
|
||||||
private?: boolean,
|
private?: boolean,
|
||||||
instanceId?: string,
|
instanceId?: number,
|
||||||
profile: Profile
|
profile: Profile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,30 +53,55 @@ class MatchmakingBase {
|
|||||||
loginLocks.delete(prof.getId());
|
loginLocks.delete(prof.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
matchmake(options: MatchmakingOptions) {
|
async matchmake(options: MatchmakingOptions) {
|
||||||
|
|
||||||
if (options.instanceId) {
|
if (options.instanceId) {
|
||||||
|
|
||||||
// get instance
|
const instance = Instances.getInstance(options.instanceId);
|
||||||
// if instance exists, check private
|
if (instance) {
|
||||||
|
|
||||||
|
if (Instances.playerIsInInstance(options.profile, instance)) return { errorCode: MatchmakingErrorCode.AlreadyInTargetInstance };
|
||||||
|
else {
|
||||||
|
if (instance.isFull) return { errorCode: MatchmakingErrorCode.InsufficientSpace }
|
||||||
|
else if (instance.isPrivate) return { errorCode: MatchmakingErrorCode.RoomInstanceIsPrivate };
|
||||||
|
|
||||||
|
Instances.setPlayerInstance(options.profile, instance);
|
||||||
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: instance };
|
||||||
|
}
|
||||||
|
|
||||||
|
} else return { errorCode: MatchmakingErrorCode.NoSuchGame }
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const targetRoom = options.roomName !== 'DormRoom' ? await Rooms.getByName(options.roomName) : await Rooms.getProfileDormDefault(options.profile);
|
||||||
|
if (!targetRoom) return { errorCode: MatchmakingErrorCode.NoSuchRoom };
|
||||||
|
if (targetRoom.Room.Accessibility == RoomAccessibility.Private) return { errorCode: MatchmakingErrorCode.RoomIsPrivate };
|
||||||
|
if (targetRoom.Room.State !== RoomState.Active) return { errorCode: MatchmakingErrorCode.RoomIsNotActive };
|
||||||
|
const roomId = targetRoom.Room.RoomId;
|
||||||
|
|
||||||
|
let allInstances = Instances.getAllRoomInstances(roomId).values().toArray().filter(instance => !instance.isPrivate && !instance.isFull);
|
||||||
|
const subroomId = targetRoom.Scenes.find(scene => scene.Name == options.subRoomName)?.RoomSceneId;
|
||||||
|
if (subroomId) allInstances = allInstances.filter(instance => instance.subRoomId == subroomId);
|
||||||
|
|
||||||
|
const foundInstance = allInstances[Math.floor(Math.random() * allInstances.length)];
|
||||||
|
if (!foundInstance) {
|
||||||
|
|
||||||
|
const matchmakeableSubrooms = targetRoom.Scenes.filter(scene => scene.CanMatchmakeInto);
|
||||||
|
const newInstance = Instances.createInstance({
|
||||||
|
Room: targetRoom,
|
||||||
|
SceneIndex: Math.floor(Math.random() * matchmakeableSubrooms.length),
|
||||||
|
FirstPlayer: options.profile
|
||||||
|
});
|
||||||
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: newInstance };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Instances.setPlayerInstance(options.profile, foundInstance);
|
||||||
|
return { errorCode: MatchmakingErrorCode.Success, roomInstance: foundInstance };
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if roomname is dormroom, create the profile's dormroom if it does not exist
|
|
||||||
set the target room to the profile's dormroom id
|
|
||||||
|
|
||||||
get all public instances for roomname
|
}
|
||||||
filter out private and full instances
|
|
||||||
if a subroomname was specified, filter out subrooms that are not that subroom
|
|
||||||
|
|
||||||
pick an instance of the given instances at random
|
|
||||||
if none exist, create one
|
|
||||||
use only matchmakeable subrooms
|
|
||||||
if none are matchmakeable, go to "Home"
|
|
||||||
if "Home" does not exist, go to the first index
|
|
||||||
|
|
||||||
go to that instance
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ const instancePlayers: Map<RoomInstance, Set<Profile>> = new Map();
|
|||||||
* `Map<roomId (number), RoomInstance>`
|
* `Map<roomId (number), RoomInstance>`
|
||||||
*/
|
*/
|
||||||
const instanceMap: Map<number, Set<RoomInstance>> = new Map();
|
const instanceMap: Map<number, Set<RoomInstance>> = new Map();
|
||||||
/**
|
|
||||||
* `Map<instanceId (number), roomId (number)>`
|
|
||||||
*/
|
|
||||||
const instanceRoomMap: Map<number, number> = new Map();
|
|
||||||
|
|
||||||
class InstancesBase {
|
class InstancesBase {
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export const KeyGroups = {
|
|||||||
Room_Names: "room-names",
|
Room_Names: "room-names",
|
||||||
Rooms: {
|
Rooms: {
|
||||||
Root: "room",
|
Root: "room",
|
||||||
|
PlayerDorms: "player-dormids"
|
||||||
},
|
},
|
||||||
Operators: "operators",
|
Operators: "operators",
|
||||||
Users: {
|
Users: {
|
||||||
|
|||||||
@@ -33,14 +33,30 @@ route.router.post('/room/:roomName',
|
|||||||
APIUtils.Authentication,
|
APIUtils.Authentication,
|
||||||
APIUtils.AuthenticationType(AuthType.Game),
|
APIUtils.AuthenticationType(AuthType.Game),
|
||||||
|
|
||||||
(rq: express.Request<MatchmakingParams>, rs: express.Response) => {
|
async (rq: express.Request<MatchmakingParams>, rs: express.Response) => {
|
||||||
if (!rq.params.roomName) {
|
if (!rq.params.roomName) {
|
||||||
rs.json({
|
rs.json({
|
||||||
errorCode: MatchmakingErrorCode.NoSuchRoom
|
errorCode: MatchmakingErrorCode.NoSuchRoom
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rs.json(Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName }));
|
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName }));
|
||||||
},
|
},
|
||||||
|
|
||||||
);
|
);
|
||||||
|
route.router.post('/room/:roomName/:subRoomName',
|
||||||
|
|
||||||
|
APIUtils.Authentication,
|
||||||
|
APIUtils.AuthenticationType(AuthType.Game),
|
||||||
|
|
||||||
|
async (rq: express.Request<MatchmakingParams>, rs: express.Response) => {
|
||||||
|
if (!rq.params.roomName) {
|
||||||
|
rs.json({
|
||||||
|
errorCode: MatchmakingErrorCode.NoSuchRoom
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rs.json(await Matchmaking.matchmake({ profile: rs.locals.profile, roomName: rq.params.roomName, subRoomName: rq.params.subRoomName }));
|
||||||
|
},
|
||||||
|
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user