SpaceNinjaServer/src/services/saveLoadoutService.ts

187 lines
7.9 KiB
TypeScript
Raw Normal View History

import {
IItemEntry,
ILoadoutClient,
ILoadoutEntry,
ILoadoutConfigDatabase,
IOperatorConfigEntry,
ISaveLoadoutRequestNoUpgradeVer
} from "@/src/types/saveLoadoutTypes";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
import { getInventory } from "@/src/services/inventoryService";
import { IOid } from "@/src/types/commonTypes";
import { Types } from "mongoose";
import { isEmptyObject } from "@/src/helpers/general";
2024-01-06 16:26:58 +01:00
import { logger } from "@/src/utils/logger";
//TODO: setup default items on account creation or like originally in giveStartingItems.php
//TODO: change update functions to only add and not save perhaps, functions that add and return inventory perhaps
/* loadouts has loadoutconfigs
operatorloadouts has itemconfig, but no multiple config ids
itemconfig has multiple config ids
*/
export const handleInventoryItemConfigChange = async (
equipmentChanges: ISaveLoadoutRequestNoUpgradeVer,
accountId: string
): Promise<string | void> => {
const inventory = await getInventory(accountId);
for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) {
const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer];
const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer;
if (isEmptyObject(equipment)) {
continue;
}
// non-empty is a change in loadout(or suit...)
switch (equipmentName) {
case "OperatorLoadOuts":
case "AdultOperatorLoadOuts": {
const operatorConfig = equipment as IOperatorConfigEntry;
const operatorLoadout = inventory[equipmentName];
2024-01-06 16:26:58 +01:00
logger.debug(`operator loadout received ${equipmentName} `, operatorConfig);
// all non-empty entries are one loadout slot
for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) {
2024-01-06 16:26:58 +01:00
logger.debug(`loadoutId ${loadoutId} loadoutConfig`, { config: loadoutConfig });
const loadout = operatorLoadout.find(loadout => loadout._id?.toString() === loadoutId);
// if no config with this id exists, create a new one
if (!loadout) {
const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig;
operatorLoadout.push({
_id: ItemId.$id,
...loadoutConfigItemIdRemoved
});
continue;
}
loadout.set(loadoutConfig);
}
break;
}
case "LoadOuts": {
2024-01-06 16:26:58 +01:00
logger.debug("loadout received");
const loadout = await Loadout.findOne({ loadoutOwnerId: accountId });
if (!loadout) {
throw new Error("loadout not found");
}
let newLoadoutId: Types.ObjectId | undefined;
for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) {
const loadoutSlot = _loadoutSlot as keyof ILoadoutClient;
const newLoadout = _loadout as ILoadoutEntry;
// empty loadout slot like: "NORMAL": {}
if (isEmptyObject(newLoadout)) {
continue;
}
// all non-empty entries are one loadout slot
for (const [loadoutId, loadoutConfig] of Object.entries(newLoadout)) {
if (loadoutConfig.Remove) {
loadout[loadoutSlot].pull({ _id: loadoutId });
continue;
}
const oldLoadoutConfig = loadout[loadoutSlot].find(
loadout => loadout._id.toString() === loadoutId
);
const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig;
const loadoutConfigDatabase: ILoadoutConfigDatabase = {
_id: new Types.ObjectId(ItemId.$id),
...loadoutConfigItemIdRemoved
};
// if no config with this id exists, create a new one
if (!oldLoadoutConfig) {
//save the new object id and assign it for every ffff return at the end
if (ItemId.$id === "ffffffffffffffffffffffff") {
if (!newLoadoutId) {
newLoadoutId = new Types.ObjectId();
}
loadout[loadoutSlot].push({ _id: newLoadoutId, ...loadoutConfigItemIdRemoved });
continue;
}
loadout[loadoutSlot].push(loadoutConfigDatabase);
continue;
}
const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig);
if (loadoutIndex === undefined || loadoutIndex === -1) {
throw new Error("loadout index not found");
}
loadout[loadoutSlot][loadoutIndex].overwrite(loadoutConfigDatabase);
}
}
await loadout.save();
//only return an id if a new loadout was added
if (newLoadoutId) {
return newLoadoutId.toString();
}
break;
}
case "LongGuns":
case "Pistols":
case "Suits":
case "Melee":
case "Scoops":
case "DataKnives":
case "DrifterMelee":
case "Sentinels":
case "Horses":
case "OperatorAmps":
case "SentinelWeapons":
case "KubrowPets":
case "SpaceSuits":
case "SpaceGuns":
case "SpaceMelee":
case "SpecialItems":
case "MoaPets":
case "Hoverboards":
case "MechSuits":
case "CrewShipHarnesses":
case "CrewShips": {
2024-01-06 16:26:58 +01:00
logger.debug(`general Item config saved of type ${equipmentName}`, { config: equipment });
const itemEntries = equipment as IItemEntry;
for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId);
if (!inventoryItem) {
throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`);
}
//config ids are 0,1,2 can there be a 3?
for (const [configId, config] of Object.entries(itemConfigEntries)) {
inventoryItem.Configs[parseInt(configId)] = config;
}
}
break;
}
case "CurrentLoadOutIds": {
const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance
inventory.CurrentLoadOutIds = loadoutIds;
break;
}
2024-07-03 12:33:09 +02:00
case "EquippedGear":
case "EquippedEmotes": {
inventory[equipmentName] = equipment as string[];
break;
}
case "UseAdultOperatorLoadout": {
inventory.UseAdultOperatorLoadout = equipment as boolean;
break;
}
default: {
2024-01-06 16:26:58 +01:00
logger.error(`category not implemented: ${equipmentName}`, { config: equipment });
}
//case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory
}
}
await inventory.save();
};