Fix issie with BuyRestrictionCurrent value persisting between profiles

This commit is contained in:
Dev 2024-01-20 00:19:13 +00:00
parent 4fd37e3a92
commit a1f043d088
3 changed files with 50 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import { RagfairServer } from "@spt-aki/servers/RagfairServer";
import { FenceService } from "@spt-aki/services/FenceService"; import { FenceService } from "@spt-aki/services/FenceService";
import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PaymentService } from "@spt-aki/services/PaymentService"; import { PaymentService } from "@spt-aki/services/PaymentService";
import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil";
@ -44,6 +45,7 @@ export class TradeHelper
@inject("InventoryHelper") protected inventoryHelper: InventoryHelper, @inject("InventoryHelper") protected inventoryHelper: InventoryHelper,
@inject("RagfairServer") protected ragfairServer: RagfairServer, @inject("RagfairServer") protected ragfairServer: RagfairServer,
@inject("TraderAssortHelper") protected traderAssortHelper: TraderAssortHelper, @inject("TraderAssortHelper") protected traderAssortHelper: TraderAssortHelper,
@inject("TraderPurchasePersisterService") protected traderPurchasePersisterService: TraderPurchasePersisterService,
@inject("ConfigServer") protected configServer: ConfigServer, @inject("ConfigServer") protected configServer: ConfigServer,
) )
{ {
@ -84,7 +86,7 @@ export class TradeHelper
const assortHasBuyRestrictions = this.itemHelper.hasBuyRestrictions(itemPurchased); const assortHasBuyRestrictions = this.itemHelper.hasBuyRestrictions(itemPurchased);
if (assortHasBuyRestrictions) if (assortHasBuyRestrictions)
{ {
this.checkPurchaseIsWithinTraderItemLimit(itemPurchased, buyRequestData.item_id, buyCount); this.checkPurchaseIsWithinTraderItemLimit(sessionID, buyRequestData.tid, itemPurchased, buyRequestData.item_id, buyCount);
} }
// Decrement trader item count // Decrement trader item count
@ -153,7 +155,7 @@ export class TradeHelper
const assortHasBuyRestrictions = this.itemHelper.hasBuyRestrictions(itemPurchased); const assortHasBuyRestrictions = this.itemHelper.hasBuyRestrictions(itemPurchased);
if (assortHasBuyRestrictions) if (assortHasBuyRestrictions)
{ {
this.checkPurchaseIsWithinTraderItemLimit(itemPurchased, buyRequestData.item_id, buyCount); this.checkPurchaseIsWithinTraderItemLimit(sessionID, buyRequestData.tid, itemPurchased, buyRequestData.item_id, buyCount);
} }
// Decrement trader item count // Decrement trader item count
@ -291,13 +293,16 @@ export class TradeHelper
/** /**
* Traders allow a limited number of purchases per refresh cycle (default 60 mins) * Traders allow a limited number of purchases per refresh cycle (default 60 mins)
* @param sessionId Session id
* @param traderId Trader assort is purchased from
* @param assortBeingPurchased the item from trader being bought * @param assortBeingPurchased the item from trader being bought
* @param assortId Id of assort being purchased * @param assortId Id of assort being purchased
* @param count How many are being bought * @param count How many of the item are being bought
*/ */
protected checkPurchaseIsWithinTraderItemLimit(assortBeingPurchased: Item, assortId: string, count: number): void protected checkPurchaseIsWithinTraderItemLimit(sessionId: string, traderId: string, assortBeingPurchased: Item, assortId: string, count: number): void
{ {
if ((assortBeingPurchased.upd.BuyRestrictionCurrent + count) > assortBeingPurchased.upd?.BuyRestrictionMax) const traderPurchaseData = this.traderPurchasePersisterService.getProfileTraderPurchase(sessionId, traderId, assortBeingPurchased._id);
if ((traderPurchaseData?.count ?? 0 + count) > assortBeingPurchased.upd?.BuyRestrictionMax)
{ {
throw new Error( throw new Error(
`Unable to purchase ${count} items, this would exceed your purchase limit of ${assortBeingPurchased.upd.BuyRestrictionMax} from the traders assort: ${assortId} this refresh`, `Unable to purchase ${count} items, this would exceed your purchase limit of ${assortBeingPurchased.upd.BuyRestrictionMax} from the traders assort: ${assortId} this refresh`,

View File

@ -83,6 +83,8 @@ export class TraderAssortHelper
trader.assort = this.assortHelper.stripLockedLoyaltyAssort(pmcProfile, traderId, trader.assort); trader.assort = this.assortHelper.stripLockedLoyaltyAssort(pmcProfile, traderId, trader.assort);
} }
this.resetBuyRestrictionCurrentValue(trader.assort.items);
// Append nextResupply value to assorts so client knows when refresh is occuring // Append nextResupply value to assorts so client knows when refresh is occuring
trader.assort.nextResupply = trader.base.nextResupply; trader.assort.nextResupply = trader.base.nextResupply;
@ -139,6 +141,25 @@ export class TraderAssortHelper
return trader.assort; return trader.assort;
} }
/**
* Reset every traders root item `BuyRestrictionCurrent` property to 0
* @param assortItems Items to adjust
*/
protected resetBuyRestrictionCurrentValue(assortItems: Item[]): void
{
// iterate over root items
for (const assort of assortItems.filter(item => item.slotId === "hideout"))
{
// no value to adjust
if (!assort.upd.BuyRestrictionCurrent)
{
continue;
}
assort.upd.BuyRestrictionCurrent = 0;
}
}
/** /**
* Create a dict of all assort id = quest id mappings used to work out what items should be shown to player based on the quests they've started/completed/failed * Create a dict of all assort id = quest id mappings used to work out what items should be shown to player based on the quests they've started/completed/failed
*/ */

View File

@ -46,6 +46,25 @@ export class TraderPurchasePersisterService
return profile.traderPurchases[traderId]; return profile.traderPurchases[traderId];
} }
/**
* Get a purchase made from a trader for requested profile before the last trader reset
* @param sessionId Session id
* @param traderId Trader to loop up purchases for
* @param assortId Id of assort to get data for
* @returns TraderPurchaseData
*/
public getProfileTraderPurchase(sessionId: string, traderId: string, assortId: string): TraderPurchaseData
{
const profile = this.profileHelper.getFullProfile(sessionId);
if (!profile.traderPurchases)
{
return null;
}
return profile.traderPurchases[traderId][assortId];
}
/** /**
* Remove all trader purchase records from all profiles that exist * Remove all trader purchase records from all profiles that exist
* @param traderId Traders id * @param traderId Traders id