public override void ProcessServer() { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); if (player != null && player.IsAdmin()) // hold on there, are we an admin first? { // we look up our bank record based on our Steam Id/ var myaccount = EconomyScript.Instance.Data.Accounts.FirstOrDefault( a => a.SteamId == SenderSteamId); // wait do we even have an account yet? Cant remove whats not there! if (myaccount != null) { AccountManager.ResetAccount(myaccount); MessageUpdateClient.SendAccountMessage(myaccount); } else { //ok cause i am an admin and everything else checks out, lets construct our bank record with a new balance myaccount = AccountManager.CreateNewDefaultAccount(SenderSteamId, player.DisplayName, SenderLanguage); //ok lets apply it EconomyScript.Instance.Data.Accounts.Add(myaccount); EconomyScript.Instance.Data.CreditBalance -= myaccount.BankBalance; } MessageClientTextMessage.SendMessage(SenderSteamId, "RESET", "Done"); } }
public override void ProcessServer() { var account = EconomyScript.Instance.Data.Clients.FirstOrDefault( a => a.NickName.Equals(UserName, StringComparison.InvariantCultureIgnoreCase)); string reply; if (account == null) // extra check for substring if no match found ie /seen fox also matches starfox case sensitive as tolowerinvariant wont work for me { account = EconomyScript.Instance.Data.Clients.FirstOrDefault(a => a.NickName.Contains(UserName)); } if (account == null) { reply = "Player not found"; } else { reply = "Player " + account.NickName + " Last seen: " + account.Date; } //reply = string.Format("Player {0} Last seen: {1:%d} days {1:hh\\:mm\\:ss}", account.NickName, (account.Date - DateTime.Now)); // TODO: https://github.com/jpcsupplies/Economy_mod/issues/54 MessageClientTextMessage.SendMessage(SenderSteamId, "SEEN", reply); // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Balance Request for '{0}' from '{1}'", UserName, SenderSteamId); if (string.IsNullOrEmpty(UserName)) //did we just type bal? show our balance { // lets grab the current player data from our bankfile ready for next step // we look up our Steam Id/ var account = EconomyScript.Instance.Data.Accounts.FirstOrDefault( a => a.SteamId == SenderSteamId); // check if we actually found it, add default if not if (account == null) { EconomyScript.Instance.ServerLogger.WriteInfo("Creating new Bank Account for '{0}'", SenderDisplayName); account = AccountManager.CreateNewDefaultAccount(SenderSteamId, SenderDisplayName, SenderLanguage); EconomyScript.Instance.Data.Accounts.Add(account); EconomyScript.Instance.Data.CreditBalance -= account.BankBalance; } MessageClientTextMessage.SendMessage(SenderSteamId, "BALANCE", "Your bank balance is {0:#,##0.######} {1}", account.BankBalance, EconomyScript.Instance.ServerConfig.CurrencyName); } else // if username is supplied, we want to know someone elses balance. { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); if (player != null && player.IsAdmin()) // hold on there, are we an admin first? { var account = EconomyScript.Instance.Data.Accounts.FirstOrDefault( a => a.NickName.Equals(UserName, StringComparison.InvariantCultureIgnoreCase)); string reply; if (account == null) { reply = string.Format("Player '{0}' not found Balance: 0", UserName); } else { reply = string.Format("Player '{0}' Balance: {1}", account.NickName, account.BankBalance); } MessageClientTextMessage.SendMessage(SenderSteamId, "BALANCE", reply); } } }
/// <summary> /// Send a message to targeted player if have additional offers pending for them. /// </summary> /// <param name="steamdId"></param> private void DisplayNextOrderToAccept(ulong steamdId) { // Buyers should be presented with the oldest order first, as they will timout first. // use of OrderBy assures us that [0] is the most oldest order added. var remaingingUnacceptedOrders = EconomyScript.Instance.Data.OrderBook.Where(e => (e.OptionalId == steamdId.ToString() && e.TradeState == TradeState.SellDirectPlayer)).OrderBy(e => e.Created).ToList(); if (remaingingUnacceptedOrders.Count <= 0) { return; } var order = remaingingUnacceptedOrders[0]; var accountToSell = AccountManager.FindAccount(order.TraderId); var transactionAmount = order.Price * order.Quantity; var payingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(steamdId); // need fix negative amounts before checking if the player can afford it. if (!payingPlayer.IsAdmin()) { transactionAmount = Math.Abs(transactionAmount); } var definition = MyDefinitionManager.Static.GetDefinition(order.TypeId, order.SubtypeName); if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(steamdId, "SELL", "Sorry, the item in your order doesn't exist!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during 'DisplayNextOrderToAccept'; '{0}' '{1}'.", order.TypeId, order.SubtypeName); return; } MessageClientTextMessage.SendMessage(steamdId, "SELL", "You have received an offer from {0} to buy {1} {2} at total price {3} {4} - type '/sell accept' to accept offer (or '/sell deny' to reject and return item to seller)", accountToSell.NickName, order.Quantity, definition.GetDisplayName(), transactionAmount, EconomyScript.Instance.ServerConfig.CurrencyName); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Value Request for '{0}:{1}' from '{2}'", TypeId, SubtypeName, SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.GetCharacter(); if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "VALUE", "You are dead. You get market items values while dead."); return; } var position = ((IMyEntity)character).WorldMatrix.Translation; var markets = MarketManager.FindMarketsFromLocation(position); if (markets.Count == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "VALUE", "Sorry, your are not in range of any markets!"); return; } // TODO: find market with best Buy price that isn't blacklisted. var market = markets.FirstOrDefault(); if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "VALUE", "That market does not exist."); return; } // TypeId and SubtypeName are both Case sensitive. Do not Ignore case when comparing these. var item = market.MarketItems.FirstOrDefault(e => e.TypeId == TypeId && e.SubtypeName == SubtypeName); if (item == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "VALUE", "Sorry, the items you are trying to value doesn't have a market entry!"); return; } string reply; if (item.IsBlacklisted) { reply = "Sorry, the item you tried to get a value for is blacklisted on this server."; } else { // TODO: qty may need additional range checking here. if (Quantity == 1) { // set reply to report back the current buy and sell price only since that is all we asked for reply = string.Format("Player TRADE - You can buy each '{0}' for {1}, or sell it back for {2} each.", DisplayName, item.SellPrice, item.BuyPrice); reply += "\r\n" + string.Format("NPC TRADE - You can buy each '{0}' for {1}, or sell it back for {2} each.", DisplayName, EconDataManager.PriceAdjust(item.SellPrice, item.Quantity, PricingBias.Sell), EconDataManager.PriceAdjust(item.BuyPrice, item.Quantity, PricingBias.Buy)); } else { // value BLAH 12 - we must want to know how much we make/pay for buying/selling 12 // set reply to current buy and sell price multiplied by the requested qty. reply = string.Format("Player TRADE - You can buy {0} '{1}' for {2} or sell it back for {3} each.", Quantity, DisplayName, item.SellPrice * Quantity, item.BuyPrice * Quantity); reply += "\r\n" + string.Format("NPC TRADE - You can buy {0} '{1}' for {2} or sell it back for {3} each.", Quantity, DisplayName, EconDataManager.PriceAdjust(item.SellPrice, item.Quantity, PricingBias.Sell) * Quantity, EconDataManager.PriceAdjust(item.BuyPrice, item.Quantity, PricingBias.Buy) * Quantity); } } MessageClientTextMessage.SendMessage(SenderSteamId, "VALUE", reply); }
public override void ProcessServer() { if (!EconomyScript.Instance.ServerConfig.EnableNpcTradezones && !EconomyScript.Instance.ServerConfig.EnablePlayerTradezones) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "All Trade zones are disabled."); return; } switch (SellAction) { #region create case SellAction.Create: { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create started by Steam Id '{0}'.", SenderSteamId); //* Logic: //* Get player steam ID var sellingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); MyDefinitionBase definition = null; MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(ItemTypeId, out result)) { var id = new MyDefinitionId(result, ItemSubTypeName); MyDefinitionManager.Static.TryGetDefinition(id, out definition); } if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item you specified doesn't exist!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during '/sell'; '{0}' '{1}'.", ItemTypeId, ItemSubTypeName); return; } // Do a floating point check on the item item. Tools and components cannot have decimals. They must be whole numbers. if (definition.Id.TypeId != typeof(MyObjectBuilder_Ore) && definition.Id.TypeId != typeof(MyObjectBuilder_Ingot)) { if (ItemQuantity != Math.Truncate(ItemQuantity)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You must provide a whole number for the quantity of that item."); return; } //ItemQuantity = Math.Round(ItemQuantity, 0); // Or do we just round the number? } if (ItemQuantity <= 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Invalid quantity, or you dont have any to trade!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- Invalid quantity.", SenderSteamId); return; } // Who are we selling to? BankAccountStruct accountToBuy; if (SellToMerchant) { accountToBuy = AccountManager.FindAccount(EconomyConsts.NpcMerchantId); } else { accountToBuy = AccountManager.FindAccount(ToUserName); } if (accountToBuy == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, player does not exist or have an account!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- account not found.", SenderSteamId); return; } if (MarketManager.IsItemBlacklistedOnServer(ItemTypeId, ItemSubTypeName)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item you tried to sell is blacklisted on this server."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- Item is blacklisted.", SenderSteamId); return; } // Verify that the items are in the player inventory. // TODO: later check trade block, cockpit inventory, cockpit ship inventory, inventory of targeted cube. // Get the player's inventory, regardless of if they are in a ship, or a remote control cube. var character = sellingPlayer.GetCharacter(); // TODO: do players in Cryochambers count as a valid trading partner? They should be alive, but the connected player may be offline. // I think we'll have to do lower level checks to see if a physical player is Online. if (character == null) { // Player has no body. Could mean they are dead. // Either way, there is no inventory. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You are dead. You cannot trade while dead."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- player is dead.", SenderSteamId); return; } // TODO: is a null check adaqaute?, or do we need to check for IsDead? // I don't think the chat console is accessible during respawn, only immediately after death. // Is it valid to be able to trade when freshly dead? //var identity = payingPlayer.Identity(); //MyAPIGateway.Utilities.ShowMessage("CHECK", "Is Dead: {0}", identity.IsDead); //if (identity.IsDead) //{ // MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You are dead. You cannot trade while dead."); // return; //} EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell finalizing by Steam Id '{0}' -- cataloging cargo cubes.", SenderSteamId); // Build list of all cargo blocks that player is attached to as pilot or passenger. var cargoBlocks = new List <MyCubeBlock>(); var tankBlocks = new List <MyCubeBlock>(); var controllingCube = sellingPlayer.Controller.ControlledEntity as IMyCubeBlock; if (controllingCube != null) { var terminalsys = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(controllingCube.CubeGrid); var blocks = new List <IMyTerminalBlock>(); terminalsys.GetBlocksOfType <IMyCargoContainer>(blocks); cargoBlocks.AddRange(blocks.Cast <MyCubeBlock>()); terminalsys.GetBlocksOfType <IMyGasTank>(blocks); tankBlocks.AddRange(blocks.Cast <MyCubeBlock>()); } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell finalizing by Steam Id '{0}' -- checking inventory.", SenderSteamId); var position = ((IMyEntity)character).WorldMatrix.Translation; var playerInventory = character.GetPlayerInventory(); MyFixedPoint amount = (MyFixedPoint)ItemQuantity; var storedAmount = playerInventory.GetItemAmount(definition.Id); if (definition.Id.TypeId == typeof(MyObjectBuilder_GasProperties)) { foreach (MyCubeBlock cubeBlock in tankBlocks) { MyGasTankDefinition gasTankDefintion = cubeBlock.BlockDefinition as MyGasTankDefinition; if (gasTankDefintion == null || gasTankDefintion.StoredGasId != definition.Id) { continue; } var tankLevel = ((IMyGasTank)cubeBlock).FilledRatio; storedAmount += (MyFixedPoint)((decimal)tankLevel * (decimal)gasTankDefintion.Capacity); } } else { foreach (MyCubeBlock cubeBlock in cargoBlocks) { var cubeInventory = cubeBlock.GetInventory(); storedAmount += cubeInventory.GetItemAmount(definition.Id); } } if (amount > storedAmount) { // Insufficient items in inventory. // TODO: use of definition.GetDisplayName() isn't localized here. if ((definition.Id.TypeId != typeof(MyObjectBuilder_GasProperties) && cargoBlocks.Count == 0) && (definition.Id.TypeId == typeof(MyObjectBuilder_GasProperties) && tankBlocks.Count == 0)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You don't have {0} of '{1}' to sell. You have {2} in your inventory.", ItemQuantity, definition.GetDisplayName(), storedAmount); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You don't have {0} of '{1}' to sell. You have {2} in your player and cargo inventory.", ItemQuantity, definition.GetDisplayName(), storedAmount); } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- inventory doesn't exist.", SenderSteamId); return; } MarketItemStruct marketItem = null; if (SellToMerchant || UseBankBuyPrice) { var markets = MarketManager.FindMarketsFromLocation(position); if (markets.Count == 0) //once again here is were we could put the multi market best price logic.. { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, your are not in range of any markets!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- no market in range.", SenderSteamId); return; } // TODO: find market with best Buy price that isn't blacklisted. var market = markets.FirstOrDefault(); if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the market you are accessing does not exist!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- no market found.", SenderSteamId); return; } accountToBuy = AccountManager.FindAccount(market.MarketId); marketItem = market.MarketItems.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); if (marketItem == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the items you are trying to sell doesn't have a market entry!"); // In reality, this shouldn't happen as all markets have their items synced up on start up of the mod. return; } if (marketItem.IsBlacklisted) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item you tried to sell is blacklisted in this market."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- item is blacklisted.", SenderSteamId); return; } if (UseBankBuyPrice) { // The player is selling, but the *Market* will *buy* it from the player at this price. // if we are not using price scaling OR the market we are trading with isn't owned by the NPC ID, dont change price. Otherwise scale. if (!EconomyScript.Instance.ServerConfig.PriceScaling || accountToBuy.SteamId != EconomyConsts.NpcMerchantId) { ItemPrice = marketItem.BuyPrice; } else { ItemPrice = EconDataManager.PriceAdjust(marketItem.BuyPrice, marketItem.Quantity, PricingBias.Buy); } } // if we are using price scaling adjust the price before our NPC trade (or check player for subsidy pricing) } var accountToSell = AccountManager.FindOrCreateAccount(SenderSteamId, SenderDisplayName, SenderLanguage); // need fix negative amounts before checking if the player can afford it. if (!sellingPlayer.IsAdmin()) { ItemPrice = Math.Abs(ItemPrice); } var transactionAmount = ItemPrice * ItemQuantity; if (!sellingPlayer.IsAdmin()) { transactionAmount = Math.Abs(transactionAmount); } if (SellToMerchant) // && (merchant has enough money || !EconomyScript.Instance.ServerConfig.LimitedSupply) //this is also a quick fix ideally npc should buy what it can afford and the rest is posted as a sell offer { if (accountToBuy.SteamId != accountToSell.SteamId) { decimal limit = EconomyScript.Instance.ServerConfig.LimitedSupply ? marketItem.StockLimit - marketItem.Quantity : ItemQuantity; if (limit == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, you cannot sell any more {0} into this market.", definition.GetDisplayName()); return; } if (ItemQuantity > limit) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, you cannot sell any more than {0} of {1} into this market.", limit, definition.GetDisplayName()); return; } } if (accountToBuy.BankBalance >= transactionAmount // || !EconomyScript.Instance.ServerConfig.LimitedSupply // I'm not sure why we check limited supply when selling. || accountToBuy.SteamId == accountToSell.SteamId) { // here we look up item price and transfer items and money as appropriate EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell finalizing by Steam Id '{0}' -- removing inventory.", SenderSteamId); RemoveInventory(playerInventory, cargoBlocks, tankBlocks, amount, definition.Id); marketItem.Quantity += ItemQuantity; // increment Market content. if (accountToBuy.SteamId != accountToSell.SteamId) { accountToBuy.BankBalance -= transactionAmount; accountToBuy.Date = DateTime.Now; accountToSell.BankBalance += transactionAmount; accountToSell.Date = DateTime.Now; MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just sold {0} {3} worth of {2} ({1} units)", transactionAmount, ItemQuantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); MessageUpdateClient.SendAccountMessage(accountToBuy); MessageUpdateClient.SendAccountMessage(accountToSell); } else { accountToSell.Date = DateTime.Now; MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You just arranged transfer of {0} '{1}' into your market.", ItemQuantity, definition.GetDisplayName()); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "NPC can't afford {0} {4} worth of {2} ({1} units) NPC only has {3} funds!", transactionAmount, ItemQuantity, definition.GetDisplayName(), accountToBuy.BankBalance, EconomyScript.Instance.ServerConfig.CurrencyName); } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create completed by Steam Id '{0}' -- to NPC market.", SenderSteamId); return; } if (OfferToMarket) { // TODO: Here we post offer to appropriate zone market MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Offset to market at price is not yet available!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- Offer to market at price is not yet available.", SenderSteamId); return; } // is it a player then? if (accountToBuy.SteamId == sellingPlayer.SteamUserId) { // commented out for testing with myself. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, you cannot sell to yourself!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- can't sell to self.", SenderSteamId); return; } // check if buying player is online and in range? var buyingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(accountToBuy.SteamId); if (EconomyScript.Instance.ServerConfig.LimitedRange && !Support.RangeCheck(buyingPlayer, sellingPlayer)) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, you are not in range of that player!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- target player not in range.", SenderSteamId); return; } // if other player online, send message. if (buyingPlayer == null) { // TODO: other player offline. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You cannot sell to offline players at this time."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create aborted by Steam Id '{0}' -- cannot sell to offline player.", SenderSteamId); return; // TODO: we need a way to queue up messages. // While you were gone.... // You missed an offer for 4000Kg of Gold for 20,000. } else { // The other player is online. // write to Trade offer table. MarketManager.CreateTradeOffer(SenderSteamId, ItemTypeId, ItemSubTypeName, ItemQuantity, ItemPrice, accountToBuy.SteamId); // remove items from inventory. EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell finalizing by Steam Id '{0}' -- removing inventory.", SenderSteamId); RemoveInventory(playerInventory, cargoBlocks, tankBlocks, amount, definition.Id); // Only send message to targeted player if this is the only offer pending for them. // Otherwise it will be sent when the have with previous orders in their order Queue. if (EconomyScript.Instance.Data.OrderBook.Count(e => (e.OptionalId == accountToBuy.SteamId.ToString() && e.TradeState == TradeState.SellDirectPlayer)) == 1) { MessageClientTextMessage.SendMessage(accountToBuy.SteamId, "SELL", "You have received an offer from {0} to buy {1} {2} at price {3} {4} each - type '/sell accept' to accept offer (or '/sell deny' to reject and return item to seller)", SenderDisplayName, ItemQuantity, definition.GetDisplayName(), ItemPrice, EconomyScript.Instance.ServerConfig.CurrencyName); } // TODO: Improve the message here, to say who were are trading to, and that the item is gone from inventory. // send message to seller to confirm action, "Your Trade offer has been submitted, and the goods removed from you inventory." MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Your offer of {0} {1} for {2} {4} each has been sent to {3}.", ItemQuantity, definition.GetDisplayName(), ItemPrice, accountToBuy.NickName, EconomyScript.Instance.ServerConfig.CurrencyName); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Create completed by Steam Id '{0}' -- to another player.", SenderSteamId); return; } } #endregion #region accept case SellAction.Accept: { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Accept started by Steam Id '{0}'.", SenderSteamId); var order = EconomyScript.Instance.Data.OrderBook.FirstOrDefault(e => e.OptionalId == SenderSteamId.ToString() && e.TradeState == TradeState.SellDirectPlayer); if (order == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "There are no outstanding orders to be accepted."); return; } var payingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); // get the accounts and check finance. var accountToBuy = AccountManager.FindAccount(ulong.Parse(order.OptionalId)); var transactionAmount = order.Price * order.Quantity; // need fix negative amounts before checking if the player can afford it. if (!payingPlayer.IsAdmin()) { transactionAmount = Math.Abs(transactionAmount); } if (accountToBuy.BankBalance < transactionAmount) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You cannot afford {0} {1} at this time.", transactionAmount, EconomyScript.Instance.ServerConfig.CurrencyName); return; } var accountToSell = AccountManager.FindAccount(order.TraderId); // rebalance accounts. accountToBuy.BankBalance -= transactionAmount; accountToBuy.Date = DateTime.Now; accountToSell.BankBalance += transactionAmount; accountToSell.Date = DateTime.Now; MessageUpdateClient.SendAccountMessage(accountToBuy); MessageUpdateClient.SendAccountMessage(accountToSell); order.TradeState = TradeState.SellAccepted; var definition = MyDefinitionManager.Static.GetDefinition(order.TypeId, order.SubtypeName); if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item in your order doesn't exist!"); // trade has been finalized, so we can exit safely. EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during '/sell accept'; '{0}' '{1}'.", order.TypeId, order.SubtypeName); return; } // TODO: Improve the messages. // message back "Your Trade offer of xxx to yyy has been accepted. You have recieved zzzz" MessageClientTextMessage.SendMessage(accountToSell.SteamId, "SELL", "You just sold {0} {3} worth of {2} ({1} units)", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); var collectingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var playerInventory = collectingPlayer.GetPlayerInventory(); bool hasAddedToInventory = true; if (playerInventory != null) { MyFixedPoint amount = (MyFixedPoint)order.Quantity; hasAddedToInventory = Support.InventoryAdd(playerInventory, amount, definition.Id); } if (hasAddedToInventory) { EconomyScript.Instance.Data.OrderBook.Remove(order); // item has been collected, so the order is finalized. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just purchased {0} {3} worth of {2} ({1} units) which are now in your player inventory.", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just purchased {0} {3} worth of {2} ({1} units). Enter '/collect' when you are ready to receive them.", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); } // Send message to player if additional offers are pending their attention. DisplayNextOrderToAccept(SenderSteamId); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Accept completed by Steam Id '{0}'.", SenderSteamId); return; } #endregion #region collect case SellAction.Collect: { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Collect or /collect started by Steam Id '{0}'.", SenderSteamId); var collectableOrders = EconomyScript.Instance.Data.OrderBook.Where(e => (e.TraderId == SenderSteamId && e.TradeState == TradeState.SellTimedout) || (e.TraderId == SenderSteamId && e.TradeState == TradeState.Holding) || (e.TraderId == SenderSteamId && e.TradeState == TradeState.SellRejected) || (e.OptionalId == SenderSteamId.ToString() && e.TradeState == TradeState.SellAccepted)).ToArray(); if (collectableOrders.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "There is nothing to collect currently."); return; } var collectingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); // TODO: this is just for debugging until the message below are completed.... //MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You are collecting items from {0} order/s.", collectableOrders.Length); foreach (var order in collectableOrders) { MyDefinitionBase definition = null; MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(order.TypeId, out result)) { var id = new MyDefinitionId(result, order.SubtypeName); MyDefinitionManager.Static.TryGetDefinition(id, out definition); } if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item in your order doesn't exist!"); // TODO: more detail on the item. EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during '/sell collect or /collect'; '{0}' '{1}'.", order.TypeId, order.SubtypeName); continue; } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell finalizing by Steam Id '{0}' -- adding to inventories.", SenderSteamId); var remainingToCollect = MessageSell.AddToInventories(collectingPlayer, order.Quantity, definition.Id); var collected = order.Quantity - remainingToCollect; if (remainingToCollect == 0) { EconomyScript.Instance.Data.OrderBook.Remove(order); MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just collected {0} worth of {2} ({1} units)", order.Price * collected, collected, definition.GetDisplayName()); } else { order.Quantity = remainingToCollect; MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just collected {0} worth of {2} ({1} units). There are {3} remaining.", order.Price * collected, collected, definition.GetDisplayName(), remainingToCollect); } } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Collect completed by Steam Id '{0}'.", SenderSteamId); return; } #endregion #region cancel case SellAction.Cancel: { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Cancel started by Steam Id '{0}'.", SenderSteamId); var cancellableOrders = EconomyScript.Instance.Data.OrderBook.Where(e => (e.TraderId == SenderSteamId && e.TradeState == TradeState.SellDirectPlayer)).OrderByDescending(e => e.Created).ToArray(); if (cancellableOrders.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "There is nothing to cancel currently."); } // Sellers should be presented with the newest order first, as they will be the most recently created. // use of OrderByDescending above assures us that [0] is the most recent order added. var order = cancellableOrders[0]; order.TradeState = TradeState.SellRejected; var definition = MyDefinitionManager.Static.GetDefinition(order.TypeId, order.SubtypeName); if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item in your order doesn't exist!"); // trade has been finalized, so we can exit safely. EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during '/sell cancel'; '{0}' '{1}'.", order.TypeId, order.SubtypeName); return; } var transactionAmount = order.Price * order.Quantity; var collectingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var inventory = collectingPlayer.GetPlayerInventory(); bool hasAddedToInventory = true; if (inventory != null) { MyFixedPoint amount = (MyFixedPoint)order.Quantity; hasAddedToInventory = Support.InventoryAdd(inventory, amount, definition.Id); } if (hasAddedToInventory) { EconomyScript.Instance.Data.OrderBook.Remove(order); // item has been collected, so the order is finalized. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just cancelled the sale of {2} ({1} units) for a total of {0} {3} which are now in your inventory.", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "You just cancelled the sale of {2} ({1} units) for a total of {0} {3}. Enter '/sell collect' when you are ready to receive them.", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); } cancellableOrders = EconomyScript.Instance.Data.OrderBook.Where(e => (e.TraderId == SenderSteamId && e.TradeState == TradeState.SellDirectPlayer)).OrderByDescending(e => e.Created).ToArray(); if (cancellableOrders.Length > 0) { // TODO: Inform the player of the next order in the queue that can be cancelled. } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Cancel completed by Steam Id '{0}'.", SenderSteamId); return; } #endregion #region deny case SellAction.Deny: { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Deny started by Steam Id '{0}'.", SenderSteamId); var buyOrdersForMe = EconomyScript.Instance.Data.OrderBook.Where(e => (e.OptionalId == SenderSteamId.ToString() && e.TradeState == TradeState.SellDirectPlayer)).OrderBy(e => e.Created).ToArray(); if (buyOrdersForMe.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "There is nothing to deny currently."); } // Buyers should be presented with the oldest order first, as they will timout first. // use of OrderBy above assures us that [0] is the most oldest order added. var order = buyOrdersForMe[0]; order.TradeState = TradeState.SellRejected; var definition = MyDefinitionManager.Static.GetDefinition(order.TypeId, order.SubtypeName); if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Sorry, the item in your order doesn't exist!"); // trade has been finalized, so we can exit safely. EconomyScript.Instance.ServerLogger.WriteVerbose("Definition could not be found for item during '/sell deny'; '{0}' '{1}'.", order.TypeId, order.SubtypeName); return; } var transactionAmount = order.Price * order.Quantity; var buyerId = ulong.Parse(order.OptionalId); MessageClientTextMessage.SendMessage(buyerId, "SELL", "You just rejected the purchase of {2} ({1} units) for a total of {0} {3}.", transactionAmount, order.Quantity, definition.GetDisplayName(), EconomyScript.Instance.ServerConfig.CurrencyName); // TODO: return items to inventory automatically to Trader inventory if there is space. MessageClientTextMessage.SendMessage(order.TraderId, "SELL", "{3} has just rejected your offer of {2} ({1} units) for a total of {0} {4}. Enter '/sell collect' when you are ready to receive them.", transactionAmount, order.Quantity, definition.GetDisplayName(), SenderDisplayName, EconomyScript.Instance.ServerConfig.CurrencyName); // Send message to player if additional offers are pending their attention. DisplayNextOrderToAccept(SenderSteamId); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Sell Deny completed by Steam Id '{0}'.", SenderSteamId); return; } #endregion } // this is a fall through from the above conditions not yet complete. MessageClientTextMessage.SendMessage(SenderSteamId, "SELL", "Not yet complete."); }
public override void ProcessServer() { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); // Only Admin can change Npc Market prices. if (!player.IsAdmin() && MarketId == EconomyConsts.NpcMerchantId) { EconomyScript.Instance.ServerLogger.WriteWarning("A Player without Admin \"{0}\" {1} attempted to set Default Market characteristics of item {2}/{3} to Quantity={4}.", SenderDisplayName, SenderSteamId, ItemTypeId, ItemSubTypeName, ItemQuantity); return; } // Only Player can change their own Market prices. if (SenderSteamId != MarketId && MarketId != EconomyConsts.NpcMerchantId) { EconomyScript.Instance.ServerLogger.WriteWarning("A Player \"{0}\" {1} attempted to set another Market characteristics of item {2}/{3} to Quantity={4}.", SenderDisplayName, SenderSteamId, ItemTypeId, ItemSubTypeName, ItemQuantity); return; } // TODO: do we check range to market? MyDefinitionBase definition = null; MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(ItemTypeId, out result)) { var id = new MyDefinitionId(result, ItemSubTypeName); MyDefinitionManager.Static.TryGetDefinition(id, out definition); } if (definition == null) { // Passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Sorry, the item you specified doesn't exist!"); return; } if (SetType.HasFlag(SetMarketItemType.Quantity)) { // Do a floating point check on the item item. Tools and components cannot have decimals. They must be whole numbers. if (definition.Id.TypeId != typeof(MyObjectBuilder_Ore) && definition.Id.TypeId != typeof(MyObjectBuilder_Ingot)) { if (ItemQuantity != Math.Truncate(ItemQuantity)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "You must provide a whole number for the quantity of that item."); return; } //ItemQuantity = Math.Round(ItemQuantity, 0); // Or do we just round the number? } if (ItemQuantity <= 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Invalid quantity specified"); return; } } // Find the specified market. List <MarketStruct> markets; if (string.IsNullOrEmpty(MarketZone)) { var character = player.GetCharacter(); if (character == null) { // Player has no body. Could mean they are dead. MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "There is no market at your location to set."); return; } var position = ((IMyEntity)character).WorldMatrix.Translation; markets = MarketManager.FindMarketsFromLocation(position).Where(m => m.MarketId == MarketId).ToList(); } else { markets = EconomyScript.Instance.Data.Markets.Where(m => m.MarketId == MarketId && (MarketZone == "*" || m.DisplayName.Equals(MarketZone, StringComparison.InvariantCultureIgnoreCase))).ToList(); } if (markets.Count == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Sorry, you are not near any markets currently or the market does not exist!"); return; } var msg = new StringBuilder(); msg.AppendFormat("Applying changes to : '{0}' {1}/{2}\r\n\r\n", definition.GetDisplayName(), ItemTypeId, ItemSubTypeName); foreach (var market in markets) { msg.AppendFormat("Market: '{0}'\r\n", market.DisplayName); var marketItem = market.MarketItems.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); if (marketItem == null) { msg.AppendLine("Sorry, the items you are trying to set doesn't have a market entry!"); // In reality, this shouldn't happen as all markets have their items synced up on start up of the mod. continue; } if (SetType.HasFlag(SetMarketItemType.Quantity)) { marketItem.Quantity = ItemQuantity; msg.AppendFormat("Stock on hand to {0} units", ItemQuantity); } // Validation to prevent admins setting prices too low for items. if (SetType.HasFlag(SetMarketItemType.BuyPrice)) { if (ItemBuyPrice >= 0) { marketItem.BuyPrice = ItemBuyPrice; msg.AppendFormat("Buy price to {0}", ItemBuyPrice); } else { msg.AppendFormat("Could not set buy price to less than 0."); } } // Validation to prevent admins setting prices too low for items. if (SetType.HasFlag(SetMarketItemType.SellPrice)) { if (ItemSellPrice >= 0) { marketItem.SellPrice = ItemSellPrice; msg.AppendFormat("Sell price to {0}", ItemSellPrice); } else { msg.AppendFormat("Could not set sell price to less than 0."); } } if (SetType.HasFlag(SetMarketItemType.Blacklisted)) { marketItem.IsBlacklisted = !marketItem.IsBlacklisted; msg.AppendFormat("Blacklist to {0}", marketItem.IsBlacklisted ? "On" : "Off"); } msg.AppendLine(); msg.AppendLine(); } #region update config for the item MarketItemStruct configItem = null; if (player.IsAdmin() && MarketId == EconomyConsts.NpcMerchantId) { configItem = EconomyScript.Instance.ServerConfig.DefaultPrices.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); } if (configItem != null) { if (SetType.HasFlag(SetMarketItemType.BuyPrice)) { if (ItemBuyPrice >= 0) { configItem.BuyPrice = ItemBuyPrice; msg.AppendFormat("Config updated Buy price to {0}", ItemBuyPrice); } } // Validation to prevent admins setting prices too low for items. if (SetType.HasFlag(SetMarketItemType.SellPrice)) { if (ItemSellPrice >= 0) { configItem.SellPrice = ItemSellPrice; msg.AppendFormat("Config updated Sell price to {0}", ItemSellPrice); } } if (SetType.HasFlag(SetMarketItemType.Blacklisted)) { configItem.IsBlacklisted = !configItem.IsBlacklisted; msg.AppendFormat("Config updated Blacklist to {0}", configItem.IsBlacklisted ? "On" : "Off"); // If config blacklisted, then all markets should be updated. if (configItem.IsBlacklisted) { int counter = 0; foreach (var market in EconomyScript.Instance.Data.Markets) { var marketItem = market.MarketItems.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); if (marketItem != null && !marketItem.IsBlacklisted) { counter++; marketItem.IsBlacklisted = true; } } msg.AppendFormat("Config updated {0} Markets to also Blacklist to {1}.", counter, configItem.IsBlacklisted ? "On" : "Off"); } } } #endregion MessageClientDialogMessage.SendMessage(SenderSteamId, "SET", " ", msg.ToString()); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Manage Npc Market Request for from '{0}'", SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); if (player == null || !player.IsAdmin()) // hold on there, are we an admin first? { return; } switch (CommandType) { case NpcMarketManage.Add: { if (string.IsNullOrWhiteSpace(MarketName) || MarketName == "*") { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC ADD", "Invalid name supplied for the market name."); return; } var checkMarket = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.DisplayName.Equals(MarketName, StringComparison.InvariantCultureIgnoreCase)); if (checkMarket != null) { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC ADD", "A market of name '{0}' already exists.", checkMarket.DisplayName); return; } // TODO: market inside market check? EconDataManager.CreateNpcMarket(MarketName, X, Y, Z, Size, Shape); MessageClientTextMessage.SendMessage(SenderSteamId, "NPC ADD", "A new market called '{0}' has been created.", MarketName); } break; case NpcMarketManage.Delete: { var market = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.DisplayName.Equals(MarketName, StringComparison.InvariantCultureIgnoreCase)); if (market == null) { var markets = EconomyScript.Instance.Data.Markets.Where(m => m.DisplayName.IndexOf(MarketName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray(); if (markets.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC DELETE", "The specified market name could not be found."); return; } if (markets.Length > 1) { var str = new StringBuilder(); str.Append("The specified market name could not be found.\r\n Which did you mean?\r\n"); foreach (var m in markets) { str.AppendLine(m.DisplayName); } MessageClientDialogMessage.SendMessage(SenderSteamId, "NPC DELETE", " ", str.ToString()); return; } market = markets[0]; } EconomyScript.Instance.Data.Markets.Remove(market); MessageClientTextMessage.SendMessage(SenderSteamId, "NPC DELETE", "The market '{0}' has been removed and all inventory.", market.DisplayName); } break; case NpcMarketManage.List: { var str = new StringBuilder(); foreach (var market in EconomyScript.Instance.Data.Markets) { if (market.MarketId != EconomyConsts.NpcMerchantId) { continue; } str.AppendFormat("Market: {0}\r\n", market.DisplayName); str.AppendFormat("{0}", market.MarketZoneType); if (market.MarketZoneType == MarketZoneType.FixedSphere && market.MarketZoneSphere.HasValue) { str.AppendFormat(" Center Position=X:{0:N} | Y:{1:N} | Z:{2:N} Radius={3:N}m\r\n\r\n", market.MarketZoneSphere.Value.Center.X, market.MarketZoneSphere.Value.Center.Y, market.MarketZoneSphere.Value.Center.Z, market.MarketZoneSphere.Value.Radius); } else if (market.MarketZoneType == MarketZoneType.FixedBox && market.MarketZoneBox.HasValue) { str.AppendFormat(" Center Position=X:{0:N} | Y:{1:N} | Z:{2:N} Size={3:N}m\r\n\r\n", market.MarketZoneBox.Value.Center.X, market.MarketZoneBox.Value.Center.Y, market.MarketZoneBox.Value.Center.Z, market.MarketZoneBox.Value.Size.X); } else { str.AppendLine("\r\n"); } } MessageClientDialogMessage.SendMessage(SenderSteamId, "NPC Market List", " ", str.ToString()); } break; case NpcMarketManage.Rename: { var market = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.DisplayName.Equals(OldMarketName, StringComparison.InvariantCultureIgnoreCase)); if (market == null) { var markets = EconomyScript.Instance.Data.Markets.Where(m => m.DisplayName.IndexOf(OldMarketName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray(); if (markets.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC RENAME", "The specified market name could not be found."); return; } if (markets.Length > 1) { var str = new StringBuilder(); str.Append("The specified market name could not be found.\r\n Which did you mean?\r\n"); foreach (var m in markets) { str.AppendLine(m.DisplayName); } MessageClientDialogMessage.SendMessage(SenderSteamId, "NPC RENAME", " ", str.ToString()); return; } market = markets[0]; } if (string.IsNullOrWhiteSpace(MarketName) || MarketName == "*") { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC RENAME", "Invalid name supplied for the market name."); return; } var checkMarket = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.DisplayName.Equals(MarketName, StringComparison.InvariantCultureIgnoreCase)); if (checkMarket != null) { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC RENAME", "A market of name '{0}' already exists.", checkMarket.DisplayName); return; } var oldName = market.DisplayName; market.DisplayName = MarketName; MessageClientTextMessage.SendMessage(SenderSteamId, "NPC RENAME", "The market '{0}' has been renamed to '{1}.", oldName, market.DisplayName); } break; case NpcMarketManage.Move: { var market = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.DisplayName.Equals(MarketName, StringComparison.InvariantCultureIgnoreCase)); if (market == null) { var markets = EconomyScript.Instance.Data.Markets.Where(m => m.DisplayName.IndexOf(MarketName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray(); if (markets.Length == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "NPC MOVE", "The specified market name could not be found."); return; } if (markets.Length > 1) { var str = new StringBuilder(); str.Append("The specified market name could not be found.\r\n Which did you mean?\r\n"); foreach (var m in markets) { str.AppendLine(m.DisplayName); } MessageClientDialogMessage.SendMessage(SenderSteamId, "NPC MOVE", " ", str.ToString()); return; } market = markets[0]; } EconDataManager.SetMarketShape(market, X, Y, Z, Size, Shape); MessageClientTextMessage.SendMessage(SenderSteamId, "NPC MOVE", "The market '{0}' has been moved and resized.", market.DisplayName); } break; } }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Manage Player Mission from '{0}'", SenderSteamId); switch (CommandType) { case PlayerMissionManage.Test: //EconomyScript.Instance.ServerLogger.WriteVerbose("Mission Text request '{0}' from '{1}'", MissionID, SenderSteamId); MessageClientTextMessage.SendMessage(SenderSteamId, "mission", (MissionId + " server side")); break; case PlayerMissionManage.AddSample: { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var playerMatrix = player.Character.WorldMatrix; //var position = player.Character.GetPosition(); Vector3D position = playerMatrix.Translation + playerMatrix.Forward * 60f; MissionBaseStruct newMission = CreateMission(new TravelMission { AreaSphere = new BoundingSphereD(position, 50), //AreaSphere = new BoundingSphereD(new Vector3D(0, 0, 0), 50), Reward = 100, }, SenderSteamId); ConnectionHelper.SendMessageToPlayer(SenderSteamId, new MessageMission { CommandType = PlayerMissionManage.AddMission, Mission = newMission }); } break; case PlayerMissionManage.AddMission: // Nothing should happen here, because the server sends missions to the client, not the other way. break; case PlayerMissionManage.SyncMission: // TODO: sync details back from the client to the server. break; case PlayerMissionManage.DeleteMission: // TODO: Delete the mission. break; case PlayerMissionManage.MissionComplete: // This should process the mission reward if appropriate and then delete from server. // We aren't archiving finished missions. MissionBaseStruct serverinstanceMission = GetMission(Mission.MissionId); if (serverinstanceMission != null && serverinstanceMission.PlayerId == SenderSteamId) { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); if (player != null) { // we look up our bank record based on our Steam Id/ // create balance if not one already, then add our reward and update client. var myaccount = AccountManager.FindOrCreateAccount(SenderSteamId, player.DisplayName, SenderLanguage); EconomyScript.Instance.Data.CreditBalance -= serverinstanceMission.Reward; myaccount.BankBalance += serverinstanceMission.Reward; myaccount.Date = DateTime.Now; MessageUpdateClient.SendAccountMessage(myaccount); } RemoveMission(serverinstanceMission); } break; } }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("ShipSale Request for {0} from '{1}'", EntityId, SenderSteamId); if (!EconomyScript.Instance.ServerConfig.ShipTrading) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Trading of ships is not enabled."); return; } var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.GetCharacter(); if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You are dead. You cant trade ships while dead."); return; } if (!MyAPIGateway.Entities.EntityExists(EntityId)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Sorry, the entity no longer exists!"); return; } var selectedShip = MyAPIGateway.Entities.GetEntityById(EntityId) as IMyCubeGrid; if (selectedShip == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Sorry, the entity no longer exists!"); return; } if (Ctype == "sell") { if (Amount > 0) { decimal amount = 0; if (selectedShip != null) { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check == 0) { int terminalBlocks = 0; int armorBlocks = 0; int gridCount = 0; int owned = 0; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background start"); try { var grids = selectedShip.GetAttachedGrids(AttachedGrids.Static); gridCount = grids.Count; foreach (var grid in grids) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { MyCubeBlockDefinition blockDefintion; if (block.FatBlock == null) { armorBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.GetObjectBuilder()); } else { if (block.FatBlock.OwnerId != 0) { terminalBlocks++; if (block.FatBlock.OwnerId == player.IdentityId) { owned++; } } } } } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background end"); }, delegate() // when the background processing is finished, this block will run foreground. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:foreground"); try { if (owned > (terminalBlocks * (EconomyConsts.ShipOwned / 100))) { ShipManager.CreateSellOrder(player.IdentityId, SenderSteamId, selectedShip.EntityId, Amount); MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship put up for sale for " + Amount); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You need to own more than {0}% of the ship to sell it.", EconomyConsts.ShipOwned); } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } }); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship already for sale for " + check + "."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You need to target a ship or station to sell."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You need to specify a price"); } } else if (Ctype == "cancel") { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check != 0) { var owner = ShipManager.GetOwner(selectedShip.EntityId); if (owner == SenderSteamId) { var removed = ShipManager.Remove(selectedShip.EntityId, SenderSteamId); if (removed) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship sale Removed."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Your are not the sale creator."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship not for sale."); } } else if (Ctype == "buy") { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check != 0) { if (check == Amount) { int terminalBlocks = 0; int armorBlocks = 0; int gridCount = 0; int owned = 0; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background start"); try { var grids = selectedShip.GetAttachedGrids(AttachedGrids.Static); gridCount = grids.Count; var owner = ShipManager.GetOwner(selectedShip.EntityId); var ownerid = ShipManager.GetOwnerId(selectedShip.EntityId); foreach (var grid in grids) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { MyCubeBlockDefinition blockDefintion; if (block.FatBlock == null) { armorBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.GetObjectBuilder()); } else { if (block.FatBlock.OwnerId != 0) { terminalBlocks++; if (block.FatBlock.OwnerId == ownerid) { owned++; } } } } } if (owned > (terminalBlocks / 2)) { var accountseller = AccountManager.FindAccount(owner); var accountbuyer = AccountManager.FindAccount(SenderSteamId); if (accountbuyer.BankBalance >= Amount) { accountbuyer.BankBalance -= Amount; accountbuyer.Date = DateTime.Now; accountseller.BankBalance += Amount; accountseller.Date = DateTime.Now; MessageUpdateClient.SendAccountMessage(accountbuyer); MessageUpdateClient.SendAccountMessage(accountseller); foreach (var grid in grids) { grid.ChangeGridOwnership(player.IdentityId, MyOwnershipShareModeEnum.All); var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { MyCubeBlockDefinition blockDefintion; if (block.FatBlock == null) { armorBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.GetObjectBuilder()); } else { terminalBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.FatBlock.BlockDefinition); (block.FatBlock as MyCubeBlock).ChangeOwner(0, MyOwnershipShareModeEnum.Faction); (block.FatBlock as MyCubeBlock).ChangeBlockOwnerRequest(player.IdentityId, MyOwnershipShareModeEnum.Faction); } } } var removed = ShipManager.Remove(selectedShip.EntityId, owner); MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship purchased."); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You cant afford that."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "The seller no longer owns more than 50% of the ship."); } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } // remove from sale // remove money and give previous owner EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background end"); }, delegate() // when the background processing is finished, this block will run foreground. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:foreground"); try { var str = new StringBuilder(); //foreach (var kvp in gridComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //foreach (var kvp in inventoryComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //var prefix = string.Format("{0:#,##0.00000}", totalValue); var shipSale = ShipManager.CheckSellOrder(selectedShip.EntityId); str.AppendFormat("{0}: {1}\r\n", selectedShip.IsStatic ? "Station" : selectedShip.GridSizeEnum.ToString() + " Ship", selectedShip.DisplayName); str.AppendFormat("Grids={2}\r\nArmor Blocks={0}\r\nTerminal Blocks={1}\r\n", armorBlocks, terminalBlocks, gridCount); str.AppendLine("-----------------------------------"); if (shipSale != 0) { str.AppendFormat("Sale Price: {0:#,##0.00000} {1}.\r\n", shipSale, EconomyScript.Instance.ServerConfig.CurrencyName); } else { str.AppendLine("Sale Price: Not for Sale.\r\n"); } // MessageClientDialogMessage.SendMessage(SenderSteamId, "ShipSale", selectedShip.DisplayName, str.ToString()); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } }); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship is on sale for " + check); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship not for sale"); } } }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Price List Request for from '{0}'", SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.GetCharacter(); if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "You are dead. You get market items values while dead."); return; } List <MarketStruct> markets; if (string.IsNullOrEmpty(FindMarket)) { var position = ((IMyEntity)character).WorldMatrix.Translation; markets = MarketManager.FindMarketsFromLocation(position); } else { markets = MarketManager.FindMarketsFromName(FindMarket); } if (markets.Count == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Sorry, your are not in range of any markets!"); return; } // TODO: combine multiple markets to list best Buy and Sell prices that isn't blacklisted. var market = markets.FirstOrDefault(); if (market == null) //hmmm looks like market name parameter checking was started but never done { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "That market does not exist."); return; //as I understand it this would only trigger if no markets are defined? //in which case should it read no markets exist? but in that case // wont the count check above halt execution before this if statement??? // remove these comments once read :) } string reply = null; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { try { bool showAll = !ShowOre && !ShowIngot && !ShowComponent && !ShowAmmo && !ShowTools && !ShowGasses; var orderedList = new Dictionary <MarketItemStruct, string>(); foreach (var marketItem in market.MarketItems) { if (marketItem.IsBlacklisted) { continue; } MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(marketItem.TypeId, out result)) { var id = new MyDefinitionId(result, marketItem.SubtypeName); var content = Support.ProducedType(id); // Cannot check the Type of the item, without having to use MyObjectBuilderSerializer.CreateNewObject(). if (showAll || (ShowOre && content is MyObjectBuilder_Ore) || (ShowIngot && content is MyObjectBuilder_Ingot) || (ShowComponent && content is MyObjectBuilder_Component) || (ShowAmmo && content is MyObjectBuilder_AmmoMagazine) || (ShowTools && content is MyObjectBuilder_PhysicalGunObject) || // guns, welders, hand drills, grinders. (ShowGasses && content is MyObjectBuilder_GasContainerObject) || // aka gas bottle. (ShowGasses && content is MyObjectBuilder_GasProperties)) // Type check here allows mods that inherit from the same type to also appear in the lists. { var definition = MyDefinitionManager.Static.GetDefinition(marketItem.TypeId, marketItem.SubtypeName); var name = definition == null ? marketItem.SubtypeName : definition.GetDisplayName(); orderedList.Add(marketItem, name); } } } orderedList = orderedList.OrderBy(kvp => kvp.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var str = new SeTextBuilder(); str.AppendLine("Market: {0}\r\n", market.DisplayName); str.AddLeftTrim(550, "Item"); str.AddRightText(650, "Buy at"); str.AddRightText(850, "Sell at"); str.AppendLine(); foreach (var kvp in orderedList) { decimal showBuy = kvp.Key.BuyPrice; decimal showSell = kvp.Key.SellPrice; if ((EconomyScript.Instance.ServerConfig.PriceScaling) && (market.MarketId == EconomyConsts.NpcMerchantId)) { showBuy = EconDataManager.PriceAdjust(kvp.Key.BuyPrice, kvp.Key.Quantity, PricingBias.Buy); showSell = EconDataManager.PriceAdjust(kvp.Key.SellPrice, kvp.Key.Quantity, PricingBias.Sell); } // TODO: formatting of numbers, and currency name. str.AddLeftTrim(550, kvp.Value); str.AddRightText(650, showBuy.ToString("0.00", EconomyScript.ServerCulture)); str.AddRightText(850, showSell.ToString("0.00", EconomyScript.ServerCulture)); str.AppendLine(); } reply = str.ToString(); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Failed and died. Please contact the administrator."); } }, delegate() // when the background processing is finished, this block will run foreground. { if (reply != null) { try { MessageClientDialogMessage.SendMessage(SenderSteamId, "PRICELIST", " ", reply); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Failed and died. Please contact the administrator."); } } }); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Price List Request for from '{0}'", SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.GetCharacter(); if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "You are dead. You get market items values while dead."); return; } var position = ((IMyEntity)character).WorldMatrix.Translation; var markets = MarketManager.FindMarketsFromLocation(position); if (markets.Count == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Sorry, your are not in range of any markets!"); return; } // TODO: combine multiple markets to list best Buy and Sell prices that isn't blacklisted. var market = markets.FirstOrDefault(); if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "That market does not exist."); return; } string reply = null; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { try { bool showAll = !ShowOre && !ShowIngot && !ShowComponent && !ShowAmmo && !ShowTools; var orderedList = new Dictionary <MarketItemStruct, string>(); foreach (var marketItem in market.MarketItems) { if (marketItem.IsBlacklisted) { continue; } MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(marketItem.TypeId, out result)) { var id = new MyDefinitionId(result, marketItem.SubtypeName); var content = Support.ProducedType(id); // Cannot check the Type of the item, without having to use MyObjectBuilderSerializer.CreateNewObject(). if (showAll || (ShowOre && content is MyObjectBuilder_Ore) || (ShowIngot && content is MyObjectBuilder_Ingot) || (ShowComponent && content is MyObjectBuilder_Component) || (ShowAmmo && content is MyObjectBuilder_AmmoMagazine) || (ShowTools && content is MyObjectBuilder_PhysicalGunObject) || (ShowTools && content is MyObjectBuilder_GasContainerObject)) // Type check here allows mods that inherit from the same type to also appear in the lists. { var definition = MyDefinitionManager.Static.GetDefinition(marketItem.TypeId, marketItem.SubtypeName); var name = definition == null ? marketItem.SubtypeName : definition.GetDisplayName(); orderedList.Add(marketItem, name); } } } orderedList = orderedList.OrderBy(kvp => kvp.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var str = new SeTextBuilder(); str.AppendLine("Market: {0}\r\n", market.DisplayName); str.AddLeftTrim(550, "Item"); str.AddRightText(650, "Buy at"); str.AddRightText(850, "Sell at"); str.AppendLine(); foreach (var kvp in orderedList) { // TODO: formatting of numbers, and currency name. str.AddLeftTrim(550, kvp.Value); str.AddRightText(650, kvp.Key.BuyPrice.ToString("0.00", EconomyScript.ServerCulture)); str.AddRightText(850, kvp.Key.SellPrice.ToString("0.00", EconomyScript.ServerCulture)); str.AppendLine(); } reply = str.ToString(); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Failed and died. Please contact the administrator."); } }, delegate() // when the background processing is finished, this block will run foreground. { if (reply != null) { try { MessageClientDialogMessage.SendMessage(SenderSteamId, "PRICELIST", " ", reply); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "PRICELIST", "Failed and died. Please contact the administrator."); } } }); }
public override void ProcessServer() { EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy started by Steam Id '{0}'.", SenderSteamId); // Get player steam ID var buyingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); MyPhysicalItemDefinition definition = null; MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(ItemTypeId, out result)) { var id = new MyDefinitionId(result, ItemSubTypeName); MyDefinitionManager.Static.TryGetPhysicalItemDefinition(id, out definition); } if (definition == null) { // Someone hacking, and passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, the item you specified doesn't exist!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- item doesn't exist.", SenderSteamId); return; } // Do a floating point check on the item item. Tools and components cannot have decimals. They must be whole numbers. if (definition.Id.TypeId != typeof(MyObjectBuilder_Ore) && definition.Id.TypeId != typeof(MyObjectBuilder_Ingot)) { if (ItemQuantity != Math.Truncate(ItemQuantity)) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You must provide a whole number for the quantity to buy that item."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- invalid qantity.", SenderSteamId); return; } //ItemQuantity = Math.Round(ItemQuantity, 0); // Or do we just round the number? } if (ItemQuantity <= 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You must provide a valid quantity to buy."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- invalid qantity.", SenderSteamId); return; } // Who are we buying to? BankAccountStruct accountToSell; if (BuyFromMerchant) { accountToSell = AccountManager.FindAccount(EconomyConsts.NpcMerchantId); } else { accountToSell = AccountManager.FindAccount(FromUserName); } if (accountToSell == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, player does not exist or have an account!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- no account.", SenderSteamId); return; } if (MarketManager.IsItemBlacklistedOnServer(ItemTypeId, ItemSubTypeName)) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, the item you tried to buy is blacklisted on this server."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- item blacklisted.", SenderSteamId); return; } // Get the player's inventory, regardless of if they are in a ship, or a remote control cube. var character = buyingPlayer.GetCharacter(); // TODO: do players in Cryochambers count as a valid trading partner? They should be alive, but the connected player may be offline. // I think we'll have to do lower level checks to see if a physical player is Online. if (character == null) { // Player has no body. Could mean they are dead. // Either way, there is no inventory. MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You are dead. You cannot trade while dead."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- player is dead.", SenderSteamId); return; } // TODO: is a null check adaqaute?, or do we need to check for IsDead? // I don't think the chat console is accessible during respawn, only immediately after death. // Is it valid to be able to trade when freshly dead? //var identity = buyingPlayer.Identity(); //MyAPIGateway.Utilities.ShowMessage("CHECK", "Is Dead: {0}", identity.IsDead); //if (identity.IsDead) //{ // MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You are dead. You cannot trade while dead."); // return; //} var position = ((IMyEntity)character).WorldMatrix.Translation; MarketItemStruct marketItem = null; if (BuyFromMerchant || UseBankSellPrice) { var markets = MarketManager.FindMarketsFromLocation(position); if (markets.Count == 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, your are not in range of any markets!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- no market in range.", SenderSteamId); return; } // TODO: find market with best Sell price that isn't blacklisted. var market = markets.FirstOrDefault(); if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, the market you are accessing does not exist!"); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- no market found.", SenderSteamId); return; } marketItem = market.MarketItems.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); if (marketItem == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, the items you are trying to buy doesn't have a market entry!"); // In reality, this shouldn't happen as all markets have their items synced up on start up of the mod. return; } if (marketItem.IsBlacklisted) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, the item you tried to buy is blacklisted in this market."); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- item is blacklisted in market.", SenderSteamId); return; } // Verify that the items are in the player inventory. // TODO: later check trade block, cockpit inventory, cockpit ship inventory, inventory of targeted cube. if (UseBankSellPrice) { // The player is buying, but the *Market* will *sell* it to the player at this price. ItemPrice = marketItem.SellPrice; } } var accountToBuy = AccountManager.FindOrCreateAccount(SenderSteamId, SenderDisplayName, SenderLanguage); var transactionAmount = ItemPrice * ItemQuantity; // need fix negative amounts before checking if the player can afford it. if (!buyingPlayer.IsAdmin()) { transactionAmount = Math.Abs(transactionAmount); } // TODO: admin check on ability to afford it? //[maybe later, our pay and reset commands let us steal money from npc anyway best to keep admin abuse features to minimum] //[we could put an admin check on blacklist however, allow admins to spawn even blacklisted gear] if (accountToBuy.BankBalance < transactionAmount) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, you cannot afford {0} {1}!", transactionAmount, EconomyScript.Instance.Config.CurrencyName); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- not enough money.", SenderSteamId); return; } if (BuyFromMerchant) // and supply is not exhausted, or unlimited mode is not on. //This is a quick fix, ideally it should do a partial buy of what is left and post a buy offer for remainder { // here we look up item price and transfer items and money as appropriate if (marketItem.Quantity >= ItemQuantity || !EconomyScript.Instance.Config.LimitedSupply) { marketItem.Quantity -= ItemQuantity; // reduce Market content. EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy finalizing by Steam Id '{0}' -- adding to inventory.", SenderSteamId); var remainingToCollect = MessageSell.AddToInventories(buyingPlayer, ItemQuantity, definition.Id); //EconomyScript.Instance.Config.LimitedSupply accountToSell.BankBalance += transactionAmount; accountToSell.Date = DateTime.Now; accountToBuy.BankBalance -= transactionAmount; accountToBuy.Date = DateTime.Now; MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "You just purchased {1} '{2}' for {0} {3}", transactionAmount, ItemQuantity, definition.GetDisplayName(), EconomyScript.Instance.Config.CurrencyName); if (remainingToCollect > 0) { MarketManager.CreateStockHeld(buyingPlayer.SteamUserId, ItemTypeId, ItemSubTypeName, remainingToCollect, ItemPrice); // TODO: there should be a common command to collect items. Not use /sell. MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "There are {0} remaining to collect. Use '/sell collect'", remainingToCollect); } EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy complete by Steam Id '{0}' -- items bought.", SenderSteamId); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "There isn't '{0}' of {1} available to purchase! Only {2} available to buy!", ItemQuantity, definition.GetDisplayName(), marketItem.Quantity); EconomyScript.Instance.ServerLogger.WriteVerbose("Action /Buy aborted by Steam Id '{0}' -- not enough stock.", SenderSteamId); } return; } else if (FindOnMarket) { // TODO: Here we find the best offer on the zone market return; } else { // is it a player then? if (accountToSell.SteamId == buyingPlayer.SteamUserId) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, you cannot buy from yourself!"); return; } // check if selling player is online and in range? var payingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(accountToSell.SteamId); if (EconomyScript.Instance.Config.LimitedRange && !Support.RangeCheck(buyingPlayer, payingPlayer)) { MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Sorry, you are not in range of that player!"); return; } if (payingPlayer == null) { // TODO: other player offline. } else { // TODO: other player is online. } } // this is a fall through from the above conditions not yet complete. MessageClientTextMessage.SendMessage(SenderSteamId, "BUY", "Not yet complete."); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("Worth Request for {0} from '{1}'", EntityId, SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.GetCharacter(); if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "You are dead. You get market items values while dead."); return; } var position = ((IMyEntity)character).WorldMatrix.Translation; var markets = MarketManager.FindMarketsFromLocation(position); // TODO: find market with best Buy price that isn't blacklisted. var market = markets.FirstOrDefault(); string marketDetail = null; if (market == null) { market = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.MarketId == EconomyConsts.NpcMerchantId); if (market != null) { marketDetail = string.Format("No markets in range, using default market '{0}' for appraisal.", market.DisplayName); } } if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "That market does not exist."); return; } if (marketDetail == null) { marketDetail = string.Format("Using market '{0}' for appraisal.", market.DisplayName); } if (!MyAPIGateway.Entities.EntityExists(EntityId)) { MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "Sorry, the entity no longer exists!"); return; } var selectedShip = MyAPIGateway.Entities.GetEntityById(EntityId) as IMyCubeGrid; if (selectedShip == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "Sorry, the entity no longer exists!"); return; } int terminalBlocks = 0; int armorBlocks = 0; decimal shipValue = 0; decimal inventoryValue = 0; int gridCount = 0; var gridComponents = new Dictionary <MyDefinitionId, decimal>(); var inventoryComponents = new Dictionary <MyDefinitionId, decimal>(); MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "Calculating the worth..."); MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { EconomyScript.Instance.ServerLogger.WriteInfo("Worth:background start"); try { var grids = selectedShip.GetAttachedGrids(AttachedGrids.Static); gridCount = grids.Count; foreach (var grid in grids) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { MyCubeBlockDefinition blockDefintion; if (block.FatBlock == null) { armorBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.GetObjectBuilder()); } else { terminalBlocks++; blockDefintion = MyDefinitionManager.Static.GetCubeBlockDefinition(block.FatBlock.BlockDefinition); } //EconomyScript.Instance.ServerLogger.Write("Cube Worth '{0}' '{1}' {2} {3}.", blockDefintion.Id.TypeId, blockDefintion.Id.SubtypeName, block.BuildIntegrity, block.BuildLevelRatio); #region Go through component List based on construction level. foreach (var component in blockDefintion.Components) { //EconomyScript.Instance.ServerLogger.Write("Component Worth '{0}' '{1}' x {2}.", component.Definition.Id.TypeId, component.Definition.Id.SubtypeName, component.Count); if (!gridComponents.ContainsKey(component.Definition.Id)) { gridComponents.Add(component.Definition.Id, 0); } gridComponents[component.Definition.Id] += component.Count; } // This will subtract off components missing from a partially built cube. // This also includes the Construction Inventory. var missingComponents = new Dictionary <string, int>(); block.GetMissingComponents(missingComponents); foreach (var kvp in missingComponents) { var definitionid = new MyDefinitionId(typeof(MyObjectBuilder_Component), kvp.Key); gridComponents[definitionid] -= kvp.Value; } #endregion if (block.FatBlock != null) { var cube = (MyEntity)block.FatBlock; #region Go through Gasses for tanks and cockpits. var tank = cube as IMyGasTank; var gasTankDefintion = blockDefintion as MyGasTankDefinition; if (gasTankDefintion != null && tank != null) { decimal volume = (decimal)gasTankDefintion.Capacity * (decimal)tank.FilledRatio; if (!inventoryComponents.ContainsKey(gasTankDefintion.StoredGasId)) { inventoryComponents.Add(gasTankDefintion.StoredGasId, 0); } inventoryComponents[gasTankDefintion.StoredGasId] += volume; //MessageClientTextMessage.SendMessage(SenderSteamId, "GAS tank", "{0} detected {1}", gasTankDefintion.StoredGasId, volume); } // Check through Cockpits. var cockpit = cube as Sandbox.Game.Entities.MyCockpit; // For some reason, the o2 is on the MyCockpit Class. There is no Interface. if (cockpit != null) { // Hardcoded, because Oxygen and Hydrogen do not have available defintions. var oxygenDefintion = new MyDefinitionId(typeof(MyObjectBuilder_GasProperties), "Oxygen"); if (!inventoryComponents.ContainsKey(oxygenDefintion)) { inventoryComponents.Add(oxygenDefintion, 0); } inventoryComponents[oxygenDefintion] += (decimal)cockpit.OxygenAmount; //MessageClientTextMessage.SendMessage(SenderSteamId, "COCKPIT tank", "{0} detected {1}", null, cockpit.OxygenAmount); } #endregion #region Go through all other Inventories for components/items. // Inventory check based on normal game access. var relation = block.FatBlock.GetUserRelationToOwner(player.IdentityId); if (relation != MyRelationsBetweenPlayerAndBlock.Enemies && relation != MyRelationsBetweenPlayerAndBlock.Neutral) { for (var i = 0; i < cube.InventoryCount; i++) { var inventory = cube.GetInventory(i); var list = inventory.GetItems(); foreach (var item in list) { var id = item.Content.GetId(); if (!inventoryComponents.ContainsKey(id)) { inventoryComponents.Add(id, 0); } inventoryComponents[id] += (decimal)item.Amount; // Go through Gas bottles. var gasContainer = item.Content as MyObjectBuilder_GasContainerObject; if (gasContainer != null) { var defintion = (MyOxygenContainerDefinition)MyDefinitionManager.Static.GetPhysicalItemDefinition(item.Content.GetId()); decimal volume = (decimal)defintion.Capacity * (decimal)gasContainer.GasLevel; if (!inventoryComponents.ContainsKey(defintion.StoredGasId)) { inventoryComponents.Add(defintion.StoredGasId, 0); } inventoryComponents[defintion.StoredGasId] += volume; //MessageClientTextMessage.SendMessage(SenderSteamId, "GAS bottle", "{0} detected {1}", defintion.StoredGasId, volume); } } } } #endregion } } } shipValue += SumComponents(market, gridComponents); inventoryValue += SumComponents(market, inventoryComponents); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "Failed and died. Please contact the administrator."); } EconomyScript.Instance.ServerLogger.WriteInfo("Worth:background end"); }, delegate() // when the background processing is finished, this block will run foreground. { EconomyScript.Instance.ServerLogger.WriteInfo("Worth:foreground"); try { var str = new StringBuilder(); //foreach (var kvp in gridComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //foreach (var kvp in inventoryComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //var prefix = string.Format("{0:#,##0.00000}", totalValue); var shipSale = ShipManager.CheckSellOrder(selectedShip.EntityId); str.AppendLine(marketDetail); str.AppendFormat("{0}: {1}\r\n", selectedShip.IsStatic ? "Station" : selectedShip.GridSizeEnum.ToString() + " Ship", selectedShip.DisplayName); str.AppendFormat("Grids={2}\r\nArmor Blocks={0}\r\nTerminal Blocks={1}\r\n", armorBlocks, terminalBlocks, gridCount); str.AppendLine("-----------------------------------"); str.AppendFormat("Ship Value: {0:#,##0.00000} {1}.\r\n", shipValue, EconomyScript.Instance.ServerConfig.CurrencyName); str.AppendFormat("Inventory Value: {0:#,##0.00000} {1}.\r\n", inventoryValue, EconomyScript.Instance.ServerConfig.CurrencyName); str.AppendFormat("Final Value: {0:#,##0.00000} {1}.\r\n", shipValue + inventoryValue, EconomyScript.Instance.ServerConfig.CurrencyName); str.AppendLine("-----------------------------------"); if (shipSale != 0) { str.AppendFormat("Sale Price: {0:#,##0.00000} {1}.\r\n", shipSale, EconomyScript.Instance.ServerConfig.CurrencyName); } else { str.AppendLine("Sale Price: Not for Sale.\r\n"); } MessageClientDialogMessage.SendMessage(SenderSteamId, "WORTH", selectedShip.DisplayName, str.ToString()); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "WORTH", "Failed and died. Please contact the administrator."); } }); }
public override void ProcessServer() { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); // Only Admin can change Npc Market prices. if (!player.IsAdmin() && MarketId == EconomyConsts.NpcMerchantId) { EconomyScript.Instance.ServerLogger.WriteWarning("A Player without Admin \"{0}\" {1} attempted to set Default Market characteristics of item {2}/{3} to Quantity={4}.", SenderDisplayName, SenderSteamId, ItemTypeId, ItemSubTypeName, ItemQuantity); return; } // Only Player can change their own Market prices. if (SenderSteamId != MarketId && MarketId != EconomyConsts.NpcMerchantId) { EconomyScript.Instance.ServerLogger.WriteWarning("A Player \"{0}\" {1} attempted to set another Market characteristics of item {2}/{3} to Quantity={4}.", SenderDisplayName, SenderSteamId, ItemTypeId, ItemSubTypeName, ItemQuantity); return; } // TODO: do we check range to market? MyPhysicalItemDefinition definition = null; MyObjectBuilderType result; if (MyObjectBuilderType.TryParse(ItemTypeId, out result)) { var id = new MyDefinitionId(result, ItemSubTypeName); MyDefinitionManager.Static.TryGetPhysicalItemDefinition(id, out definition); } if (definition == null) { // Passing bad data? MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Sorry, the item you specified doesn't exist!"); return; } if (SetType.HasFlag(SetMarketItemType.Quantity)) { // Do a floating point check on the item item. Tools and components cannot have decimals. They must be whole numbers. if (definition.Id.TypeId != typeof(MyObjectBuilder_Ore) && definition.Id.TypeId != typeof(MyObjectBuilder_Ingot)) { if (ItemQuantity != Math.Truncate(ItemQuantity)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "You must provide a whole number for the quantity of that item."); return; } //ItemQuantity = Math.Round(ItemQuantity, 0); // Or do we just round the number? } if (ItemQuantity <= 0) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Invalid quantity spectified"); return; } } // Find the specified market. var market = EconomyScript.Instance.Data.Markets.FirstOrDefault(m => m.MarketId == MarketId); if (market == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Sorry, the market you are accessing does not exist!"); return; } var marketItem = market.MarketItems.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); if (marketItem == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SET", "Sorry, the items you are trying to set doesn't have a market entry!"); // In reality, this shouldn't happen as all markets have their items synced up on start up of the mod. return; } MarketItemStruct configItem = null; if (player.IsAdmin() && MarketId == EconomyConsts.NpcMerchantId) { configItem = EconomyScript.Instance.Config.DefaultPrices.FirstOrDefault(e => e.TypeId == ItemTypeId && e.SubtypeName == ItemSubTypeName); } var msg = new StringBuilder(); msg.AppendFormat("You just set '{0}'", definition.GetDisplayName()); if (SetType.HasFlag(SetMarketItemType.Quantity)) { marketItem.Quantity = ItemQuantity; msg.AppendFormat(", stock on hand to {0} units", ItemQuantity); } // Validation to prevent admins setting prices too low for items. if (SetType.HasFlag(SetMarketItemType.BuyPrice)) { if (ItemBuyPrice >= 0) { marketItem.BuyPrice = ItemBuyPrice; msg.AppendFormat(", buy price to {0}", ItemBuyPrice); if (configItem != null) { configItem.BuyPrice = ItemBuyPrice; msg.AppendFormat("; config updated."); } } else { msg.AppendFormat(", could not set buy price to less than 0."); } } // Validation to prevent admins setting prices too low for items. if (SetType.HasFlag(SetMarketItemType.SellPrice)) { if (ItemSellPrice >= 0) { marketItem.SellPrice = ItemSellPrice; msg.AppendFormat(", sell price to {0}", ItemSellPrice); if (configItem != null) { configItem.SellPrice = ItemSellPrice; msg.AppendFormat("; config updated."); } } else { msg.AppendFormat(", could not set sell price to less than 0."); } } if (SetType.HasFlag(SetMarketItemType.Blacklisted)) { marketItem.IsBlacklisted = !marketItem.IsBlacklisted; msg.AppendFormat(", blacklist to {0}", marketItem.IsBlacklisted ? "On" : "Off"); if (configItem != null) { configItem.IsBlacklisted = marketItem.IsBlacklisted; msg.AppendFormat("; config updated."); } } MessageClientTextMessage.SendMessage(SenderSteamId, "SET", msg.ToString()); }
public override void ProcessServer() { // update our own timestamp here AccountManager.UpdateLastSeen(SenderSteamId, SenderLanguage); EconomyScript.Instance.ServerLogger.WriteVerbose("ShipSale Request for {0} from '{1}'", EntityId, SenderSteamId); if (!EconomyScript.Instance.ServerConfig.ShipTrading) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Trading of ships is not enabled."); return; } var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var character = player.Character; if (character == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You are dead. You cant trade ships while dead."); return; } if (!MyAPIGateway.Entities.EntityExists(EntityId)) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Sorry, the entity no longer exists!"); return; } var selectedShip = MyAPIGateway.Entities.GetEntityById(EntityId) as IMyCubeGrid; if (selectedShip == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Sorry, the entity no longer exists!"); return; } if (Ctype == "sell") { if (Amount > 0) { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check == 0) { int terminalBlocks = 0; int armorBlocks = 0; int gridCount = 0; int owned = 0; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background start"); try { var grids = selectedShip.GetAttachedGrids(AttachedGrids.Static); gridCount = grids.Count; foreach (var grid in grids) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { if (block.FatBlock == null) { armorBlocks++; } else { if (block.FatBlock.OwnerId != 0) { terminalBlocks++; if (block.FatBlock.OwnerId == player.IdentityId) { owned++; } } } } } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background end"); }, delegate() // when the background processing is finished, this block will run foreground. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:foreground"); try { if (owned > (terminalBlocks * (EconomyConsts.ShipOwned / 100))) { ShipManager.CreateSellOrder(player.IdentityId, SenderSteamId, selectedShip.EntityId, Amount); MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship put up for sale for " + Amount); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You need to own more than {0}% of the ship to sell it.", EconomyConsts.ShipOwned); } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } }); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship already for sale for " + check + "."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You need to specify a price"); } } else if (Ctype == "cancel") { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check != 0) { var owner = ShipManager.GetOwner(selectedShip.EntityId); if (owner == SenderSteamId) { var removed = ShipManager.Remove(selectedShip.EntityId, SenderSteamId); if (removed) { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship sale Removed."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Your are not the sale creator."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship not for sale."); } } else if (Ctype == "buy") { var check = ShipManager.CheckSellOrder(selectedShip.EntityId); if (check != 0) { if (check == Amount) { int terminalBlocks = 0; int armorBlocks = 0; int gridCount = 0; int owned = 0; MyAPIGateway.Parallel.StartBackground(delegate() // Background processing occurs within this block. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background start"); try { var grids = selectedShip.GetAttachedGrids(AttachedGrids.Static); gridCount = grids.Count; var owner = ShipManager.GetOwner(selectedShip.EntityId); var ownerid = ShipManager.GetOwnerId(selectedShip.EntityId); foreach (var grid in grids) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); foreach (var block in blocks) { if (block.FatBlock == null) { armorBlocks++; } else { if (block.FatBlock.OwnerId != 0) { terminalBlocks++; if (block.FatBlock.OwnerId == ownerid) { owned++; } } } } } // this checks the ownership, to make sure the seller (still) owns more than half of the terminal blocks at the time of purchase by the new owner. if (owned > (terminalBlocks / 2)) { var accountseller = AccountManager.FindAccount(owner); var accountbuyer = AccountManager.FindAccount(SenderSteamId); if (accountbuyer.BankBalance >= Amount) { accountbuyer.BankBalance -= Amount; accountbuyer.Date = DateTime.Now; accountseller.BankBalance += Amount; accountseller.Date = DateTime.Now; MessageUpdateClient.SendAccountMessage(accountbuyer); MessageUpdateClient.SendAccountMessage(accountseller); // Using the identity list is a crap way, but since we don't have access to BuiltBy for non-functional blocks, this has to do. var listIdentites = new List <IMyIdentity>(); MyAPIGateway.Players.GetAllIdentites(listIdentites); foreach (var grid in grids) { MyAPIGateway.Utilities.InvokeOnGameThread(delegate { // Need to run this on foreground thread, as Havok will be called // during the disconnect of ConnectorBlock if ownership changes. grid.ChangeGridOwnership(player.IdentityId, MyOwnershipShareModeEnum.Faction); }); foreach (IMyIdentity identity in listIdentites) { if (identity.IdentityId != player.IdentityId) { // The current API doesn't allow the setting of the BuiltBy to anything but an existing Identity (player or NPC). // This also doesn't appear to sync to all clients, but it remains valid on the server. ((MyCubeGrid)grid).TransferBlocksBuiltByID(identity.IdentityId, player.IdentityId); } } } var removed = ShipManager.Remove(selectedShip.EntityId, owner); MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship purchased."); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "You cant afford that."); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "The seller no longer owns more than 50% of the ship."); } } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } // remove from sale // remove money and give previous owner EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:background end"); }, delegate() // when the background processing is finished, this block will run foreground. { EconomyScript.Instance.ServerLogger.WriteInfo("ShipSale:foreground"); try { var str = new StringBuilder(); //foreach (var kvp in gridComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //foreach (var kvp in inventoryComponents) //{ // MyDefinitionBase definition = null; // MyDefinitionManager.Static.TryGetDefinition(kvp.Key, out definition); // str.AppendFormat("'{0}' x {1}.\r\n", definition == null ? kvp.Key.SubtypeName : definition.GetDisplayName(), kvp.Value); //} //var prefix = string.Format("{0:#,##0.00000}", totalValue); var shipSale = ShipManager.CheckSellOrder(selectedShip.EntityId); // stations can be both large and small grids now. str.AppendFormat("{0}: {1}\r\n", selectedShip.GridSizeEnum + (selectedShip.IsStatic ? "Station" : " Ship"), selectedShip.DisplayName); str.AppendFormat("Grids={2}\r\nArmor Blocks={0}\r\nTerminal Blocks={1}\r\n", armorBlocks, terminalBlocks, gridCount); str.AppendLine("-----------------------------------"); if (shipSale != 0) { str.AppendFormat("Sale Price: {0:#,##0.00000} {1}.\r\n", shipSale, EconomyScript.Instance.ServerConfig.CurrencyName); } else { str.AppendLine("Sale Price: Not for Sale.\r\n"); } // MessageClientDialogMessage.SendMessage(SenderSteamId, "ShipSale", selectedShip.DisplayName, str.ToString()); } catch (Exception ex) { EconomyScript.Instance.ServerLogger.WriteException(ex); MessageClientTextMessage.SendMessage(SenderSteamId, "ShipSale", "Failed and died. Please contact the administrator."); } }); } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship is on sale for " + check); } } else { MessageClientTextMessage.SendMessage(SenderSteamId, "SHIPSALE", "Ship not for sale"); } } }
public override void ProcessServer() { if (!EconomyScript.Instance.ServerConfig.EnablePlayerPayments) { MessageClientTextMessage.SendMessage(SenderSteamId, "PAY", "Player payments is disabled."); return; } // did we at least type /pay someone something . . . //* Logic: //* Get player steam ID var payingPlayer = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); var accountToSpend = AccountManager.FindOrCreateAccount(SenderSteamId, SenderDisplayName, SenderLanguage); // need fix negative amounts before checking if the player can afford it. if (!payingPlayer.IsAdmin()) { TransactionAmount = Math.Abs(TransactionAmount); } // It needs to first check the player has enough to cover his payment if (TransactionAmount <= accountToSpend.BankBalance || payingPlayer.IsAdmin()) // do we have enough or are we admin so it doesnt matter //* if true, { // it needs to check the person being paid has an account record, var account = AccountManager.FindAccount(ToUserName); //* if true - it will always be true if real as it would have created it on join anyway //* if false - then they were never on this server anyway or seen would have added them already //* display an error message player not found if (account == null) { MessageClientTextMessage.SendMessage(SenderSteamId, "PAY", "Sorry, player does not exist or have an account!"); return; } //* if true, { flag hasaccount bool true } if (account.SteamId == payingPlayer.SteamUserId) { MessageClientTextMessage.SendMessage(SenderSteamId, "PAY", "Sorry, you cannot pay yourself!"); return; } //* if hasaccount bool true // admins can give or take money, normal players can only give money so convert negative to positive // here we add the players bank record again with the updated balance minus what they spent accountToSpend.BankBalance -= TransactionAmount; accountToSpend.Date = DateTime.Now; // here we retrive the target player steam id and balance // here we write it back to our bank ledger file account.BankBalance += TransactionAmount; account.Date = DateTime.Now; MessageUpdateClient.SendAccountMessage(accountToSpend); MessageUpdateClient.SendAccountMessage(account); // if this works this is a very sexy way to work with our file // testing: it does indeed work, if i was a teenager id probably need to change my underwear at this point // This notifies receiving player that they were paid and/or any message the sending player wrote // which needs to not send if the player isnt online - pity ive no idea how to write to the faction chat system // be a good place to send the player a faction message as it would work even if they were offline.. MessageClientTextMessage.SendMessage(account.SteamId, "PAY", string.Format("{0}, {1} just paid you {2} {4} for {3}", account.NickName, SenderDisplayName, TransactionAmount, Reason, EconomyScript.Instance.ServerConfig.CurrencyName)); MessageClientTextMessage.SendMessage(SenderSteamId, "PAY", string.Format("You just paid {0} {1} {3} for {2}", account.NickName, TransactionAmount, Reason, EconomyScript.Instance.ServerConfig.CurrencyName)); EconomyScript.Instance.ServerLogger.WriteVerbose("Pay: '{0}' sent {1} {3} to '{2}'", accountToSpend.NickName, TransactionAmount, ToUserName, EconomyScript.Instance.ServerConfig.CurrencyName); //* if false/otherwise throw error you dont have enough money } else { MessageClientTextMessage.SendMessage(SenderSteamId, "PAY", "Sorry you don't have enough {0}", EconomyScript.Instance.ServerConfig.CurrencyName); } }
public override void ProcessServer() { var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); // Only Admin can change config. if (!player.IsAdmin()) { EconomyScript.Instance.ServerLogger.WriteWarning("A Player without Admin \"{0}\" {1} attempted to access EConfig.", SenderDisplayName, SenderSteamId); return; } MyTexts.LanguageDescription myLanguage; // These will match with names defined in the RegEx patterm <EconomyScript.EconfigPattern> switch (ConfigName) { #region language case "language": if (string.IsNullOrEmpty(Value)) { myLanguage = MyTexts.Languages[(MyLanguagesEnum)EconomyScript.Instance.ServerConfig.Language]; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "Language: {0} ({1})", myLanguage.Name, myLanguage.FullCultureName); } else { int intTest; if (int.TryParse(Value, out intTest)) { if (MyTexts.Languages.ContainsKey((MyLanguagesEnum)intTest)) { EconomyScript.Instance.ServerConfig.Language = intTest; EconomyScript.Instance.SetLanguage(); myLanguage = MyTexts.Languages[(MyLanguagesEnum)intTest]; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "Language updated to: {0} ({1})", myLanguage.Name, myLanguage.FullCultureName); return; } } foreach (var lang in MyTexts.Languages) { if (lang.Value.Name.Equals(Value, StringComparison.InvariantCultureIgnoreCase) || lang.Value.CultureName.Equals(Value, StringComparison.InvariantCultureIgnoreCase) || lang.Value.FullCultureName.Equals(Value, StringComparison.InvariantCultureIgnoreCase)) { EconomyScript.Instance.ServerConfig.Language = (int)lang.Value.Id; EconomyScript.Instance.SetLanguage(); MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "Language updated to: {0} ({1})", lang.Value.Name, lang.Value.FullCultureName); return; } } myLanguage = MyTexts.Languages[(MyLanguagesEnum)EconomyScript.Instance.ServerConfig.Language]; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "Language: {0} ({1})", myLanguage.Name, myLanguage.FullCultureName); } break; #endregion #region tradenetworkname case "tradenetworkname": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeNetworkName: {0}", EconomyScript.Instance.ServerConfig.TradeNetworkName); } else { EconomyScript.Instance.ServerConfig.TradeNetworkName = Value; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeNetworkName updated to: \"{0}\"", EconomyScript.Instance.ServerConfig.TradeNetworkName); MessageUpdateClient.SendServerConfig(EconomyScript.Instance.ServerConfig); } break; #endregion #region currencyname case "currencyname": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "CurrencyName: {0}", EconomyScript.Instance.ServerConfig.CurrencyName); } else { EconomyScript.Instance.ServerConfig.CurrencyName = Value; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "CurrencyName updated to: \"{0}\"", EconomyScript.Instance.ServerConfig.CurrencyName); MessageUpdateClient.SendServerConfig(EconomyScript.Instance.ServerConfig); } break; #endregion #region limitedrange case "limitedrange": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedRange: {0}", EconomyScript.Instance.ServerConfig.LimitedRange ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.LimitedRange = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedRange updated to: {0}", EconomyScript.Instance.ServerConfig.LimitedRange ? "On" : "Off"); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedRange: {0}", EconomyScript.Instance.ServerConfig.LimitedRange ? "On" : "Off"); } break; #endregion #region limitedsupply case "limitedsupply": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedSupply: {0}", EconomyScript.Instance.ServerConfig.LimitedSupply ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.LimitedSupply = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedSupply updated to: {0}", EconomyScript.Instance.ServerConfig.LimitedSupply ? "On" : "Off"); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LimitedSupply: {0}", EconomyScript.Instance.ServerConfig.LimitedSupply ? "On" : "Off"); } break; #endregion #region enablelcds case "enablelcds": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableLcds: {0}", EconomyScript.Instance.ServerConfig.EnableLcds ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { var clearRefresh = EconomyScript.Instance.ServerConfig.EnableLcds && !boolTest; EconomyScript.Instance.ServerConfig.EnableLcds = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableLcds updated to: {0}", EconomyScript.Instance.ServerConfig.EnableLcds ? "On" : "Off"); if (clearRefresh) { LcdManager.BlankLcds(); } return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableLcds: {0}", EconomyScript.Instance.ServerConfig.EnableLcds ? "On" : "Off"); } break; #endregion #region EnableNpcTradezones case "enablenpctradezones": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableNpcTradezones: {0}", EconomyScript.Instance.ServerConfig.EnableNpcTradezones ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { var clearRefresh = EconomyScript.Instance.ServerConfig.EnableNpcTradezones != boolTest; EconomyScript.Instance.ServerConfig.EnableNpcTradezones = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableNpcTradezones updated to: {0}", EconomyScript.Instance.ServerConfig.EnableNpcTradezones ? "On" : "Off"); if (clearRefresh) { MessageUpdateClient.SendServerTradeZones(); } return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableNpcTradezones: {0}", EconomyScript.Instance.ServerConfig.EnableNpcTradezones ? "On" : "Off"); } break; #endregion #region EnablePlayerTradezones case "enableplayertradezones": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerTradezones: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerTradezones ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { var clearRefresh = EconomyScript.Instance.ServerConfig.EnablePlayerTradezones != boolTest; EconomyScript.Instance.ServerConfig.EnablePlayerTradezones = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerTradezones updated to: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerTradezones ? "On" : "Off"); if (clearRefresh) { MessageUpdateClient.SendServerTradeZones(); } return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerTradezones: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerTradezones ? "On" : "Off"); } break; #endregion #region EnablePlayerPayments case "enableplayerpayments": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerPayments: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerPayments ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.EnablePlayerPayments = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerPayments updated to: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerPayments ? "On" : "Off"); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnablePlayerPayments: {0}", EconomyScript.Instance.ServerConfig.EnablePlayerPayments ? "On" : "Off"); } break; #endregion #region tradetimeout case "tradetimeout": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeTimeout: {0}", EconomyScript.Instance.ServerConfig.TradeTimeout); } else { TimeSpan timeTest; if (TimeSpan.TryParse(Value, out timeTest)) { EconomyScript.Instance.ServerConfig.TradeTimeout = timeTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeTimeout updated to: {0} ", EconomyScript.Instance.ServerConfig.TradeTimeout); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeTimeout: {0}", EconomyScript.Instance.ServerConfig.TradeTimeout); } break; #endregion #region accountexpiry case "accountexpiry": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "AccountExpiry: {0}", EconomyScript.Instance.ServerConfig.AccountExpiry); } else { TimeSpan timeTest; if (TimeSpan.TryParse(Value, out timeTest)) { EconomyScript.Instance.ServerConfig.AccountExpiry = timeTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "AccountExpiry updated to: {0} ", EconomyScript.Instance.ServerConfig.AccountExpiry); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "AccountExpiry: {0}", EconomyScript.Instance.ServerConfig.AccountExpiry); } break; #endregion #region startingbalance case "startingbalance": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "StartingBalance: {0}", EconomyScript.Instance.ServerConfig.DefaultStartingBalance); } else { decimal decimalTest; if (decimal.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { EconomyScript.Instance.ServerConfig.DefaultStartingBalance = decimalTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "StartingBalance updated to: {0} ", EconomyScript.Instance.ServerConfig.DefaultStartingBalance); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "StartingBalance: {0}", EconomyScript.Instance.ServerConfig.DefaultStartingBalance); } break; #endregion #region LicenceMin case "licencemin": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMin: {0}", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin); } else { decimal decimalTest; if (decimal.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { if (EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax < decimalTest) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMin cannot be more than LicenceMax."); return; } EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin = decimalTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMin updated to: {0} ", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMin: {0}", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin); } break; #endregion #region LicenceMax case "licencemax": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMax: {0}", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax); } else { decimal decimalTest; if (decimal.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { if (decimalTest < EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMax cannot be less than LicenceMin."); return; } EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax = decimalTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMax updated to: {0} ", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LicenceMax: {0}", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax); } break; #endregion #region RelinkRatio case "relinkratio": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "RelinkRatio: {0}", EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio); } else { var numFormat = CultureInfo.CurrentCulture.NumberFormat; NumberFormatInfo nfi = new NumberFormatInfo() { CurrencyDecimalDigits = numFormat.PercentDecimalDigits, CurrencyDecimalSeparator = numFormat.PercentDecimalSeparator, CurrencyGroupSeparator = numFormat.PercentGroupSeparator, CurrencyGroupSizes = numFormat.PercentGroupSizes, CurrencyNegativePattern = numFormat.PercentNegativePattern, CurrencyPositivePattern = numFormat.PercentPositivePattern, CurrencySymbol = numFormat.PercentSymbol }; decimal decimalTest; if (decimal.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio = decimalTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "RelinkRatio updated to: {0:P} ", EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio); return; } } else if (decimal.TryParse(Value, NumberStyles.Currency, nfi, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio = decimalTest / 100; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "RelinkRatio updated to: {0:P} ", EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "RelinkRatio: {0:P}", EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio); } break; #endregion #region MaximumPlayerZones case "maximumplayerzones": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "MaximumPlayerZones: {0}", EconomyScript.Instance.ServerConfig.MaximumPlayerTradeZones); } else { int intTest; if (int.TryParse(Value, out intTest)) { if (intTest >= 0) { EconomyScript.Instance.ServerConfig.MaximumPlayerTradeZones = intTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "MaximumPlayerZones updated to: {0} ", EconomyScript.Instance.ServerConfig.MaximumPlayerTradeZones); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "TradeZoneLicence: {0}", EconomyScript.Instance.ServerConfig.MaximumPlayerTradeZones); } break; #endregion #region pricescaling case "pricescaling": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "PriceScaling: {0}", EconomyScript.Instance.ServerConfig.PriceScaling ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.PriceScaling = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "PriceScaling updated to: {0}", EconomyScript.Instance.ServerConfig.PriceScaling ? "On" : "Off"); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "PriceScaling: {0}", EconomyScript.Instance.ServerConfig.PriceScaling ? "On" : "Off"); } break; #endregion #region shiptrading case "shiptrading": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "ShipTrading: {0}", EconomyScript.Instance.ServerConfig.ShipTrading ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.ShipTrading = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "ShipTrading updated to: {0}", EconomyScript.Instance.ServerConfig.ShipTrading ? "On" : "Off"); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "ShipTrading: {0}", EconomyScript.Instance.ServerConfig.ShipTrading ? "On" : "Off"); } break; #endregion #region MinimumLcdDisplayInterval case "lcddisplayinterval": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LcdDisplayInterval: {0}", EconomyScript.Instance.ServerConfig.MinimumLcdDisplayInterval); } else { decimal decimalTest; if (decimal.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalTest)) { // TODO: perhaps we should truncate the value. if (decimalTest >= 0) { if (decimalTest < 1) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LcdDisplayInterval cannot be less than 1 second."); return; } if (decimalTest > 1000) // no particular reason for 1000, apart from it been a reasonable limit. { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LcdDisplayInterval cannot be more than 1000 second."); return; } EconomyScript.Instance.ServerConfig.MinimumLcdDisplayInterval = decimalTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LcdDisplayInterval updated to: {0} seconds", EconomyScript.Instance.ServerConfig.MinimumLcdDisplayInterval); return; } } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "LcdDisplayInterval: {0} seconds", EconomyScript.Instance.ServerConfig.MinimumLcdDisplayInterval); } break; #endregion #region EnableMissions case "enablemissions": if (string.IsNullOrEmpty(Value)) { MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableMissions: {0}", EconomyScript.Instance.ServerConfig.EnableMissions ? "On" : "Off"); } else { bool boolTest; if (Value.TryWordParseBool(out boolTest)) { EconomyScript.Instance.ServerConfig.EnableMissions = boolTest; MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableMissions updated to: {0}", EconomyScript.Instance.ServerConfig.EnableMissions ? "On" : "Off"); MessageUpdateClient.SendServerConfig(EconomyScript.Instance.ServerConfig); return; } MessageClientTextMessage.SendMessage(SenderSteamId, "ECONFIG", "EnableMissions: {0}", EconomyScript.Instance.ServerConfig.EnableMissions ? "On" : "Off"); } break; #endregion #region default default: var msg = new StringBuilder(); myLanguage = MyTexts.Languages[(MyLanguagesEnum)EconomyScript.Instance.ServerConfig.Language]; msg.AppendFormat("Language: {0} ({1})\r\n", myLanguage.Name, myLanguage.FullCultureName); msg.AppendFormat("TradeNetworkName: \"{0}\"\r\n", EconomyScript.Instance.ServerConfig.TradeNetworkName); msg.AppendFormat("LimitedRange: {0}\r\n", EconomyScript.Instance.ServerConfig.LimitedRange ? "On" : "Off"); msg.AppendFormat("LimitedSupply: {0}\r\n", EconomyScript.Instance.ServerConfig.LimitedSupply ? "On" : "Off"); msg.AppendFormat("TradeTimeout: {0} (days.hours:mins:secs)\r\n", EconomyScript.Instance.ServerConfig.TradeTimeout); msg.AppendFormat("StartingBalance: {0:#,#.######}\r\n", EconomyScript.Instance.ServerConfig.DefaultStartingBalance); msg.AppendFormat("CurrencyName: \"{0}\"\r\n", EconomyScript.Instance.ServerConfig.CurrencyName); msg.AppendFormat("AccountExpiry: {0} (days.hours:mins:secs)\r\n", EconomyScript.Instance.ServerConfig.AccountExpiry); msg.AppendFormat("EnableLcds: {0}\r\n", EconomyScript.Instance.ServerConfig.EnableLcds ? "On" : "Off"); msg.AppendFormat("EnableNpcTradezones: {0}\r\n", EconomyScript.Instance.ServerConfig.EnableNpcTradezones ? "On" : "Off"); msg.AppendFormat("PriceScaling: {0}\r\n", EconomyScript.Instance.ServerConfig.PriceScaling ? "On" : "Off"); msg.AppendFormat("ShipTrading: {0}\r\n", EconomyScript.Instance.ServerConfig.ShipTrading ? "On" : "Off"); msg.AppendFormat("LcdDisplayInterval: {0:#,#.######} seconds\r\n", EconomyScript.Instance.ServerConfig.MinimumLcdDisplayInterval); msg.AppendLine(); msg.AppendLine("--- Player Tradezones ---"); msg.AppendFormat("EnablePlayerTradezones: {0}\r\n", EconomyScript.Instance.ServerConfig.EnablePlayerTradezones ? "On" : "Off"); msg.AppendFormat("EnablePlayerPayments: {0}\r\n", EconomyScript.Instance.ServerConfig.EnablePlayerPayments ? "On" : "Off"); msg.AppendFormat("LicenceMin: {0:#,#.######} (at {1:#,#.######}m)\r\n", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMin, EconomyScript.Instance.ServerConfig.TradeZoneMinRadius); msg.AppendFormat("LicenceMax: {0:#,#.######} (at {1:#,#.######}m)\r\n", EconomyScript.Instance.ServerConfig.TradeZoneLicenceCostMax, EconomyScript.Instance.ServerConfig.TradeZoneMaxRadius); msg.AppendFormat("RelinkRatio: {0:P}\r\n", EconomyScript.Instance.ServerConfig.TradeZoneRelinkRatio); msg.AppendFormat("MaximumPlayerZones: {0}\r\n", EconomyScript.Instance.ServerConfig.MaximumPlayerTradeZones); // Not yet ready for general use. //msg.AppendFormat("EnableMissions: {0}\r\n", EconomyScript.Instance.ServerConfig.EnableMissions ? "On" : "Off"); MessageClientDialogMessage.SendMessage(SenderSteamId, "ECONFIG", " ", msg.ToString()); break; #endregion } }