Refactored flea purchase code
This commit is contained in:
parent
4d1066b51a
commit
818bb7e37a
@ -8,9 +8,10 @@ import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
|||||||
import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem";
|
import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem";
|
||||||
import { ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
|
import { ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
|
||||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||||
|
import { IRagfairOffer } from "@spt-aki/models/eft/ragfair/IRagfairOffer";
|
||||||
import { IProcessBaseTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBaseTradeRequestData";
|
import { IProcessBaseTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBaseTradeRequestData";
|
||||||
import { IProcessBuyTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBuyTradeRequestData";
|
import { IProcessBuyTradeRequestData } from "@spt-aki/models/eft/trade/IProcessBuyTradeRequestData";
|
||||||
import { IProcessRagfairTradeRequestData } from "@spt-aki/models/eft/trade/IProcessRagfairTradeRequestData";
|
import { IOfferRequest, IProcessRagfairTradeRequestData } from "@spt-aki/models/eft/trade/IProcessRagfairTradeRequestData";
|
||||||
import { IProcessSellTradeRequestData } from "@spt-aki/models/eft/trade/IProcessSellTradeRequestData";
|
import { IProcessSellTradeRequestData } from "@spt-aki/models/eft/trade/IProcessSellTradeRequestData";
|
||||||
import { ISellScavItemsToFenceRequestData } from "@spt-aki/models/eft/trade/ISellScavItemsToFenceRequestData";
|
import { ISellScavItemsToFenceRequestData } from "@spt-aki/models/eft/trade/ISellScavItemsToFenceRequestData";
|
||||||
import { BackendErrorCodes } from "@spt-aki/models/enums/BackendErrorCodes";
|
import { BackendErrorCodes } from "@spt-aki/models/enums/BackendErrorCodes";
|
||||||
@ -60,19 +61,39 @@ export class TradeController
|
|||||||
sessionID: string,
|
sessionID: string,
|
||||||
): IItemEventRouterResponse
|
): IItemEventRouterResponse
|
||||||
{
|
{
|
||||||
return this.confirmTradingInternal(pmcData, request, sessionID, this.traderConfig.purchasesAreFoundInRaid);
|
const output = this.eventOutputHolder.getOutput(sessionID);
|
||||||
|
|
||||||
|
// Buying
|
||||||
|
if (request.type === "buy_from_trader")
|
||||||
|
{
|
||||||
|
const foundInRaid = this.traderConfig.purchasesAreFoundInRaid;
|
||||||
|
const buyData = <IProcessBuyTradeRequestData>request;
|
||||||
|
return this.tradeHelper.buyItem(pmcData, buyData, sessionID, foundInRaid, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selling
|
||||||
|
if (request.type === "sell_to_trader")
|
||||||
|
{
|
||||||
|
const sellData = <IProcessSellTradeRequestData>request;
|
||||||
|
return this.tradeHelper.sellItem(pmcData, pmcData, sellData, sessionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorMessage = `Unhandled trade event: ${request.type}`;
|
||||||
|
this.logger.error(errorMessage);
|
||||||
|
|
||||||
|
return this.httpResponse.appendErrorToOutput(output, errorMessage, BackendErrorCodes.RAGFAIRUNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handle RagFairBuyOffer event */
|
/** Handle RagFairBuyOffer event */
|
||||||
public confirmRagfairTrading(
|
public confirmRagfairTrading(
|
||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
body: IProcessRagfairTradeRequestData,
|
request: IProcessRagfairTradeRequestData,
|
||||||
sessionID: string,
|
sessionID: string,
|
||||||
): IItemEventRouterResponse
|
): IItemEventRouterResponse
|
||||||
{
|
{
|
||||||
let output = this.eventOutputHolder.getOutput(sessionID);
|
const output = this.eventOutputHolder.getOutput(sessionID);
|
||||||
|
|
||||||
for (const offer of body.offers)
|
for (const offer of request.offers)
|
||||||
{
|
{
|
||||||
const fleaOffer = this.ragfairServer.getOffer(offer.id);
|
const fleaOffer = this.ragfairServer.getOffer(offer.id);
|
||||||
if (!fleaOffer)
|
if (!fleaOffer)
|
||||||
@ -94,59 +115,110 @@ export class TradeController
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sellerIsTrader = fleaOffer.user.memberType === MemberCategory.TRADER;
|
const sellerIsTrader = fleaOffer.user.memberType === MemberCategory.TRADER;
|
||||||
|
if (sellerIsTrader)
|
||||||
// Skip buying items when player doesn't have needed loyalty
|
|
||||||
if (sellerIsTrader && fleaOffer.loyaltyLevel > pmcData.TradersInfo[fleaOffer.user.id].loyaltyLevel)
|
|
||||||
{
|
{
|
||||||
this.logger.debug(
|
this.buyTraderItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
|
||||||
`Unable to buy item: ${
|
}
|
||||||
fleaOffer.items[0]._tpl
|
else
|
||||||
} from trader: ${fleaOffer.user.id} as loyalty level too low, skipping`,
|
{
|
||||||
);
|
this.buyPmcItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log full purchase JSON
|
// Exit loop early if problem found
|
||||||
this.logger.debug(this.jsonUtil.serializeAdvanced(offer, null, 2));
|
if (output.warnings)
|
||||||
|
|
||||||
const buyData: IProcessBuyTradeRequestData = {
|
|
||||||
Action: "TradingConfirm",
|
|
||||||
type: "buy_from_trader",
|
|
||||||
tid: (sellerIsTrader) ? fleaOffer.user.id : "ragfair",
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
item_id: (sellerIsTrader) ? fleaOffer.root : fleaOffer._id, // Store ragfair offerId in buyRequestData.item_id
|
|
||||||
count: offer.count,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
scheme_id: 0,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
scheme_items: offer.items,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Trader / PMC offers use different found in raid config values
|
|
||||||
const purchasedItemFoundInRaid = (sellerIsTrader)
|
|
||||||
? this.traderConfig.purchasesAreFoundInRaid
|
|
||||||
: this.ragfairConfig.dynamic.purchasesAreFoundInRaid;
|
|
||||||
|
|
||||||
// confirmTrading() must occur prior to removing the offer stack, otherwise item inside offer doesn't exist for confirmTrading() to use
|
|
||||||
output = this.confirmTradingInternal(
|
|
||||||
pmcData,
|
|
||||||
buyData,
|
|
||||||
sessionID,
|
|
||||||
purchasedItemFoundInRaid,
|
|
||||||
fleaOffer.items[0].upd,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!sellerIsTrader)
|
|
||||||
{
|
{
|
||||||
// Remove the item purchased from flea offer
|
return output;
|
||||||
this.ragfairServer.removeOfferStack(fleaOffer._id, offer.count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buy an item off the flea sold by a trader
|
||||||
|
* @param sessionId Session id
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @param fleaOffer Offer being purchased
|
||||||
|
* @param requestOffer request data from client
|
||||||
|
* @param output Output to send back to client
|
||||||
|
* @returns IItemEventRouterResponse
|
||||||
|
*/
|
||||||
|
protected buyTraderItemFromRagfair(sessionId: string, pmcData: IPmcData, fleaOffer: IRagfairOffer, requestOffer: IOfferRequest, output: IItemEventRouterResponse): IItemEventRouterResponse
|
||||||
|
{
|
||||||
|
// Skip buying items when player doesn't have needed loyalty
|
||||||
|
if (this.playerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer, pmcData))
|
||||||
|
{
|
||||||
|
const errorMessage = `Unable to buy item: ${
|
||||||
|
fleaOffer.items[0]._tpl
|
||||||
|
} from trader: ${fleaOffer.user.id} as loyalty level too low, skipping`
|
||||||
|
this.logger.debug(errorMessage);
|
||||||
|
|
||||||
|
return this.httpResponse.appendErrorToOutput(output, errorMessage, BackendErrorCodes.RAGFAIRUNAVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const buyData: IProcessBuyTradeRequestData = {
|
||||||
|
Action: "TradingConfirm",
|
||||||
|
type: "buy_from_ragfair",
|
||||||
|
tid: fleaOffer.user.id,
|
||||||
|
item_id: fleaOffer.root,
|
||||||
|
count: requestOffer.count,
|
||||||
|
scheme_id: 0,
|
||||||
|
scheme_items: requestOffer.items,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tradeHelper.buyItem(pmcData, buyData, sessionId, this.traderConfig.purchasesAreFoundInRaid, output);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buy an item off the flea sold by a PMC
|
||||||
|
* @param sessionId Session id
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @param fleaOffer Offer being purchased
|
||||||
|
* @param requestOffer Request data from client
|
||||||
|
* @param output Output to send back to client
|
||||||
|
*/
|
||||||
|
protected buyPmcItemFromRagfair(sessionId: string, pmcData: IPmcData, fleaOffer: IRagfairOffer, requestOffer: IOfferRequest, output: IItemEventRouterResponse): IItemEventRouterResponse
|
||||||
|
{
|
||||||
|
const buyData: IProcessBuyTradeRequestData = {
|
||||||
|
Action: "TradingConfirm",
|
||||||
|
type: "buy_from_ragfair",
|
||||||
|
tid: "ragfair",
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
item_id: fleaOffer._id, // Store ragfair offerId in buyRequestData.item_id
|
||||||
|
count: requestOffer.count,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
scheme_id: 0,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
scheme_items: requestOffer.items,
|
||||||
|
};
|
||||||
|
|
||||||
|
// buyItem() must occur prior to removing the offer stack, otherwise item inside offer doesn't exist for confirmTrading() to use
|
||||||
|
this.tradeHelper.buyItem(pmcData, buyData, sessionId, this.ragfairConfig.dynamic.purchasesAreFoundInRaid, output);
|
||||||
|
if (output.warnings.length > 0)
|
||||||
|
{
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove/lower stack count of item purchased from flea offer
|
||||||
|
this.ragfairServer.removeOfferStack(fleaOffer._id, requestOffer.count);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does Player have necessary trader loyalty to purchase flea offer
|
||||||
|
* @param sellerIsTrader is seller trader
|
||||||
|
* @param fleaOffer FLea offer being bought
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @returns True if player can buy offer
|
||||||
|
*/
|
||||||
|
protected playerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer: IRagfairOffer, pmcData: IPmcData): boolean
|
||||||
|
{
|
||||||
|
return fleaOffer.loyaltyLevel > pmcData.TradersInfo[fleaOffer.user.id].loyaltyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
/** Handle SellAllFromSavage event */
|
/** Handle SellAllFromSavage event */
|
||||||
public sellScavItemsToFence(
|
public sellScavItemsToFence(
|
||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
@ -258,30 +330,4 @@ export class TradeController
|
|||||||
|
|
||||||
return totalPrice;
|
return totalPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Buy item */
|
|
||||||
protected confirmTradingInternal(
|
|
||||||
pmcData: IPmcData,
|
|
||||||
body: IProcessBaseTradeRequestData,
|
|
||||||
sessionID: string,
|
|
||||||
foundInRaid = false,
|
|
||||||
upd: Upd = null,
|
|
||||||
): IItemEventRouterResponse
|
|
||||||
{
|
|
||||||
// buying
|
|
||||||
if (body.type === "buy_from_trader")
|
|
||||||
{
|
|
||||||
const buyData = <IProcessBuyTradeRequestData>body;
|
|
||||||
return this.tradeHelper.buyItem(pmcData, buyData, sessionID, foundInRaid, upd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// selling
|
|
||||||
if (body.type === "sell_to_trader")
|
|
||||||
{
|
|
||||||
const sellData = <IProcessSellTradeRequestData>body;
|
|
||||||
return this.tradeHelper.sellItem(pmcData, pmcData, sellData, sessionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -56,19 +56,17 @@ export class TradeHelper
|
|||||||
* @param buyRequestData data from client
|
* @param buyRequestData data from client
|
||||||
* @param sessionID Session id
|
* @param sessionID Session id
|
||||||
* @param foundInRaid Should item be found in raid
|
* @param foundInRaid Should item be found in raid
|
||||||
* @param upd optional item details used when buying from flea
|
* @param output IItemEventRouterResponse
|
||||||
* @returns
|
* @returns IItemEventRouterResponse
|
||||||
*/
|
*/
|
||||||
public buyItem(
|
public buyItem(
|
||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
buyRequestData: IProcessBuyTradeRequestData,
|
buyRequestData: IProcessBuyTradeRequestData,
|
||||||
sessionID: string,
|
sessionID: string,
|
||||||
foundInRaid: boolean,
|
foundInRaid: boolean,
|
||||||
upd: Upd,
|
output: IItemEventRouterResponse,
|
||||||
): IItemEventRouterResponse
|
): IItemEventRouterResponse
|
||||||
{
|
{
|
||||||
let output = this.eventOutputHolder.getOutput(sessionID);
|
|
||||||
|
|
||||||
let offerItems: Item[] = [];
|
let offerItems: Item[] = [];
|
||||||
let buyCallback: { (buyCount: number) };
|
let buyCallback: { (buyCount: number) };
|
||||||
if (buyRequestData.tid.toLocaleLowerCase() === "ragfair")
|
if (buyRequestData.tid.toLocaleLowerCase() === "ragfair")
|
||||||
@ -102,10 +100,12 @@ export class TradeHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pay for item
|
/// Pay for item
|
||||||
output = this.paymentService.payMoney(pmcData, buyRequestData, sessionID, output);
|
this.paymentService.payMoney(pmcData, buyRequestData, sessionID, output);
|
||||||
if (output.warnings.length > 0)
|
if (output.warnings.length > 0)
|
||||||
{
|
{
|
||||||
throw new Error(`Transaction failed: ${output.warnings[0].errmsg}`);
|
this.logger.error(`Flea transaction failed: ${output.warnings[0].errmsg}`);
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assortHasBuyRestrictions)
|
if (assortHasBuyRestrictions)
|
||||||
@ -223,7 +223,7 @@ export class TradeHelper
|
|||||||
// Construct request
|
// Construct request
|
||||||
const request: IAddItemDirectRequest = {
|
const request: IAddItemDirectRequest = {
|
||||||
itemWithModsToAdd: this.itemHelper.reparentItemAndChildren(offerItems[0], offerItems),
|
itemWithModsToAdd: this.itemHelper.reparentItemAndChildren(offerItems[0], offerItems),
|
||||||
foundInRaid: this.inventoryConfig.newItemsMarkedFound,
|
foundInRaid: foundInRaid,
|
||||||
callback: buyCallback,
|
callback: buyCallback,
|
||||||
useSortingTable: true
|
useSortingTable: true
|
||||||
};
|
};
|
||||||
@ -238,7 +238,6 @@ export class TradeHelper
|
|||||||
itemsToSendRemaining -= itemCountToSend;
|
itemsToSendRemaining -= itemCountToSend;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - handle traders
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
export interface IProcessRagfairTradeRequestData
|
export interface IProcessRagfairTradeRequestData
|
||||||
{
|
{
|
||||||
Action: string;
|
Action: string;
|
||||||
offers: Offer[];
|
offers: IOfferRequest[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Offer
|
export interface IOfferRequest
|
||||||
{
|
{
|
||||||
id: string;
|
id: string;
|
||||||
count: number;
|
count: number;
|
||||||
items: Item[];
|
items: IItemReqeust[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Item
|
export interface IItemReqeust
|
||||||
{
|
{
|
||||||
id: string;
|
id: string;
|
||||||
count: number;
|
count: number;
|
||||||
|
Loading…
Reference in New Issue
Block a user