XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

fix: findSessions for matchmaking (#3532)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3532 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

f0dbf632
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

5 个文件 +105 -114
Modified src/controllers/api/findSessionsController.ts +5 -20
@@ -5,24 +5,9 @@ import type { IFindSessionRequest } from "../../types/session.ts";
5 5
6 6 export const findSessionsController: RequestHandler = (_req, res) => {
7 7 const req = JSON.parse(String(_req.body)) as IFindSessionRequest;
8 logger.debug("FindSession Request ", req);
9 if (req.id != undefined) {
10 logger.debug("Found ID");
11 const sessions = getSession(req.id);
12
13 if (sessions.length) res.json({ queryId: req.queryId, Sessions: sessions });
14 else res.json({});
15 } else if (req.originalSessionId != undefined) {
16 logger.debug("Found OriginalSessionID");
17
18 const session = getSession(req.originalSessionId);
19 if (session.length) res.json({ queryId: req.queryId, Sessions: session });
20 else res.json({});
21 } else {
22 logger.debug("Found SessionRequest");
23
24 const session = getSession(req);
25 if (session.length) res.json({ queryId: req.queryId, Sessions: session });
26 else res.json({});
27 }
8 logger.debug("FindSession Request:", req);
9 const sessions = getSession(req);
10 logger.debug("FindSession Result:", { sessions });
11 if (sessions.length) res.json({ queryId: req.queryId, Sessions: sessions });
12 else res.json({});
28 13 };
Modified src/controllers/api/hostSessionController.ts +2 -2
@@ -2,14 +2,14 @@ import type { RequestHandler } from "express";
2 2 import { getAccountForRequest } from "../../services/loginService.ts";
3 3 import { createNewSession } from "../../managers/sessionManager.ts";
4 4 import { logger } from "../../utils/logger.ts";
5 import type { ISession } from "../../types/session.ts";
5 import type { IHostSessionRequest } from "../../types/session.ts";
6 6 import { JSONParse } from "json-with-bigint";
7 7 import { toOid2, version_compare } from "../../helpers/inventoryHelpers.ts";
8 8 import gameToBuildVersion from "../../constants/gameToBuildVersion.ts";
9 9
10 10 const hostSessionController: RequestHandler = async (req, res) => {
11 11 const account = await getAccountForRequest(req);
12 const hostSessionRequest = JSONParse(String(req.body)) as ISession;
12 const hostSessionRequest = JSONParse(String(req.body)) as IHostSessionRequest;
13 13 logger.debug("HostSession Request", { hostSessionRequest });
14 14 const session = createNewSession(hostSessionRequest, account._id);
15 15 logger.debug(`New Session Created`, { session });
Modified src/controllers/api/updateSessionController.ts +3 -1
@@ -7,7 +7,9 @@ const updateSessionGetController: RequestHandler = (_req, res) => {
7 7 const updateSessionPostController: RequestHandler = (_req, res) => {
8 8 //console.log("UpdateSessions POST Request:", JSON.parse(String(_req.body)));
9 9 //console.log("ReqID:", _req.query.sessionId as string);
10 updateSession(_req.query.sessionId as string, String(_req.body));
10 if (!updateSession(_req.query.sessionId as string, String(_req.body))) {
11 res.status(400);
12 }
11 13 res.json({});
12 14 };
13 15 export { updateSessionGetController, updateSessionPostController };
Modified src/managers/sessionManager.ts +49 -57
@@ -1,38 +1,43 @@
1 1 import { generateRewardSeed } from "../services/rngService.ts";
2 import type { ISession, IFindSessionRequest, IFindSessionResponseSession } from "../types/session.ts";
2 import type {
3 ISession,
4 IFindSessionRequest,
5 IFindSessionResponseSession,
6 IHostSessionRequest
7 } from "../types/session.ts";
3 8 import { logger } from "../utils/logger.ts";
4 9 import { JSONParse } from "json-with-bigint";
5 10 import { Types } from "mongoose";
6 11
7 12 const sessions: ISession[] = [];
8 13
9 function createNewSession(sessionData: ISession, Creator: Types.ObjectId): ISession {
14 function createNewSession(sessionData: IHostSessionRequest, Creator: Types.ObjectId): ISession {
10 15 const sessionId = new Types.ObjectId();
11 16 const newSession: ISession = {
12 17 sessionId,
13 18 creatorId: Creator,
14 maxPlayers: sessionData.maxPlayers || 4,
15 minPlayers: sessionData.minPlayers || 1,
16 privateSlots: sessionData.privateSlots || 0,
17 scoreLimit: sessionData.scoreLimit || 15,
18 timeLimit: sessionData.timeLimit || 900,
19 gameModeId: sessionData.gameModeId || 0,
20 eloRating: sessionData.eloRating || 3,
21 regionId: sessionData.regionId || 3,
22 difficulty: sessionData.difficulty || 0,
23 hasStarted: sessionData.hasStarted || false,
24 enableVoice: sessionData.enableVoice || true,
25 matchType: sessionData.matchType || "NORMAL",
26 maps: sessionData.maps || [],
27 originalSessionId: sessionData.originalSessionId || "",
28 customSettings: sessionData.customSettings || "",
19 maxPlayers: sessionData.maxPlayers, // || 4
20 minPlayers: sessionData.minPlayers, // || 1
21 privateSlots: sessionData.privateSlots, // || 0
22 scoreLimit: sessionData.scoreLimit, // || 15
23 timeLimit: sessionData.timeLimit, // || 900
24 gameModeId: sessionData.gameModeId, // || 0
25 eloRating: sessionData.eloRating, // || 3
26 regionId: sessionData.regionId, // || 3
27 difficulty: sessionData.difficulty, // || 0
28 hasStarted: sessionData.hasStarted, // || false
29 enableVoice: sessionData.enableVoice, // || true
30 matchType: sessionData.matchType, // || "NORMAL"
31 maps: sessionData.maps, // || []
32 originalSessionId: sessionData.originalSessionId, // || ""
33 customSettings: sessionData.customSettings, // || ""
29 34 rewardSeed: sessionData.rewardSeed || -1,
30 guildId: sessionData.guildId || "",
31 buildId: sessionData.buildId || 4920386201513015989n,
32 platform: sessionData.platform || 0,
33 xplatform: sessionData.xplatform || true,
34 freePublic: sessionData.freePublic || 3,
35 freePrivate: sessionData.freePrivate || 0,
35 guildId: sessionData.guildId, // || ""
36 buildId: sessionData.buildId, // || 4920386201513015989n
37 platform: sessionData.platform ?? 0,
38 xplatform: sessionData.xplatform ?? false,
39 freePublic: sessionData.freePublic, // || 3
40 freePrivate: sessionData.freePrivate, // || 0
36 41 fullReset: 0
37 42 };
38 43 if (newSession.rewardSeed == -1) {
@@ -50,39 +55,26 @@ function getSessionByID(sessionId: string | Types.ObjectId): ISession | undefine
50 55 return sessions.find(session => session.sessionId.equals(sessionId));
51 56 }
52 57
53 function getSession(sessionIdOrRequest: string | Types.ObjectId | IFindSessionRequest): IFindSessionResponseSession[] {
54 if (typeof sessionIdOrRequest === "string" || sessionIdOrRequest instanceof Types.ObjectId) {
55 const session = sessions.find(session => session.sessionId.equals(sessionIdOrRequest));
56 if (session) {
57 logger.debug("Found Sessions:", { session });
58 return [
59 {
60 createdBy: session.creatorId.toString(),
61 id: session.sessionId.toString()
62 }
63 ];
64 }
65 return [];
66 }
67
68 const request = sessionIdOrRequest;
69 const matchingSessions = sessions.filter(session => {
70 for (const key in request) {
71 if (
72 key !== "eloRating" &&
73 key !== "queryId" &&
74 request[key as keyof IFindSessionRequest] !== session[key as keyof ISession]
75 ) {
76 return false;
58 function getSession(request: IFindSessionRequest): IFindSessionResponseSession[] {
59 return sessions
60 .filter(session => {
61 if ("id" in request) {
62 return session.sessionId.equals(request.id);
63 } else if ("originalSessionId" in request) {
64 return session.sessionId.equals(request.originalSessionId);
65 } else {
66 return (
67 request.buildId == session.buildId &&
68 request.gameModeId == session.gameModeId &&
69 Math.abs(session.eloRating - request.eloRating) <= request.maxEloDifference &&
70 (request.maps == "" || session.maps.indexOf(request.maps) != -1)
71 );
77 72 }
78 }
79 logger.debug("Found Matching Sessions:", { matchingSessions });
80 return true;
81 });
82 return matchingSessions.map(session => ({
83 createdBy: session.creatorId.toString(),
84 id: session.sessionId.toString()
85 }));
73 })
74 .map(session => ({
75 createdBy: session.creatorId.toString(),
76 id: session.sessionId.toString()
77 }));
86 78 }
87 79
88 80 function getSessionByCreatorID(creatorId: string | Types.ObjectId): ISession | undefined {
@@ -90,14 +82,14 @@ function getSessionByCreatorID(creatorId: string | Types.ObjectId): ISession | u
90 82 }
91 83
92 84 function updateSession(sessionId: string | Types.ObjectId, sessionData: string): boolean {
93 logger.debug(`session update:`, sessionData);
85 logger.debug(`session update: ${sessionData}`);
94 86 const session = sessions.find(session => session.sessionId.equals(sessionId));
95 87 if (!session) return false;
96 88 try {
97 89 Object.assign(session, JSONParse(sessionData));
98 90 return true;
99 91 } catch (error) {
100 console.error("Invalid JSON string for session update.");
92 logger.error("Invalid JSON string for session update.");
101 93 return false;
102 94 }
103 95 }
Modified src/types/session.ts +46 -34
@@ -1,46 +1,58 @@
1 1 import type { Types } from "mongoose";
2 2
3 export interface ISession {
4 sessionId: Types.ObjectId;
5 creatorId: Types.ObjectId;
6 maxPlayers?: number;
7 minPlayers?: number;
8 privateSlots?: number;
9 scoreLimit?: number;
10 timeLimit?: number;
11 gameModeId?: number;
12 eloRating?: number;
13 regionId?: number;
14 difficulty?: number;
15 hasStarted?: boolean;
16 enableVoice?: boolean;
17 matchType?: string;
18 maps?: string[];
19 originalSessionId?: string;
20 customSettings?: string;
3 export interface IHostSessionRequest {
4 maxPlayers: number;
5 minPlayers: number;
6 privateSlots: number;
7 scoreLimit: number;
8 timeLimit: number;
9 gameModeId: number;
10 eloRating: number;
11 regionId: number;
12 difficulty: number;
13 hasStarted: boolean;
14 enableVoice: boolean;
15 matchType: string;
16 maps: string[];
17 originalSessionId: string;
18 customSettings: string;
21 19 rewardSeed?: number | bigint;
22 guildId?: string;
23 buildId?: number | bigint;
20 guildId: string;
21 buildId: number | bigint;
24 22 platform?: number;
25 23 xplatform?: boolean;
26 freePublic?: number;
27 freePrivate?: number;
28 fullReset?: number;
24 freePublic: number;
25 freePrivate: number;
26 fullReset: number;
29 27 }
30 28
31 export interface IFindSessionRequest {
32 id?: string;
33 originalSessionId?: string;
34 buildId?: number | bigint;
35 gameModeId?: number;
36 regionId?: number;
37 maxEloDifference?: number;
38 eloRating?: number;
39 enforceElo?: boolean;
40 xplatform?: boolean;
41 queryId?: number;
29 export interface ISession extends Omit<IHostSessionRequest, "rewardSeed" | "platform" | "xplatform"> {
30 sessionId: Types.ObjectId;
31 creatorId: Types.ObjectId;
32 rewardSeed: number | bigint;
33 platform: number;
34 xplatform: boolean;
42 35 }
43 36
37 export type IFindSessionRequest = { queryId: number } & (
38 | {
39 id: string;
40 }
41 | {
42 originalSessionId: string;
43 }
44 | {
45 buildId: number | bigint;
46 gameModeId: number;
47 maps: string;
48 regionId: number;
49 maxEloDifference: number;
50 eloRating: number;
51 enforceElo: boolean;
52 xplatform: boolean;
53 }
54 );
55
44 56 export interface IFindSessionResponse {
45 57 queryId: number;
46 58 Sesions: IFindSessionResponseSession[];