Server/project/src/controllers/BuildController.ts

230 lines
8.5 KiB
TypeScript
Raw Normal View History

2023-03-03 15:23:46 +00:00
import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
import { IPresetBuildActionRequestData } from "@spt-aki/models/eft/presetBuild/IPresetBuildActionRequestData";
import { IRemoveBuildRequestData } from "@spt-aki/models/eft/presetBuild/IRemoveBuildRequestData";
import { IUserBuilds, IWeaponBuild } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
2023-03-03 15:23:46 +00:00
@injectable()
2023-12-27 20:19:17 +00:00
export class BuildController
2023-03-03 15:23:46 +00:00
{
constructor(
@inject("WinstonLogger") protected logger: ILogger,
2023-03-03 15:23:46 +00:00
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("EventOutputHolder") protected eventOutputHolder: EventOutputHolder,
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
2023-03-03 15:23:46 +00:00
@inject("ItemHelper") protected itemHelper: ItemHelper,
2023-11-10 16:49:29 -05:00
@inject("SaveServer") protected saveServer: SaveServer,
2023-03-03 15:23:46 +00:00
)
2023-11-10 16:49:29 -05:00
{}
2023-03-03 15:23:46 +00:00
2023-07-15 14:49:25 +01:00
/** Handle client/handbook/builds/my/list */
public getUserBuilds(sessionID: string): IUserBuilds
2023-03-03 15:23:46 +00:00
{
const profile = this.saveServer.getProfile(sessionID);
if (!profile.userbuilds)
{
2023-12-27 20:19:17 +00:00
profile.userbuilds = { equipmentBuilds: [], weaponBuilds: [], magazineBuilds: [] };
}
// Ensure the secure container in the default presets match what the player has equipped
2023-11-10 16:49:29 -05:00
const defaultEquipmentPresets = this.jsonUtil.clone(
this.databaseServer.getTables().templates.defaultEquipmentPresets,
);
const playerSecureContainer = profile.characters.pmc.Inventory.items?.find((x) =>
x.slotId === "SecuredContainer"
);
const firstDefaultItemsSecureContainer = defaultEquipmentPresets[0]?.items?.find((x) =>
x.slotId === "SecuredContainer"
);
if (playerSecureContainer && playerSecureContainer?._tpl !== firstDefaultItemsSecureContainer?._tpl)
{
2023-11-10 16:49:29 -05:00
// Default equipment presets' secure container tpl doesn't match players secure container tpl
for (const defaultPreset of defaultEquipmentPresets)
{
// Find presets secure container
2023-11-10 16:49:29 -05:00
const secureContainer = defaultPreset.items.find((x) => x.slotId === "SecuredContainer");
if (secureContainer)
{
secureContainer._tpl = playerSecureContainer._tpl;
}
}
}
// Clone player build data from profile and append the above defaults onto end
const result = this.jsonUtil.clone(profile.userbuilds);
result.equipmentBuilds.push(...defaultEquipmentPresets);
return result;
}
/** Handle SaveWeaponBuild event */
2023-11-10 16:49:29 -05:00
public saveWeaponBuild(
pmcData: IPmcData,
body: IPresetBuildActionRequestData,
sessionId: string,
): IItemEventRouterResponse
{
2023-11-10 16:49:29 -05:00
// TODO: Could be merged into saveBuild, maybe
const output = this.eventOutputHolder.getOutput(sessionId);
// Replace duplicate Id's. The first item is the base item.
// The root ID and the base item ID need to match.
body.items = this.itemHelper.replaceIDs(pmcData, body.items);
body.root = body.items[0]._id;
// Create new object ready to save into profile userbuilds.weaponBuilds
const newId = this.hashUtil.generate(); // Id is empty, generate it
const newBuild: IWeaponBuild = {
id: newId,
name: body.name,
root: body.root,
items: body.items,
type: "weapon",
};
const savedWeaponBuilds = this.saveServer.getProfile(sessionId).userbuilds.weaponBuilds;
2023-11-10 16:49:29 -05:00
const existingBuild = savedWeaponBuilds.find((x) => x.id === body.id);
if (existingBuild)
{
// exists, replace
2023-11-10 16:49:29 -05:00
this.saveServer.getProfile(sessionId).userbuilds.weaponBuilds.splice(
savedWeaponBuilds.indexOf(existingBuild),
1,
newBuild,
);
}
else
{
// Add fresh
this.saveServer.getProfile(sessionId).userbuilds.weaponBuilds.push(newBuild);
}
// Inform client of new weapon preset
output.profileChanges[sessionId].weaponBuilds.push(newBuild);
return output;
2023-03-03 15:23:46 +00:00
}
/** Handle SaveEquipmentBuild event */
2023-11-10 16:49:29 -05:00
public saveEquipmentBuild(
pmcData: IPmcData,
body: IPresetBuildActionRequestData,
sessionID: string,
): IItemEventRouterResponse
2023-03-03 15:23:46 +00:00
{
return this.saveBuild(pmcData, body, sessionID, "equipmentBuilds");
}
2023-03-03 15:23:46 +00:00
2023-11-10 16:49:29 -05:00
protected saveBuild(
pmcData: IPmcData,
body: IPresetBuildActionRequestData,
sessionID: string,
buildType: string,
): IItemEventRouterResponse
{
2023-03-03 15:23:46 +00:00
const output = this.eventOutputHolder.getOutput(sessionID);
const existingSavedBuilds: any[] = this.saveServer.getProfile(sessionID).userbuilds[buildType];
2023-03-03 15:23:46 +00:00
// replace duplicate ID's. The first item is the base item.
// The root ID and the base item ID need to match.
body.items = this.itemHelper.replaceIDs(pmcData, body.items);
const newBuild = {
id: this.hashUtil.generate(),
name: body.name,
buildType: "Custom",
root: body.root,
fastPanel: [],
2023-11-10 16:49:29 -05:00
items: body.items,
};
2023-11-10 16:49:29 -05:00
const existingBuild = existingSavedBuilds.find((x) => x.name === body.name);
if (existingBuild)
{
// Already exists, replace
2023-11-10 16:49:29 -05:00
this.saveServer.getProfile(sessionID).userbuilds[buildType].splice(
existingSavedBuilds.indexOf(existingBuild),
1,
newBuild,
);
}
else
{
// Fresh, add new
this.saveServer.getProfile(sessionID).userbuilds[buildType].push(newBuild);
}
output.profileChanges[sessionID][buildType].push(newBuild);
2023-03-03 15:23:46 +00:00
return output;
}
/** Handle RemoveWeaponBuild event*/
public removeBuild(pmcData: IPmcData, body: IRemoveBuildRequestData, sessionID: string): IItemEventRouterResponse
{
return this.removePlayerBuild(pmcData, body.id, sessionID);
}
/** Handle RemoveWeaponBuild event*/
2023-11-10 16:49:29 -05:00
public removeWeaponBuild(
pmcData: IPmcData,
body: IPresetBuildActionRequestData,
sessionID: string,
): IItemEventRouterResponse
{
2023-11-10 16:49:29 -05:00
// TODO: Does this get called?
return this.removePlayerBuild(pmcData, body.id, sessionID);
}
/** Handle RemoveEquipmentBuild event*/
2023-11-10 16:49:29 -05:00
public removeEquipmentBuild(
pmcData: IPmcData,
body: IPresetBuildActionRequestData,
sessionID: string,
): IItemEventRouterResponse
{
2023-11-10 16:49:29 -05:00
// TODO: Does this get called?
return this.removePlayerBuild(pmcData, body.id, sessionID);
}
2023-11-10 16:49:29 -05:00
protected removePlayerBuild(pmcData: IPmcData, id: string, sessionID: string): IItemEventRouterResponse
2023-03-03 15:23:46 +00:00
{
const weaponBuilds = this.saveServer.getProfile(sessionID).userbuilds.weaponBuilds;
const equipmentBuilds = this.saveServer.getProfile(sessionID).userbuilds.equipmentBuilds;
2023-03-03 15:23:46 +00:00
// Check for id in weapon array first
2023-11-10 16:49:29 -05:00
const matchingWeaponBuild = weaponBuilds.find((x) => x.id === id);
if (matchingWeaponBuild)
2023-03-03 15:23:46 +00:00
{
weaponBuilds.splice(weaponBuilds.indexOf(matchingWeaponBuild), 1);
return this.eventOutputHolder.getOutput(sessionID);
}
// Id not found in weapons, try equipment
2023-11-10 16:49:29 -05:00
const matchingEquipmentBuild = equipmentBuilds.find((x) => x.id === id);
if (matchingEquipmentBuild)
{
equipmentBuilds.splice(equipmentBuilds.indexOf(matchingEquipmentBuild), 1);
}
// Not found in weapons or equipment, not good
if (!(matchingWeaponBuild || matchingEquipmentBuild))
{
this.logger.error(`Unable to delete preset, cannot find ${id} in weapon or equipment presets`);
2023-03-03 15:23:46 +00:00
}
return this.eventOutputHolder.getOutput(sessionID);
}
2023-11-10 16:49:29 -05:00
}