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

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
UTF-8
import { Session } from "../models/sessionModel.ts";
import { generateRewardSeed } from "./rngService.ts";
import type {
    ISession,
    IFindSessionRequest,
    IFindSessionResponseSession,
    IHostSessionRequest,
    ISessionDatabase
} from "../types/sessionTypes.ts";
import { logger } from "../utils/logger.ts";
import { JSONParse } from "json-with-bigint";
import { Types, type QueryFilter } from "mongoose";

//const sessions: ISession[] = [];

export const createNewSession = async (
    sessionData: IHostSessionRequest,
    Creator: Types.ObjectId
): Promise<ISession> => {
    const newSession: ISessionDatabase = {
        _id: new Types.ObjectId(),
        ...sessionData,
        creatorId: Creator,
        //maxPlayers: sessionData.maxPlayers ?? 4,
        //minPlayers: sessionData.minPlayers ?? 1,
        //privateSlots: sessionData.privateSlots ?? 0,
        //scoreLimit: sessionData.scoreLimit ?? 15,
        //timeLimit: sessionData.timeLimit ?? 900,
        //gameModeId: sessionData.gameModeId ?? 0,
        //eloRating: sessionData.eloRating ?? 3,
        //regionId: sessionData.regionId ?? 3,
        //difficulty: sessionData.difficulty ?? 0,
        hasStarted: sessionData.hasStarted ?? false,
        //enableVoice: sessionData.enableVoice ?? true,
        //matchType: sessionData.matchType ?? "NORMAL",
        //maps: sessionData.maps ?? [],
        //originalSessionId: sessionData.originalSessionId ?? "",
        //customSettings: sessionData.customSettings ?? "",
        rewardSeed: sessionData.rewardSeed || -1,
        //guildId: sessionData.guildId ?? "",
        //buildId: sessionData.buildId ?? 4920386201513015989n,
        //platform: sessionData.platform ?? Platform.Windows,
        //xplatform: sessionData.xplatform ?? false,
        //freePublic: sessionData.freePublic ?? 3,
        //freePrivate: sessionData.freePrivate ?? 0,
        fullReset: 0,

        lastUpdate: new Date()
    };
    if (newSession.rewardSeed == -1) {
        newSession.rewardSeed = generateRewardSeed();
    }

    await Session.create(newSession);
    //sessions.push(newSession);

    return newSession;
};

export const getSessionByID = async (sessionId: string | Types.ObjectId): Promise<ISessionDatabase | null> => {
    return await Session.findById(sessionId);
};

export const getSession = async (request: IFindSessionRequest): Promise<IFindSessionResponseSession[]> => {
    const query: QueryFilter<ISessionDatabase> = {};
    if ("id" in request) {
        query._id = request.id;
    } else if ("originalSessionId" in request) {
        query.originalSessionId = request.originalSessionId;
    } else {
        query.hasStarted = false;
        query.buildId = request.buildId;
        query.gameModeId = request.gameModeId;
        if (request.freePublic) {
            query.freePublic = { $gte: 1 };
        }
        query.regionId = request.regionId;
        if (request.eloRating !== undefined && request.maxEloDifference !== undefined) {
            query.eloRating = {
                $gte: request.eloRating - request.maxEloDifference,
                $lte: request.eloRating + request.maxEloDifference
            };
        }
        if (request.maps) {
            query.maps = request.maps;
        }
    }
    return (await Session.find(query, "creatorId")).map(session => ({
        createdBy: session.creatorId.toString(),
        id: session._id.toString()
    }));

    /*return sessions
        .filter(session => {
            if ("id" in request) {
                return session._id.equals(request.id);
            } else if ("originalSessionId" in request) {
                return session._id.equals(request.originalSessionId);
            } else {
                return (
                    !session.hasStarted &&
                    request.buildId == session.buildId &&
                    request.gameModeId == session.gameModeId &&
                    (!request.freePublic || session.freePublic >= 1) &&
                    session.regionId == request.regionId &&
                    Math.abs(session.eloRating - request.eloRating) <= request.maxEloDifference &&
                    (!request.maps || session.maps.indexOf(request.maps) != -1)
                );
            }
        })
        .map(session => ({
            createdBy: session.creatorId.toString(),
            id: session._id.toString()
        }));*/
};

export const updateSession = async (
    sessionId: string | Types.ObjectId,
    updateData: string | undefined
): Promise<boolean> => {
    //const session = sessions.find(session => session._id.equals(sessionId));
    const session = await Session.findById(sessionId);
    if (!session) {
        return false;
    }

    if (updateData) {
        logger.debug(`session update: ${updateData}`);
        if (updateData.substring(0, 1) == "{") {
            try {
                Object.assign(session, JSONParse(updateData));
            } catch (error) {
                logger.error("Invalid JSON string for session update.");
                return false;
            }
        } else {
            const updates: string[] = updateData.split("&");
            for (const update of updates) {
                const arr = update.split("=");
                if (arr.length == 2) {
                    const [key, value] = arr;
                    switch (key) {
                        case "maxPlayers":
                        case "minPlayers":
                        case "privateSlots":
                        case "scoreLimit":
                        case "timeLimit":
                        case "gameModeId":
                        case "eloRating":
                        case "regionId":
                        case "difficulty":
                        case "freePublic":
                        case "freePrivate":
                            session[key] = parseInt(value);
                            break;

                        default:
                            logger.error(`unexpected key in legacy session update format: ${key}`);
                            break;
                    }
                }
            }
        }
    }

    session.lastUpdate = new Date();
    logger.trace(`session after update:`, session);
    await session.save();

    return true;
};

export const deleteSession = async (sessionId: string | Types.ObjectId): Promise<void> => {
    await Session.deleteOne({ _id: sessionId });

    /*const index = sessions.findIndex(session => session._id.equals(sessionId));
    if (index !== -1) {
        sessions.splice(index, 1);
    }*/
};

export const aggregateSessions = (): Promise<{ gameModeId: number; count: number }[]> => {
    return Session.aggregate([
        {
            $match: {
                freePublic: { $ne: 0 }
            }
        },
        {
            $group: {
                _id: "$gameModeId",
                count: { $sum: 1 }
            }
        },
        {
            $project: {
                _id: 0,
                gameModeId: "$_id",
                count: 1
            }
        }
    ]);

    /*const result: { gameModeId: number; count: number }[] = [];
    for (const session of sessions) {
        if (session.freePublic != 0) {
            const obj = result.find(x => x.gameModeId == session.gameModeId);
            if (obj) {
                obj.count += 1;
            } else {
                result.push({ gameModeId: session.gameModeId, count: 1 });
            }
        }
    }
    return result;*/
};