6cd86e67b0
# Conflicts: # project/.vscode/launch.json # project/assets/database/locations/bigmap/base.json # project/assets/database/locations/interchange/base.json # project/assets/database/locations/rezervbase/base.json # project/gulpfile.mjs # project/package.json # project/src/ErrorHandler.ts # project/src/Program.ts # project/src/callbacks/DataCallbacks.ts # project/src/callbacks/DialogueCallbacks.ts # project/src/callbacks/GameCallbacks.ts # project/src/callbacks/HandbookCallbacks.ts # project/src/callbacks/HealthCallbacks.ts # project/src/callbacks/HttpCallbacks.ts # project/src/callbacks/LauncherCallbacks.ts # project/src/callbacks/LocationCallbacks.ts # project/src/callbacks/MatchCallbacks.ts # project/src/callbacks/ModCallbacks.ts # project/src/callbacks/NotifierCallbacks.ts # project/src/callbacks/PresetCallbacks.ts # project/src/callbacks/ProfileCallbacks.ts # project/src/callbacks/RagfairCallbacks.ts # project/src/callbacks/TraderCallbacks.ts # project/src/context/ApplicationContext.ts # project/src/context/ContextVariableType.ts # project/src/controllers/BotController.ts # project/src/controllers/CustomizationController.ts # project/src/controllers/DialogueController.ts # project/src/controllers/GameController.ts # project/src/controllers/HealthController.ts # project/src/controllers/HideoutController.ts # project/src/controllers/InraidController.ts # project/src/controllers/InsuranceController.ts # project/src/controllers/InventoryController.ts # project/src/controllers/LauncherController.ts # project/src/controllers/LocationController.ts # project/src/controllers/MatchController.ts # project/src/controllers/QuestController.ts # project/src/controllers/RagfairController.ts # project/src/controllers/RepeatableQuestController.ts # project/src/controllers/TradeController.ts # project/src/di/Container.ts # project/src/di/Router.ts # project/src/generators/BotEquipmentModGenerator.ts # project/src/generators/BotLevelGenerator.ts # project/src/generators/BotWeaponGenerator.ts # project/src/generators/LocationGenerator.ts # project/src/generators/LootGenerator.ts # project/src/generators/RepeatableQuestGenerator.ts # project/src/generators/WeatherGenerator.ts # project/src/generators/weapongen/InventoryMagGen.ts # project/src/generators/weapongen/implementations/BarrelInventoryMagGen.ts # project/src/generators/weapongen/implementations/ExternalInventoryMagGen.ts # project/src/helpers/AssortHelper.ts # project/src/helpers/BotGeneratorHelper.ts # project/src/helpers/InRaidHelper.ts # project/src/helpers/ProfileHelper.ts # project/src/helpers/RagfairHelper.ts # project/src/helpers/RagfairOfferHelper.ts # project/src/helpers/TraderHelper.ts # project/src/loaders/ModLoadOrder.ts # project/src/loaders/PostDBModLoader.ts # project/src/loaders/PreAkiModLoader.ts # project/src/models/eft/common/IGlobals.ts # project/src/models/eft/common/ILocationBase.ts # project/src/models/eft/common/tables/IBotBase.ts # project/src/models/eft/common/tables/IProfileTemplate.ts # project/src/models/eft/common/tables/ITemplateItem.ts # project/src/models/eft/dialog/IAcceptFriendRequestData.ts # project/src/models/eft/dialog/IDeleteFriendRequest.ts # project/src/models/eft/game/IGameConfigResponse.ts # project/src/models/eft/game/IGameKeepAliveResponse.ts # project/src/models/eft/game/IGameStartResponse.ts # project/src/models/eft/match/IJoinMatchResult.ts # project/src/models/eft/notifier/INotifier.ts # project/src/models/eft/profile/GetProfileStatusResponseData.ts # project/src/models/eft/trade/IProcessBuyTradeRequestData.ts # project/src/models/eft/trade/IProcessSellTradeRequestData.ts # project/src/models/enums/WildSpawnTypeNumber.ts # project/src/models/spt/bots/BotGenerationDetails.ts # project/src/models/spt/config/IBotConfig.ts # project/src/models/spt/config/IBotDurability.ts # project/src/models/spt/config/IInRaidConfig.ts # project/src/models/spt/config/ILocationConfig.ts # project/src/models/spt/config/IQuestConfig.ts # project/src/models/spt/config/ISeasonalEventConfig.ts # project/src/models/spt/server/ILocations.ts # project/src/models/spt/utils/IUuidGenerator.ts # project/src/routers/dynamic/BotDynamicRouter.ts # project/src/routers/dynamic/BundleDynamicRouter.ts # project/src/routers/dynamic/CustomizationDynamicRouter.ts # project/src/routers/dynamic/DataDynamicRouter.ts # project/src/routers/dynamic/HttpDynamicRouter.ts # project/src/routers/dynamic/InraidDynamicRouter.ts # project/src/routers/dynamic/LocationDynamicRouter.ts # project/src/routers/dynamic/NotifierDynamicRouter.ts # project/src/routers/dynamic/TraderDynamicRouter.ts # project/src/routers/save_load/InsuranceSaveLoadRouter.ts # project/src/routers/save_load/ProfileSaveLoadRouter.ts # project/src/routers/serializers/NotifySerializer.ts # project/src/routers/static/BotStaticRouter.ts # project/src/routers/static/BundleStaticRouter.ts # project/src/routers/static/ClientLogStaticRouter.ts # project/src/routers/static/CustomizationStaticRouter.ts # project/src/routers/static/DataStaticRouter.ts # project/src/routers/static/DialogStaticRouter.ts # project/src/routers/static/GameStaticRouter.ts # project/src/routers/static/HealthStaticRouter.ts # project/src/routers/static/InraidStaticRouter.ts # project/src/routers/static/InsuranceStaticRouter.ts # project/src/routers/static/ItemEventStaticRouter.ts # project/src/routers/static/LauncherStaticRouter.ts # project/src/routers/static/LocationStaticRouter.ts # project/src/routers/static/MatchStaticRouter.ts # project/src/routers/static/NotifierStaticRouter.ts # project/src/routers/static/PresetStaticRouter.ts # project/src/routers/static/ProfileStaticRouter.ts # project/src/routers/static/QuestStaticRouter.ts # project/src/routers/static/RagfairStaticRouter.ts # project/src/routers/static/TraderStaticRouter.ts # project/src/routers/static/WeatherStaticRouter.ts # project/src/services/BotEquipmentFilterService.ts # project/src/services/BotGenerationCacheService.ts # project/src/services/BotWeaponModLimitService.ts # project/src/services/PaymentService.ts # project/src/services/ProfileFixerService.ts # project/src/services/RagfairOfferService.ts # project/src/services/RagfairTaxService.ts # project/src/services/RepairService.ts # project/src/services/SeasonalEventService.ts # project/src/utils/RagfairOfferHolder.ts # project/src/utils/TimeUtil.ts # project/src/utils/UUidGenerator.ts # project/src/utils/VFS.ts # project/src/utils/collections/queue/Queue.ts # project/src/utils/logging/AbstractWinstonLogger.ts # project/src/utils/logging/WinstonMainLogger.ts # project/src/utils/logging/WinstonRequestLogger.ts # project/tests/utils/TimeUtil.test.ts Manually resolved by Refringe.
266 lines
9.2 KiB
TypeScript
266 lines
9.2 KiB
TypeScript
import { inject, injectable } from "tsyringe";
|
|
|
|
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
|
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
|
|
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
|
|
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
|
import { IRagfairOffer } from "@spt-aki/models/eft/ragfair/IRagfairOffer";
|
|
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
|
import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
|
|
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
|
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
|
|
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
|
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
|
import { SaveServer } from "@spt-aki/servers/SaveServer";
|
|
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
|
import { RagfairCategoriesService } from "@spt-aki/services/RagfairCategoriesService";
|
|
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
|
import { RagfairOfferHolder } from "@spt-aki/utils/RagfairOfferHolder";
|
|
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
|
|
|
@injectable()
|
|
export class RagfairOfferService
|
|
{
|
|
protected playerOffersLoaded = false;
|
|
protected expiredOffers: Record<string, IRagfairOffer> = {};
|
|
|
|
protected ragfairConfig: IRagfairConfig;
|
|
protected ragfairOfferHandler: RagfairOfferHolder = new RagfairOfferHolder();
|
|
|
|
constructor(
|
|
@inject("WinstonLogger") protected logger: ILogger,
|
|
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
|
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
|
@inject("SaveServer") protected saveServer: SaveServer,
|
|
@inject("RagfairServerHelper") protected ragfairServerHelper: RagfairServerHelper,
|
|
@inject("RagfairCategoriesService") protected ragfairCategoriesService: RagfairCategoriesService,
|
|
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
@inject("EventOutputHolder") protected eventOutputHolder: EventOutputHolder,
|
|
@inject("HttpResponseUtil") protected httpResponse: HttpResponseUtil,
|
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
)
|
|
{
|
|
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
|
}
|
|
|
|
/**
|
|
* Get all offers
|
|
* @returns IRagfairOffer array
|
|
*/
|
|
public getOffers(): IRagfairOffer[]
|
|
{
|
|
return this.ragfairOfferHandler.getOffers();
|
|
}
|
|
|
|
public getOfferByOfferId(offerId: string): IRagfairOffer
|
|
{
|
|
return this.ragfairOfferHandler.getOfferById(offerId);
|
|
}
|
|
|
|
public getOffersOfType(templateId: string): IRagfairOffer[]
|
|
{
|
|
return this.ragfairOfferHandler.getOffersByTemplate(templateId);
|
|
}
|
|
|
|
public addOffer(offer: IRagfairOffer): void
|
|
{
|
|
this.ragfairOfferHandler.addOffer(offer);
|
|
}
|
|
|
|
public addOfferToExpired(staleOffer: IRagfairOffer): void
|
|
{
|
|
this.expiredOffers[staleOffer._id] = staleOffer;
|
|
}
|
|
|
|
public getExpiredOfferCount(): number
|
|
{
|
|
return Object.keys(this.expiredOffers).length;
|
|
}
|
|
|
|
/**
|
|
* Get an array of expired items not yet processed into new offers
|
|
* @returns items that need to be turned into offers
|
|
*/
|
|
public getExpiredOfferItems(): Item[]
|
|
{
|
|
const expiredItems: Item[] = [];
|
|
|
|
for (const expiredOfferId in this.expiredOffers)
|
|
{
|
|
expiredItems.push(this.expiredOffers[expiredOfferId].items[0]);
|
|
}
|
|
|
|
return expiredItems;
|
|
}
|
|
|
|
public resetExpiredOffers(): void
|
|
{
|
|
this.expiredOffers = {};
|
|
}
|
|
|
|
/**
|
|
* Does the offer exist on the ragfair
|
|
* @param offerId offer id to check for
|
|
* @returns offer exists - true
|
|
*/
|
|
public doesOfferExist(offerId: string): boolean
|
|
{
|
|
return this.ragfairOfferHandler.getOfferById(offerId) !== undefined;
|
|
}
|
|
|
|
/**
|
|
* Remove an offer from ragfair by offer id
|
|
* @param offerId Offer id to remove
|
|
*/
|
|
public removeOfferById(offerId: string): void
|
|
{
|
|
const offer = this.ragfairOfferHandler.getOfferById(offerId);
|
|
if (!offer)
|
|
{
|
|
this.logger.warning(
|
|
this.localisationService.getText("ragfair-unable_to_remove_offer_doesnt_exist", offerId),
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
this.ragfairOfferHandler.removeOffer(offer);
|
|
}
|
|
|
|
/**
|
|
* Reduce size of an offer stack by specified amount
|
|
* @param offerId Offer to adjust stack size of
|
|
* @param amount How much to deduct from offers stack size
|
|
*/
|
|
public removeOfferStack(offerId: string, amount: number): void
|
|
{
|
|
const offer = this.ragfairOfferHandler.getOfferById(offerId);
|
|
offer.items[0].upd.StackObjectsCount -= amount;
|
|
if (offer.items[0].upd.StackObjectsCount <= 0)
|
|
{
|
|
this.processStaleOffer(offer);
|
|
}
|
|
}
|
|
|
|
public removeAllOffersByTrader(traderId: string): void
|
|
{
|
|
this.ragfairOfferHandler.removeOfferByTrader(traderId);
|
|
}
|
|
|
|
/**
|
|
* Do the trader offers on flea need to be refreshed
|
|
* @param traderID Trader to check
|
|
* @returns true if they do
|
|
*/
|
|
public traderOffersNeedRefreshing(traderID: string): boolean
|
|
{
|
|
const trader = this.databaseServer.getTables().traders[traderID];
|
|
|
|
// No value, occurs when first run, trader offers need to be added to flea
|
|
if (typeof trader.base.refreshTraderRagfairOffers !== "boolean")
|
|
{
|
|
trader.base.refreshTraderRagfairOffers = true;
|
|
}
|
|
|
|
return trader.base.refreshTraderRagfairOffers;
|
|
}
|
|
|
|
public addPlayerOffers(): void
|
|
{
|
|
if (!this.playerOffersLoaded)
|
|
{
|
|
for (const sessionID in this.saveServer.getProfiles())
|
|
{
|
|
const pmcData = this.saveServer.getProfile(sessionID).characters.pmc;
|
|
|
|
if (pmcData.RagfairInfo === undefined || pmcData.RagfairInfo.offers === undefined)
|
|
{
|
|
// Profile is wiped
|
|
continue;
|
|
}
|
|
|
|
this.ragfairOfferHandler.addOffers(pmcData.RagfairInfo.offers);
|
|
}
|
|
this.playerOffersLoaded = true;
|
|
}
|
|
}
|
|
|
|
public expireStaleOffers(): void
|
|
{
|
|
const time = this.timeUtil.getTimestamp();
|
|
for (const staleOffer of this.ragfairOfferHandler.getStaleOffers(time))
|
|
{
|
|
this.processStaleOffer(staleOffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove stale offer from flea
|
|
* @param staleOffer Stale offer to process
|
|
*/
|
|
protected processStaleOffer(staleOffer: IRagfairOffer): void
|
|
{
|
|
const staleOfferUserId = staleOffer.user.id;
|
|
const isTrader = this.ragfairServerHelper.isTrader(staleOfferUserId);
|
|
const isPlayer = this.ragfairServerHelper.isPlayer(staleOfferUserId.replace(/^pmc/, ""));
|
|
|
|
// Skip trader offers, managed by RagfairServer.update()
|
|
if (isTrader)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Handle dynamic offer
|
|
if (!(isTrader || isPlayer))
|
|
{
|
|
// Dynamic offer
|
|
this.addOfferToExpired(staleOffer);
|
|
}
|
|
|
|
// Handle player offer - items need returning/XP adjusting. Checking if offer has actually expired or not.
|
|
if (isPlayer && staleOffer.endTime <= this.timeUtil.getTimestamp())
|
|
{
|
|
// TODO: something feels wrong, func returns ItemEventRouterResponse but we dont pass it back to caller?
|
|
this.returnPlayerOffer(staleOffer);
|
|
}
|
|
|
|
// Reduce category count by 1 as offer is now stale and about to be removed
|
|
this.ragfairCategoriesService.decrementCategory(staleOffer);
|
|
|
|
// Remove expired existing offer from global offers
|
|
this.removeOfferById(staleOffer._id);
|
|
}
|
|
|
|
protected returnPlayerOffer(offer: IRagfairOffer): IItemEventRouterResponse
|
|
{
|
|
const pmcID = String(offer.user.id);
|
|
const profile = this.profileHelper.getProfileByPmcId(pmcID);
|
|
const sessionID = profile.sessionId;
|
|
const offerIndex = profile.RagfairInfo.offers.findIndex((o) => o._id === offer._id);
|
|
|
|
if (offerIndex === -1)
|
|
{
|
|
this.logger.warning(this.localisationService.getText("ragfair-unable_to_find_offer_to_remove", offer._id));
|
|
return this.httpResponse.appendErrorToOutput(
|
|
this.eventOutputHolder.getOutput(sessionID),
|
|
this.localisationService.getText("ragfair-offer_not_found_in_profile_short"),
|
|
);
|
|
}
|
|
|
|
profile.RagfairInfo.rating -= this.ragfairConfig.sell.reputation.loss;
|
|
profile.RagfairInfo.isRatingGrowing = false;
|
|
|
|
if (offer.items[0].upd.StackObjectsCount > offer.items[0].upd.OriginalStackObjectsCount)
|
|
{
|
|
offer.items[0].upd.StackObjectsCount = offer.items[0].upd.OriginalStackObjectsCount;
|
|
}
|
|
delete offer.items[0].upd.OriginalStackObjectsCount;
|
|
|
|
this.ragfairServerHelper.returnItems(profile.sessionId, offer.items);
|
|
profile.RagfairInfo.offers.splice(offerIndex, 1);
|
|
|
|
return this.eventOutputHolder.getOutput(sessionID);
|
|
}
|
|
}
|