Update types

This commit is contained in:
Dev 2023-09-30 15:48:09 +01:00
parent 746a756046
commit 148e517508
114 changed files with 3211 additions and 646 deletions

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

View File

@ -7,8 +7,6 @@ export interface IInsuranceConfig extends IBaseConfig {
returnChancePercent: Record<string, number>;
/** Item slots that should never be returned as insurance */
blacklistedEquipment: string[];
/** Names of equipment slots that could not be returned as insurance */
slotIdsWithChanceOfNotReturning: string[];
/** Override to control how quickly insurance is processed/returned in second */
returnTimeOverrideSeconds: number;
/** How often server should process insurance in seconds */

View File

@ -2,6 +2,7 @@ import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
import { NotifierHelper } from "../helpers/NotifierHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { Item } from "../models/eft/common/tables/IItem";
import { Dialogue, IUserDialogInfo, Message, MessageItems } from "../models/eft/profile/IAkiProfile";
import { MessageType } from "../models/enums/MessageType";
@ -24,56 +25,57 @@ export declare class MailSendService {
protected notificationSendHelper: NotificationSendHelper;
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected traderHelper: TraderHelper;
protected readonly systemSenderId = "59e7125688a45068a6249071";
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, notifierHelper: NotifierHelper, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, localisationService: LocalisationService, itemHelper: ItemHelper, traderHelper: TraderHelper);
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param message Text to send to the player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendDirectNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendDirectNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, message: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items
* @param playerId Players id to send message to
* @param sender The trader sending the message
* @param sessionId The session ID to send the message to
* @param trader The trader sending the message
* @param messageType What type the message will assume (e.g. QUEST_SUCCESS)
* @param messageLocaleId The localised text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedNpcMessageToPlayer(playerId: string, sender: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
sendLocalisedNpcMessageToPlayer(sessionId: string, trader: Traders, messageType: MessageType, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any, systemData?: any, ragfair?: any): void;
/**
* Send a message from SYSTEM to the player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendSystemMessageToPlayer(playerId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendSystemMessageToPlayer(sessionId: string, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a message from SYSTEM to the player with or without items with loalised text
* @param playerId Players id to send message to
* Send a message from SYSTEM to the player with or without items with localised text
* @param sessionId The session ID to send the message to
* @param messageLocaleId Id of key from locale file to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendLocalisedSystemMessageToPlayer(playerId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendLocalisedSystemMessageToPlayer(sessionId: string, messageLocaleId: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Send a USER message to a player with or without items
* @param playerId Players id to send message to
* @param sessionId The session ID to send the message to
* @param senderId Who is sending the message
* @param message The text to send to player
* @param items Optional items to send to player
* @param maxStorageTimeSeconds Optional time to collect items before they expire
*/
sendUserMessageToPlayer(playerId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
sendUserMessageToPlayer(sessionId: string, senderDetails: IUserDialogInfo, message: string, items?: Item[], maxStorageTimeSeconds?: any): void;
/**
* Large function to send messages to players from a variety of sources (SYSTEM/NPC/USER)
* Helper functions in this class are availble to simplify common actions
* Helper functions in this class are available to simplify common actions
* @param messageDetails Details needed to send a message to the player
*/
sendMessageToPlayer(messageDetails: ISendMessageDetails): void;

View File

@ -1,8 +1,10 @@
import { DialogueHelper } from "../helpers/DialogueHelper";
import { ItemHelper } from "../helpers/ItemHelper";
import { ProfileHelper } from "../helpers/ProfileHelper";
import { TraderHelper } from "../helpers/TraderHelper";
import { IPmcData } from "../models/eft/common/IPmcData";
import { Item } from "../models/eft/common/tables/IItem";
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
import { IGetInsuranceCostRequestData } from "../models/eft/insurance/IGetInsuranceCostRequestData";
import { IGetInsuranceCostResponseData } from "../models/eft/insurance/IGetInsuranceCostResponseData";
import { IInsureRequestData } from "../models/eft/insurance/IInsureRequestData";
@ -15,6 +17,7 @@ import { ConfigServer } from "../servers/ConfigServer";
import { DatabaseServer } from "../servers/DatabaseServer";
import { SaveServer } from "../servers/SaveServer";
import { InsuranceService } from "../services/InsuranceService";
import { MailSendService } from "../services/MailSendService";
import { PaymentService } from "../services/PaymentService";
import { RandomUtil } from "../utils/RandomUtil";
import { TimeUtil } from "../utils/TimeUtil";
@ -28,31 +31,134 @@ export declare class InsuranceController {
protected itemHelper: ItemHelper;
protected profileHelper: ProfileHelper;
protected dialogueHelper: DialogueHelper;
protected traderHelper: TraderHelper;
protected paymentService: PaymentService;
protected insuranceService: InsuranceService;
protected mailSendService: MailSendService;
protected configServer: ConfigServer;
protected insuranceConfig: IInsuranceConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, traderHelper: TraderHelper, paymentService: PaymentService, insuranceService: InsuranceService, mailSendService: MailSendService, configServer: ConfigServer);
/**
* Process insurance items prior to being given to player in mail
*/
* Process insurance items of all profiles prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturn(): void;
/**
* Change SlotId of children inside Containers to be a root item
* @param insured Insured Items
*/
protected updateSlotIdOfContainersChildren(insured: Insurance): void;
* Process insurance items of a single profile prior to being given back to the player through the mail service.
*
* @returns void
*/
processReturnByProfile(sessionID: string): void;
/**
* Should the passed in item be removed from player inventory
* @param insuredItem Insurued item to roll to lose
* @param traderId Trader the item was insured by
* @param itemsBeingDeleted All items to remove from player
* @returns True if item should be removed
* Get all insured items that are ready to be processed in a specific profile.
*
* @param sessionID Session ID of the profile to check.
* @param time The time to check ready status against. Current time by default.
* @returns All insured items that are ready to be processed.
*/
protected itemShouldBeLost(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
protected filterInsuredItems(sessionID: string, time?: number): Insurance[];
/**
* This method orchestrates the processing of insured items in a profile.
*
* @param insuranceDetails The insured items to process.
* @param sessionID The session ID that should receive the processed items.
* @returns void
*/
protected processInsuredItems(insuranceDetails: Insurance[], sessionID: string): void;
/**
* Build an array of items to delete from the insured items.
*
* This method orchestrates several steps:
* - Filters items based on their presence in the database and their raid moddability.
* - Sorts base and independent child items to consider for deletion.
* - Groups child items by their parent for later evaluation.
* - Evaluates grouped child items to decide which should be deleted, based on their value and a random roll.
*
* @param insured - The insured items to build a removal array from.
* @returns An array of IDs representing items that should be deleted.
*/
protected findItemsToDelete(insured: Insurance): string[];
/**
* Filters an item based on its existence in the database, raid moddability, and slot requirements.
*
* @param item The item to be filtered.
* @param parentItemDbDetails The database details of the parent item, or null if the item has no parent.
* @param itemDbDetails A tuple where the first element is a boolean indicating if the item exists in the database,
* and the second element is the item details if it does.
* @returns true if the item exists in the database and neither of the following conditions are met:
* - The item has the RaidModdable property set to false.
* - The item is attached to a required slot in its parent item.
* Otherwise, returns false.
*/
protected filterByRaidModdability(item: Item, parentItemDbDetails: ITemplateItem | null, itemDbDetails: [boolean, ITemplateItem]): boolean;
/**
* Determines if an item is either a base item or a child item that is not equipped to its parent.
*
* @param item The item to check.
* @returns true if the item is a base or an independent child item, otherwise false.
*/
protected isBaseOrIndependentChild(item: Item): boolean;
/**
* Makes a roll to determine if a given item should be deleted. If the roll is successful, the item's ID is added
* to the `toDelete` array.
*
* @param item The item for which the roll is made.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array accumulating the IDs of items to be deleted.
* @returns true if the item is marked for deletion, otherwise false.
*/
protected makeRollAndMarkForDeletion(item: Item, traderId: string, toDelete: string[]): boolean;
/**
* Groups child items by their parent IDs in a Map data structure.
*
* @param item The child item to be grouped by its parent.
* @param childrenGroupedByParent The Map that holds arrays of children items grouped by their parent IDs.
* @returns void
*/
protected groupChildrenByParent(item: Item, childrenGroupedByParent: Map<string, Item[]>): void;
/**
* Sorts the array of children items in descending order by their maximum price. For each child, a roll is made to
* determine if it should be deleted. The method then deletes the most valuable children based on the number of
* successful rolls made.
*
* @param children The array of children items to sort and filter.
* @param traderId The ID of the trader to consider in the rollForItemDelete method.
* @param toDelete The array that accumulates the IDs of the items to be deleted.
* @returns void
*/
protected sortAndFilterChildren(children: Item[], traderId: string, toDelete: string[]): void;
/**
* Remove items from the insured items that should not be returned to the player.
*
* @param insured The insured items to process.
* @param toDelete The items that should be deleted.
* @returns void
*/
protected removeItemsFromInsurance(insured: Insurance, toDelete: string[]): void;
/**
* Handle sending the insurance message to the user that potentially contains the valid insurance items.
*
* @param sessionID The session ID that should receive the insurance message.
* @param insurance The context of insurance to use.
* @param noItems Whether or not there are any items to return to the player.
* @returns void
*/
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void;
/**
* Determines whether a valid insured item should be removed from the player's inventory based on a random roll and
* trader-specific return chance.
*
* @param insuredItem The insured item being evaluated for removal.
* @param traderId The ID of the trader who insured the item.
* @param itemsBeingDeleted List of items that are already slated for removal.
* @returns true if the insured item should be removed from inventory, false otherwise.
*/
protected rollForItemDelete(insuredItem: Item, traderId: string, itemsBeingDeleted: string[]): boolean;
/**
* Handle Insure event
* Add insurance to an item
*
* @param pmcData Player profile
* @param body Insurance request
* @param sessionID Session id
@ -62,6 +168,7 @@ export declare class InsuranceController {
/**
* Handle client/insurance/items/list/cost
* Calculate insurance cost
*
* @param request request object
* @param sessionID session id
* @returns IGetInsuranceCostResponseData object to send to client

View File

@ -84,13 +84,13 @@ export declare class InventoryHelper {
* Handle Remove event
* Remove item from player inventory + insured items array
* Also deletes child items
* @param pmcData Profile to remove item from
* @param profile Profile to remove item from (pmc or scav)
* @param itemId Items id to remove
* @param sessionID Session id
* @param output Existing IItemEventRouterResponse object to append data to, creates new one by default if not supplied
* @returns IItemEventRouterResponse
*/
removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): IItemEventRouterResponse;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
getItemSize(itemTpl: string, itemID: string, inventoryItem: Item[]): number[];

View File

@ -56,6 +56,13 @@ declare class ItemHelper {
* @returns Price in roubles
*/
getItemPrice(tpl: string): number;
/**
* Returns the item price based on the handbook or as a fallback from the prices.json if the item is not
* found in the handbook. If the price can't be found at all return 0
* @param tpl Item to look price up of
* @returns Price in roubles
*/
getItemMaxPrice(tpl: string): number;
/**
* Get the static (handbook) price in roubles for an item by tpl
* @param tpl Items tpl id to look up price

View File

@ -115,10 +115,31 @@ export declare class TraderHelper {
* @returns Traders key
*/
getTraderById(traderId: string): Traders;
/**
* Validates that the provided traderEnumValue exists in the Traders enum. If the value is valid, it returns the
* same enum value, effectively serving as a trader ID; otherwise, it logs an error and returns an empty string.
* This method provides a runtime check to prevent undefined behavior when using the enum as a dictionary key.
*
* For example, instead of this:
* `const traderId = Traders[Traders.PRAPOR];`
*
* You can use safely use this:
* `const traderId = this.traderHelper.getValidTraderIdByEnumValue(Traders.PRAPOR);`
*
* @param traderEnumValue The trader enum value to validate
* @returns The validated trader enum value as a string, or an empty string if invalid
*/
getValidTraderIdByEnumValue(traderEnumValue: Traders): string;
/**
* Does the 'Traders' enum has a value that matches the passed in parameter
* @param value Value to check for
* @param key Value to check for
* @returns True, values exists in Traders enum as a value
*/
traderEnumHasValue(value: string): boolean;
traderEnumHasKey(key: string): boolean;
/**
* Accepts a trader id
* @param traderId Trader id
* @returns Ttrue if Traders enum has the param as a value
*/
traderEnumHasValue(traderId: string): boolean;
}

Some files were not shown because too many files have changed in this diff Show More