Files
SPT-Server-Build/Libraries/Core/Controllers/TradeController.cs
T

262 lines
8.7 KiB
C#

using SptCommon.Annotations;
using Core.Helpers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.ItemEvent;
using Core.Models.Eft.Ragfair;
using Core.Models.Eft.Trade;
using Core.Models.Enums;
using Core.Models.Spt.Config;
using Core.Models.Utils;
using Core.Routers;
using Core.Servers;
using Core.Services;
using Core.Utils;
namespace Core.Controllers;
[Injectable]
public class TradeController(
ISptLogger<TradeController> _logger,
DatabaseService _databaseService,
EventOutputHolder _eventOutputHolder,
TradeHelper _tradeHelper,
TimeUtil _timeUtil,
HashUtil _hashUtil,
ItemHelper _itemHelper,
ProfileHelper _profileHelper,
RagfairOfferHelper _ragfairOfferHelper,
TraderHelper _traderHelper,
RagfairServer _ragfairServer,
HttpResponseUtil _httpResponseUtil,
LocalisationService _localisationService,
RagfairPriceService _ragfairPriceService,
ConfigServer _configServer
)
{
protected RagfairConfig _ragfairConfig = _configServer.GetConfig<RagfairConfig>();
protected TraderConfig _traderConfig = _configServer.GetConfig<TraderConfig>();
/// <summary>
/// Handle TradingConfirm event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="request"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse ConfirmTrading(
PmcData pmcData,
ProcessBaseTradeRequestData request,
string sessionID)
{
var output = _eventOutputHolder.GetOutput(sessionID);
// Buying
if (request.Type == "buy_from_trader")
{
var foundInRaid = _traderConfig.PurchasesAreFoundInRaid;
ProcessBuyTradeRequestData buyData = (ProcessBuyTradeRequestData)request;
_tradeHelper.buyItem(pmcData, buyData, sessionID, foundInRaid, output);
return output;
}
// Selling
if (request.Type == "sell_to_trader")
{
ProcessSellTradeRequestData sellData = (ProcessSellTradeRequestData)request;
_tradeHelper.sellItem(pmcData, pmcData, sellData, sessionID, output);
return output;
}
var errorMessage = $"Unhandled trade event: {request.Type}";
_logger.Error(errorMessage);
return _httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.RagfairUnavailable);
}
/// <summary>
/// Handle RagFairBuyOffer event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="request"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse ConfirmRagfairTrading(
PmcData pmcData,
ProcessRagfairTradeRequestData request,
string sessionID)
{
var output = _eventOutputHolder.GetOutput(sessionID);
foreach (var offer in request.Offers)
{
var fleaOffer = _ragfairServer.GetOffer(offer.Id);
if (fleaOffer is null)
{
return _httpResponseUtil.AppendErrorToOutput(
output,
$"Offer with ID {offer.Id} not found",
BackendErrorCodes.OfferNotFound
);
}
if (offer.Count == 0)
{
var errorMessage = _localisationService.GetText(
"ragfair-unable_to_purchase_0_count_item",
_itemHelper.GetItem(fleaOffer.Items[0].Template).Value.Name
);
return _httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.OfferOutOfStock);
}
if (_ragfairOfferHelper.OfferIsFromTrader(fleaOffer))
{
BuyTraderItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
}
else
{
BuyPmcItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output);
}
// Exit loop early if problem found
if (output.Warnings.Count > 0)
{
return output;
}
}
return output;
}
/// <summary>
/// Buy an item off the flea sold by a trader
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Player profile</param>
/// <param name="fleaOffer">Offer being purchased</param>
/// <param name="offerRequest">request data from client</param>
/// <param name="output">Output to send back to client</param>
private void BuyTraderItemFromRagfair(
string sessionId,
PmcData pmcData,
RagfairOffer fleaOffer,
OfferRequest requestOffer,
ItemEventRouterResponse output)
{
// Skip buying items when player doesn't have needed loyalty
if (PlayerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer, pmcData)) {
var errorMessage = $"Unable to buy item: {fleaOffer.Items[0].Template} from trader: {fleaOffer.User.Id} as loyalty level too low, skipping";
_logger.Debug(errorMessage);
_httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.RagfairUnavailable);
return;
}
ProcessBuyTradeRequestData buyData = new ProcessBuyTradeRequestData {
Action = "TradingConfirm",
Type = "buy_from_ragfair",
TransactionId = fleaOffer.User.Id,
ItemId = fleaOffer.Root,
Count = requestOffer.Count,
SchemeId = 0,
SchemeItems = requestOffer.Items,
};
_tradeHelper.buyItem(pmcData, buyData, sessionId, _traderConfig.PurchasesAreFoundInRaid, output);
}
/// <summary>
/// Buy an item off the flea sold by a PMC
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcData">Player profile</param>
/// <param name="fleaOffer">Offer being purchased</param>
/// <param name="offerRequest">request data from client</param>
/// <param name="output">Output to send back to client</param>
private void BuyPmcItemFromRagfair(
string sessionId,
PmcData pmcData,
RagfairOffer fleaOffer,
OfferRequest offerRequest,
ItemEventRouterResponse output)
{
throw new NotImplementedException();
}
/// <summary>
/// Is the provided offerid and ownerid from a player made offer
/// </summary>
/// <param name="offerId">id of the offer</param>
/// <param name="offerOwnerId">Owner id</param>
/// <returns>true if offer was made by a player</returns>
private bool IsPlayerOffer(
string offerId,
string offerOwnerId)
{
throw new NotImplementedException();
}
/// <summary>
/// Does Player have necessary trader loyalty to purchase flea offer
/// </summary>
/// <param name="fleaOffer">Flea offer being bought</param>
/// <param name="pmcData">Player profile</param>
/// <returns>True if player can buy offer</returns>
private bool PlayerLacksTraderLoyaltyLevelToBuyOffer(
RagfairOffer fleaOffer,
PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle SellAllFromSavage event
/// </summary>
/// <param name="pmcData"></param>
/// <param name="request"></param>
/// <param name="sessionId"></param>
/// <returns></returns>
public ItemEventRouterResponse SellScavItemsToFence(
PmcData pmcData,
SellScavItemsToFenceRequestData request,
string sessionId)
{
throw new NotImplementedException();
}
/// <summary>
/// Send the specified rouble total to player as mail
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="roublesToSend">amount of roubles to send</param>
/// <param name="trader">Trader to sell items to</param>
private void MailMoneyToPlayer(
string sessionId,
int roublesToSend,
string trader)
{
throw new NotImplementedException();
}
/// <summary>
/// Looks up an items children and gets total handbook price for them
/// </summary>
/// <param name="parentItemId">parent item that has children we want to sum price of</param>
/// <param name="items">All items (parent + children)</param>
/// <param name="handbookPrices">Prices of items from handbook</param>
/// <param name="traderDetails">Trader being sold to, to perform buy category check against</param>
/// <returns>Rouble price</returns>
private int GetPriceOfItemAndChildren(
string parentItemId,
List<Item> items,
Dictionary<string, int> handbookPrices,
TraderBase traderDetails)
{
throw new NotImplementedException();
}
}