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 { getJSONfromString } from "../../helpers/stringHelpers.ts";
import { getAccountForRequest, getBuildLabel } from "../../services/loginService.ts";
import type { RequestHandler } from "express";
import type { IUpgradeClient, IUpgradeFromClient } from "../../types/inventoryTypes/inventoryTypes.ts";
import {
    addCrewShipFusionPoints,
    addFusionPoints,
    addMiscItem,
    addMods,
    getInventory2,
    updateCredits
} from "../../services/inventoryService.ts";
import { broadcastInventoryUpdate } from "../../services/wsService.ts";
import { fromOid, version_compare } from "../../helpers/inventoryHelpers.ts";
import gameToBuildVersion from "../../constants/gameToBuildVersion.ts";

export const artifactsController: RequestHandler = async (req, res) => {
    const account = await getAccountForRequest(req);
    const artifactsData = getJSONfromString<IArtifactsRequest>(String(req.body));

    const { Upgrade, LevelDiff, Cost, FusionPointCost, Consumed, Fingerprint } = artifactsData;

    const inventory = await getInventory2(
        account._id,
        "Upgrades",
        "MiscItems",
        "RawUpgrades",
        "infiniteCredits",
        "RegularCredits",
        "infiniteEndo",
        "FusionPoints",
        "infiniteDirac",
        "CrewShipFusionPoints"
    );
    const { Upgrades } = inventory;
    const { ItemType, UpgradeFingerprint, ItemId } = Upgrade;

    const buildLabel = getBuildLabel(req, account);
    if (version_compare(buildLabel, gameToBuildVersion["18.18.0"]) >= 0) {
        const useDiracForFusion =
            version_compare(buildLabel, gameToBuildVersion["29.10.0"]) < 0 &&
            Upgrade.ItemType.startsWith("/Lotus/Upgrades/Mods/Railjack/");
        const safeUpgradeFingerprint = UpgradeFingerprint || '{"lvl":0}';
        const parsedUpgradeFingerprint = JSON.parse(safeUpgradeFingerprint) as { lvl: number; variant?: number };
        parsedUpgradeFingerprint.lvl += LevelDiff;
        if (artifactsData.VariantFusion !== undefined) {
            parsedUpgradeFingerprint.variant = artifactsData.VariantFusion;
            addMiscItem(inventory, "/Lotus/Types/Items/MiscItems/FoilModUnlocker", -1);
        }
        const stringifiedUpgradeFingerprint = JSON.stringify(parsedUpgradeFingerprint);

        let itemId = fromOid(ItemId);
        let itemIndex = Upgrades.findIndex(upgrade => upgrade._id.equals(itemId));

        if (itemIndex !== -1) {
            Upgrades[itemIndex].UpgradeFingerprint = stringifiedUpgradeFingerprint;
        } else {
            itemIndex =
                Upgrades.push({
                    UpgradeFingerprint: stringifiedUpgradeFingerprint,
                    ItemType
                }) - 1;
            itemId = Upgrades[itemIndex]._id.toString();

            addMods(inventory, [{ ItemType, ItemCount: -1 }]);
        }

        updateCredits(inventory, Cost);

        if (useDiracForFusion) {
            addCrewShipFusionPoints(inventory, -FusionPointCost);
        } else {
            addFusionPoints(inventory, -FusionPointCost);
        }

        if (artifactsData.LegendaryFusion) {
            addMods(inventory, [
                {
                    ItemType: "/Lotus/Upgrades/Mods/Fusers/LegendaryModFuser",
                    ItemCount: -1
                }
            ]);
        }

        await inventory.save();

        res.send(itemId);
    } else {
        // Pre-U18.18.0 uses the old pre-Endo fusion system which uses a different UpgradeFingerprint format
        // that has to be converted and consumes upgrades in the fusion proccess
        const safeUpgradeFingerprint = `{"lvl":${Fingerprint?.substring(4, Fingerprint.lastIndexOf("|"))}}`;
        const parsedUpgradeFingerprint = JSON.parse(safeUpgradeFingerprint) as { lvl: number };
        if (LevelDiff) {
            parsedUpgradeFingerprint.lvl += LevelDiff;
        }
        const stringifiedUpgradeFingerprint = JSON.stringify(parsedUpgradeFingerprint);

        let itemIndex = Upgrades.findIndex(upgrade => upgrade._id.equals(ItemId.$id));

        if (itemIndex !== -1) {
            Upgrades[itemIndex].UpgradeFingerprint = stringifiedUpgradeFingerprint;
        } else {
            itemIndex =
                Upgrades.push({
                    UpgradeFingerprint: stringifiedUpgradeFingerprint,
                    ItemType
                }) - 1;

            addMods(inventory, [{ ItemType, ItemCount: -1 }]);
        }

        const itemId = Upgrades[itemIndex]._id.toString();
        if (!itemId) {
            throw new Error("Item Id not found in upgradeMod");
        }

        if (!inventory.infiniteCredits) {
            inventory.RegularCredits -= Cost;
        }
        if (Consumed && Consumed.length > 0) {
            for (const upgrade of Consumed) {
                // The client does not send the expected information about the mods, so we have to check if it's an Upgrade or RawUpgrade manually.
                if (Upgrades.id(fromOid(upgrade.ItemId))) {
                    Upgrades.pull({ _id: upgrade.ItemId.$id });
                } else {
                    addMods(inventory, [
                        {
                            ItemType: upgrade.ItemType,
                            ItemCount: -1
                        }
                    ]);
                }
            }

            itemIndex = Upgrades.findIndex(upgrade => upgrade._id.equals(itemId));
        }

        await inventory.save();

        res.send(itemId);
    }

    broadcastInventoryUpdate(req);
};

interface IArtifactsRequest {
    Upgrade: IUpgradeClient;
    LevelDiff: number;
    Cost: number;
    FusionPointCost: number;
    LegendaryFusion?: boolean;
    Fingerprint?: string;
    Consumed?: IUpgradeFromClient[];
    VariantFusion?: number;
}