public void HandleRequest(IRequest request) { var definition = request.Data.GetOrDefault <int>(k.definition); var character = request.Session.Character; var marketEid = request.Data.GetOrDefault <long>(k.eid); if (!_entityServices.Defaults.TryGet(definition, out EntityDefault ed)) { throw new PerpetuumException(ErrorCodes.DefinitionNotSupported); } if (!ed.Purchasable) { throw new PerpetuumException(ErrorCodes.ItemNotPurchasable); } var market = marketEid == 0 ? character.GetCurrentDockingBase().GetMarketOrThrow() : Market.GetOrThrow(marketEid); var tax = market.GetMarketTaxRate(character); var feeRate = Market.GetMarketFeeRate(character); var feeReal = feeRate * _marketInfoService.Fee; var avgPrice = _marketHandler.GetAveragePriceByMarket(market, definition).AveragePrice; var result = new Dictionary <string, object> { { k.average, avgPrice }, { k.definition, definition }, { k.tax, 1.0 - tax }, { k.feeRate, feeRate }, { k.fee, feeReal }, { k.marketMargin, _marketInfoService.Margin }, { k.marketCheckMargin, _marketInfoService.CheckAveragePrice } }; Message.Builder.FromRequest(request).WithData(result).Send(); }
public void HandleRequest(IRequest request) { using (var scope = Db.CreateTransaction()) { var buyer = request.Session.Character; var itemDefinition = request.Data.GetOrDefault <int>(k.definition); var duration = request.Data.GetOrDefault <int>(k.duration); var pricePerPiece = request.Data.GetOrDefault <double>(k.price); var quantity = request.Data.GetOrDefault(k.quantity, 1); var useBuyerCorporationWallet = request.Data.GetOrDefault <int>(k.useCorporationWallet) == 1; var forMyCorporation = request.Data.GetOrDefault <int>(k.forMembersOf) == 1; quantity.ThrowIfLessOrEqual(0, ErrorCodes.AmountTooLow); buyer.IsDocked.ThrowIfFalse(ErrorCodes.CharacterHasToBeDocked); buyer.CheckPrivilegedTransactionsAndThrowIfFailed(); pricePerPiece.ThrowIfLessOrEqual(0, ErrorCodes.IllegalMarketPrice); duration.ThrowIfLessOrEqual(1, ErrorCodes.MinimalDurationNotReached); var ed = EntityDefault.Get(itemDefinition).ThrowIfEqual(EntityDefault.None, ErrorCodes.DefinitionNotSupported); ed.IsSellable.ThrowIfFalse(ErrorCodes.ItemNotSellable); var market = buyer.GetCurrentDockingBase().GetMarketOrThrow(); var realMarketFee = Market.GetRealMarketFee(buyer, duration); var corporationEid = buyer.CorporationEid; //cash market fee anyways _marketHelper.CashInMarketFee(buyer, useBuyerCorporationWallet, realMarketFee); buyer.GetCurrentDockingBase().AddCentralBank(TransactionType.marketFee, realMarketFee); if (_marketInfoService.CheckAveragePrice) { var avgPrice = _marketHandler.GetAveragePriceByMarket(market, itemDefinition); if (avgPrice != null && avgPrice.AveragePrice > 0) { if (pricePerPiece < avgPrice.AveragePrice * (1 - _marketInfoService.Margin) || pricePerPiece > avgPrice.AveragePrice * (1 + _marketInfoService.Margin)) { throw new PerpetuumException(ErrorCodes.PriceOutOfAverageRange); } } } var publicContainer = buyer.GetPublicContainerWithItems(); long?forMembersOf = null; if (forMyCorporation) { if (!DefaultCorporationDataCache.IsCorporationDefault(corporationEid)) { forMembersOf = corporationEid; } else { forMyCorporation = false; } } if (!forMyCorporation) { _marketHelper.CheckBuyOrderCounts(buyer).ThrowIfFalse(ErrorCodes.MarketItemsExceed); } var lowestSellOrder = _marketOrderRepository.GetLowestSellOrder(itemDefinition, pricePerPiece, buyer.Eid, market, corporationEid); if (!forMyCorporation && lowestSellOrder != null) { // requested item was found on the market, make immediate transaction market.FulfillBuyOrderInstantly(buyer, useBuyerCorporationWallet, lowestSellOrder, pricePerPiece, duration, quantity, publicContainer, forMembersOf); } else { var deposit = pricePerPiece * quantity; // take the deposit from the character _marketHelper.CashIn(buyer, useBuyerCorporationWallet, pricePerPiece, itemDefinition, quantity, TransactionType.buyOrderDeposit); //store the deposit in the central bank market.AddCentralBank(TransactionType.buyOrderDeposit, deposit); // create a new buy order var newBuyOrder = market.CreateBuyOrder(buyer, itemDefinition, duration, pricePerPiece, quantity, useBuyerCorporationWallet, forMembersOf); var data = new Dictionary <string, object> { { k.buyOrder, newBuyOrder.ToDictionary() } }; Message.Builder.SetCommand(Commands.MarketBuyOrderCreated) .WithData(data) .ToCharacter(buyer) .Send(); } publicContainer.Save(); Message.Builder.SetCommand(Commands.ListContainer) .WithData(publicContainer.ToDictionary()) .ToCharacter(buyer) .Send(); scope.Complete(); } }
public void HandleRequest(IRequest request) { using (var scope = Db.CreateTransaction()) { var seller = request.Session.Character; var itemEid = request.Data.GetOrDefault <long>(k.itemEID); var duration = request.Data.GetOrDefault <int>(k.duration); var pricePerPiece = request.Data.GetOrDefault <double>(k.price); var quantity = request.Data.GetOrDefault <int>(k.quantity); var useSellerCorporationWallet = request.Data.GetOrDefault <int>(k.useCorporationWallet) == 1; var containerEid = request.Data.GetOrDefault <long>(k.container); var forMyCorporation = request.Data.GetOrDefault <int>(k.forMembersOf) == 1; var targetOrderId = request.Data.GetOrDefault <int>(k.targetOrder); seller.IsDocked.ThrowIfFalse(ErrorCodes.CharacterHasToBeDocked); seller.CheckPrivilegedTransactionsAndThrowIfFailed(); quantity.ThrowIfLessOrEqual(0, ErrorCodes.WTFErrorMedicalAttentionSuggested); pricePerPiece.ThrowIfLessOrEqual(0, ErrorCodes.IllegalMarketPrice); duration.ThrowIfLess(1, ErrorCodes.MinimalDurationNotReached); var market = seller.GetCurrentDockingBase().GetMarketOrThrow(); var corporationEid = seller.CorporationEid; var publicContainer = seller.GetPublicContainerWithItems(); var sourceContainer = (Container)publicContainer.GetItemOrThrow(containerEid, true); long?forMembersOf = null; if (forMyCorporation) { if (!DefaultCorporationDataCache.IsCorporationDefault(corporationEid)) { forMembersOf = corporationEid; } else { forMyCorporation = false; } } //unstack a fraction or take the whole item, check for conditions var itemToSell = market.PrepareItemForSale(seller, itemEid, quantity, sourceContainer); if (_marketInfoService.CheckAveragePrice) { var avgPrice = _marketHandler.GetAveragePriceByMarket(market, itemToSell.Definition); if (avgPrice != null && avgPrice.AveragePrice > 0) { (pricePerPiece <avgPrice.AveragePrice * (1 - _marketInfoService.Margin) || pricePerPiece> avgPrice.AveragePrice * (1 + _marketInfoService.Margin)).ThrowIfTrue(ErrorCodes.PriceOutOfAverageRange); } } MarketOrder highestBuyOrder; if (targetOrderId > 0) { //target order was defined by user highestBuyOrder = _marketOrderRepository.Get(targetOrderId).ThrowIfNull(ErrorCodes.ItemNotFound); //for my corp? highestBuyOrder.forMembersOf?.ThrowIfNotEqual(corporationEid, ErrorCodes.AccessDenied); //sell to order market.FulfillSellOrderInstantly(seller, useSellerCorporationWallet, highestBuyOrder, itemToSell, sourceContainer); } else { //try to find a buy order for the currently submitted item, it finds the closest buy order highestBuyOrder = _marketOrderRepository.GetHighestBuyOrder(itemToSell.Definition, pricePerPiece, seller.Eid, market, corporationEid); if (!forMyCorporation && highestBuyOrder != null) { //sell to order market.FulfillSellOrderInstantly(seller, useSellerCorporationWallet, highestBuyOrder, itemToSell, sourceContainer); } else { if (!forMyCorporation) { _marketHelper.CheckSellOrderCounts(seller).ThrowIfFalse(ErrorCodes.MarketItemsExceed); } var realMarketFee = Market.GetRealMarketFee(seller, duration); //cash market fee anyways _marketHelper.CashInMarketFee(seller, useSellerCorporationWallet, realMarketFee); market.GetDockingBase().AddCentralBank(TransactionType.marketFee, realMarketFee); market.CreateSellOrder(seller.Eid, itemToSell, duration, pricePerPiece, quantity, useSellerCorporationWallet, forMembersOf); } } publicContainer.Save(); var containerData = publicContainer.ToDictionary(); Message.Builder.SetCommand(Commands.ListContainer) .WithData(containerData) .ToCharacter(seller) .Send(); scope.Complete(); } }