Advertisement
Guest User

Untitled

a guest
Mar 17th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 44.41 KB | None | 0 0
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using Oxide.Core;
  6. using Oxide.Core.Plugins;
  7. using Newtonsoft.Json;
  8. using System.Linq;
  9.  
  10. namespace Oxide.Plugins
  11. {
  12.     [Info("Trade", "Calytic", "1.1.7", ResourceId = 1242)]
  13.     class Trade : RustPlugin
  14.     {
  15.         #region Configuration Data
  16.  
  17.         private string box;
  18.         private int slots;
  19.         private float cooldownMinutes;
  20.         private float maxRadius;
  21.         private float pendingSeconds;
  22.         private float radiationMax;
  23.  
  24.         [PluginReference]
  25.         private Plugin Ignore;
  26.  
  27.         private Dictionary<string, DateTime> tradeCooldowns = new Dictionary<string, DateTime>();
  28.  
  29.         #endregion
  30.  
  31.         #region Trade State
  32.  
  33.         class OnlinePlayer
  34.         {
  35.             public BasePlayer Player;
  36.             public StorageContainer View;
  37.             public OpenTrade Trade;
  38.  
  39.             public PlayerInventory inventory
  40.             {
  41.                 get
  42.                 {
  43.                     return Player.inventory;
  44.                 }
  45.             }
  46.  
  47.             public ItemContainer containerMain
  48.             {
  49.                 get
  50.                 {
  51.                     return Player.inventory.containerMain;
  52.                 }
  53.             }
  54.  
  55.             public OnlinePlayer(BasePlayer player)
  56.             {
  57.             }
  58.  
  59.             public void Clear()
  60.             {
  61.                 View = null;
  62.                 Trade = null;
  63.             }
  64.         }
  65.  
  66.         [OnlinePlayers]
  67.         Hash<BasePlayer, OnlinePlayer> onlinePlayers = new Hash<BasePlayer, OnlinePlayer>();
  68.  
  69.         class OpenTrade {
  70.             public OnlinePlayer source;
  71.             public OnlinePlayer target;
  72.  
  73.             public BasePlayer sourcePlayer
  74.             {
  75.                 get
  76.                 {
  77.                     return source.Player;
  78.                 }
  79.             }
  80.  
  81.             public BasePlayer targetPlayer
  82.             {
  83.                 get
  84.                 {
  85.                     return target.Player;
  86.                 }
  87.             }
  88.  
  89.             public bool complete = false;
  90.             public bool closing = false;
  91.  
  92.             public bool sourceAccept = false;
  93.             public bool targetAccept = false;
  94.  
  95.             public OpenTrade(OnlinePlayer source, OnlinePlayer target)
  96.             {
  97.                 this.source = source;
  98.                 this.target = target;
  99.             }
  100.  
  101.             public OnlinePlayer GetOther(OnlinePlayer onlinePlayer)
  102.             {
  103.                 if (source == onlinePlayer)
  104.                 {
  105.                     return target;
  106.                 }
  107.  
  108.                 return source;
  109.             }
  110.  
  111.             public BasePlayer GetOther(BasePlayer player)
  112.             {
  113.                 if (sourcePlayer == player)
  114.                 {
  115.                     return targetPlayer;
  116.                 }
  117.  
  118.                 return sourcePlayer;
  119.             }
  120.  
  121.             public void ResetAcceptance()
  122.             {
  123.                 sourceAccept = false;
  124.                 targetAccept = false;
  125.             }
  126.  
  127.             public bool IsInventorySufficient()
  128.             {
  129.                 if(target == null || source == null)
  130.                 {
  131.                     return false;
  132.                 }
  133.  
  134.                 if(target.containerMain == null || source.containerMain == null)
  135.                 {
  136.                     return false;
  137.                 }
  138.  
  139.                 if ((target.containerMain.capacity - target.containerMain.itemList.Count) < source.View.inventory.itemList.Count ||
  140.                        (source.containerMain.capacity - source.containerMain.itemList.Count) < target.View.inventory.itemList.Count)
  141.                 {
  142.                     return true;
  143.                 }
  144.  
  145.                 return false;
  146.             }
  147.  
  148.             public bool IsValid()
  149.             {
  150.                 if (IsSourceValid() && IsTargetValid())
  151.                     return true;
  152.  
  153.                 return false;
  154.             }
  155.  
  156.             public bool IsSourceValid()
  157.             {
  158.                 if (sourcePlayer != null && sourcePlayer.IsConnected)
  159.                     return true;
  160.  
  161.                 return false;
  162.             }
  163.  
  164.             public bool IsTargetValid()
  165.             {
  166.                 if (targetPlayer != null && targetPlayer.IsConnected)
  167.                     return true;
  168.  
  169.                 return false;
  170.             }
  171.         }
  172.  
  173.         class PendingTrade
  174.         {
  175.             public BasePlayer Target;
  176.             public Timer Timer;
  177.  
  178.             public PendingTrade(BasePlayer target)
  179.             {
  180.                 Target = target;
  181.             }
  182.  
  183.             public void Destroy()
  184.             {
  185.                 if (Timer != null && !Timer.Destroyed)
  186.                 {
  187.                     Timer.Destroy();
  188.                 }
  189.             }
  190.         }
  191.  
  192.         List<OpenTrade> openTrades = new List<OpenTrade>();
  193.         Dictionary<BasePlayer, PendingTrade> pendingTrades = new Dictionary<BasePlayer, PendingTrade>();
  194.         #endregion
  195.  
  196.         #region Initialization
  197.  
  198.         void Init()
  199.         {
  200.            
  201.             UnsubscribeAll();
  202.         }
  203.  
  204.         void UnsubscribeAll()
  205.         {
  206.             //Unsubscribe(nameof(CanNetworkTo));
  207.             Unsubscribe(nameof(OnItemAction));
  208.             Unsubscribe(nameof(OnItemAddedToContainer));
  209.             Unsubscribe(nameof(OnItemRemovedFromContainer));
  210.         }
  211.  
  212.         void SubscribeAll()
  213.         {
  214.             //Subscribe(nameof(CanNetworkTo));
  215.             Subscribe(nameof(OnItemAction));
  216.             Subscribe(nameof(OnItemAddedToContainer));
  217.             Subscribe(nameof(OnItemRemovedFromContainer));
  218.         }
  219.  
  220.         void Loaded() {
  221.             permission.RegisterPermission("trade.use", this);
  222.             permission.RegisterPermission("trade.accept", this);
  223.  
  224.             LoadMessages();
  225.  
  226.             CheckConfig();
  227.  
  228.             box = GetConfig("Settings","box", "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab");
  229.             slots = GetConfig("Settings","slots", 30);
  230.             cooldownMinutes = GetConfig("Settings","cooldownMinutes", 5f);
  231.             maxRadius = GetConfig("Settings","maxRadius", 5000f);
  232.             pendingSeconds = GetConfig("Settings", "pendingSeconds", 25f);
  233.             radiationMax = GetConfig("Settings", "radiationMax", 1f);
  234.         }
  235.  
  236.         void Unloaded()
  237.         {
  238.             foreach (var player in BasePlayer.activePlayerList)
  239.             {
  240.                 OnlinePlayer onlinePlayer;
  241.                 if (onlinePlayers.TryGetValue(player, out onlinePlayer))
  242.                 {
  243.                     if (onlinePlayer.Trade != null)
  244.                     {
  245.                         TradeCloseBoxes(onlinePlayer.Trade);
  246.                     }
  247.                     else if (onlinePlayer.View != null)
  248.                     {
  249.                         CloseBoxView(player, onlinePlayer.View);
  250.                     }
  251.                 }
  252.             }
  253.         }
  254.  
  255.         protected override void LoadDefaultConfig()
  256.         {
  257.             Config["Settings", "box"] = "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab";
  258.             Config["Settings", "slots"] = 30;
  259.             Config["Settings", "cooldownMinutes"] = 5;
  260.             Config["Settings", "maxRadius"] = 5000f;
  261.             Config["Settings", "pendingSeconds"] = 25f;
  262.             Config["Settings", "radiationMax"] = 1;
  263.             Config["VERSION"] = Version.ToString();
  264.         }
  265.  
  266.         void CheckConfig()
  267.         {
  268.             if (Config["VERSION"] == null)
  269.             {
  270.                 // FOR COMPATIBILITY WITH INITIAL VERSIONS WITHOUT VERSIONED CONFIG
  271.                 ReloadConfig();
  272.             }
  273.             else if (GetConfig<string>("VERSION", "") != Version.ToString())
  274.             {
  275.                 // ADDS NEW, IF ANY, CONFIGURATION OPTIONS
  276.                 ReloadConfig();
  277.             }
  278.         }
  279.  
  280.         protected void ReloadConfig()
  281.         {
  282.             Config["VERSION"] = Version.ToString();
  283.  
  284.             // NEW CONFIGURATION OPTIONS HERE
  285.             Config["Settings", "radiationMax"] = GetConfig("Settings", "radiationMax", 1f);
  286.             // END NEW CONFIGURATION OPTIONS
  287.  
  288.             PrintToConsole("Upgrading configuration file");
  289.             SaveConfig();
  290.         }
  291.  
  292.         void LoadMessages()
  293.         {
  294.             lang.RegisterMessages(new Dictionary<string, string>
  295.             {
  296.                 {"Inventory: You", "You do not have enough room in your inventory"},
  297.                 {"Inventory: Them", "Their inventory does not have enough room"},
  298.                 {"Inventory: Generic", "Insufficient inventory space"},
  299.  
  300.                 {"Player: Not Found", "No player found by that name"},
  301.                 {"Player: Unknown", "Unknown"},
  302.                 {"Player: Yourself", "You cannot trade with yourself"},
  303.  
  304.                 {"Status: Completing", "Completing trade.."},
  305.                 {"Status: No Pending", "You have no pending trade requests"},
  306.                 {"Status: Pending", "They already have a pending trade request"},
  307.                 {"Status: Received", "You have received a trade request from {0}. Type <color=lime>/trade accept</color> to begin trading"},
  308.                 {"Status: They Interrupted", "They moved or closed the trade"},
  309.                 {"Status: You Interrupted", "You moved or closed the trade"},
  310.  
  311.                 {"Trade: Sent", "Trade request sent"},
  312.                 {"Trade: They Declined", "They declined your trade request"},
  313.                 {"Trade: You Declined", "You declined their trade request"},
  314.                 {"Trade: They Accepted", "{0} accepted."},
  315.                 {"Trade: You Accepted", "You accepted."},
  316.                 {"Trade: Pending", "Trade pending."},
  317.  
  318.                 {"Denied: Permission", "You lack permission to do that"},
  319.                 {"Denied: Privilege", "You do no have building privilege"},
  320.                 {"Denied: Swimming", "You cannot do that while swimming"},
  321.                 {"Denied: Falling", "You cannot do that while falling"},
  322.                 {"Denied: Wounded", "You cannot do that while wounded"},
  323.                 {"Denied: Irradiated", "You cannot do that while irradiated"},
  324.                 {"Denied: Generic", "You cannot do that right now"},
  325.                 {"Denied: They Busy", "That player is busy"},
  326.                 {"Denied: They Ignored You", "They ignored you"},
  327.                 {"Denied: Distance", "Too far away"},
  328.  
  329.                 {"Item: BP", "BP"},
  330.  
  331.                 {"Syntax: Trade Accept", "Invalid syntax. /trade accept"},
  332.                 {"Syntax: Trade", "Invalid syntax. /trade \"Player Name\""},
  333.  
  334.                 {"Cooldown: Seconds", "You are doing that too often, try again in a {0} seconds(s)."},
  335.                 {"Cooldown: Minutes", "You are doing that too often, try again in a {0} minute(s)."},
  336.             }, this);
  337.         }
  338.  
  339.         #endregion
  340.  
  341.         #region Oxide Hooks
  342.  
  343.         //object CanNetworkTo(BaseNetworkable entity, BasePlayer target)
  344.         //{
  345.         //    if (entity == null || target == null || entity == target) return null;
  346.         //    if (target.IsAdmin) return null;
  347.  
  348.         //    OnlinePlayer onlinePlayer;
  349.         //    bool IsMyBox = false;
  350.         //    if (onlinePlayers.TryGetValue(target, out onlinePlayer))
  351.         //    {
  352.         //        if (onlinePlayer.View != null && onlinePlayer.View.net.ID == entity.net.ID)
  353.         //        {
  354.         //            IsMyBox = true;
  355.         //        }
  356.         //    }
  357.  
  358.         //    if (IsTradeBox(entity) && !IsMyBox) return false;
  359.  
  360.         //    return null;
  361.         //}
  362.  
  363.         void OnPlayerInit(BasePlayer player)
  364.         {
  365.             onlinePlayers[player].View = null;
  366.             onlinePlayers[player].Trade = null;
  367.         }
  368.  
  369.         void OnPlayerDisconnected(BasePlayer player)
  370.         {
  371.             OnlinePlayer onlinePlayer;
  372.             if (onlinePlayers.TryGetValue(player, out onlinePlayer)) {
  373.                 if (onlinePlayer.Trade != null)
  374.                 {
  375.                     TradeCloseBoxes(onlinePlayer.Trade);
  376.                 }
  377.                 else if (onlinePlayer.View != null)
  378.                 {
  379.                     CloseBoxView(player, onlinePlayer.View);
  380.                 }
  381.             }
  382.         }
  383.  
  384.         void OnPlayerLootEnd(PlayerLoot inventory) {
  385.             var player = inventory.GetComponent<BasePlayer>();
  386.             if (player == null)
  387.                 return;
  388.  
  389.             OnlinePlayer onlinePlayer;
  390.             if (onlinePlayers.TryGetValue(player, out onlinePlayer) && onlinePlayer.View != null)
  391.             {
  392.                 if(onlinePlayer.View == inventory.entitySource && onlinePlayer.Trade != null) {
  393.                     OpenTrade t = onlinePlayer.Trade;
  394.  
  395.                     if (!t.closing)
  396.                     {
  397.                         t.closing = true;
  398.                         if (!onlinePlayer.Trade.complete)
  399.                         {
  400.                             if (onlinePlayer.Trade.sourcePlayer == player)
  401.                             {
  402.                                 TradeReply(t, "Status: They Interrupted", "Status: You Interrupted");
  403.                             }
  404.                             else
  405.                             {
  406.                                 TradeReply(t, "Status: You Interrupted", "Status: They Interrupted");
  407.                             }
  408.                         }
  409.                         CloseBoxView(player, (StorageContainer)inventory.entitySource);
  410.                     }
  411.                 }
  412.             }
  413.         }
  414.  
  415.         void OnItemAction(Item item, string cmd) {
  416.             if(cmd == "drop") {
  417.                 BasePlayer player = item.GetOwnerPlayer();
  418.  
  419.                 if (player is BasePlayer)
  420.                 {
  421.                     OnlinePlayer onlinePlayer;
  422.                     if (onlinePlayers.TryGetValue(player, out onlinePlayer) && onlinePlayer.Trade != null && player.inventory != null)
  423.                     {
  424.                         if (item.parent == player.inventory.containerMain && !onlinePlayer.Trade.IsInventorySufficient())
  425.                         {
  426.                             ShowTrades(onlinePlayer.Trade, "Trade: Pending");
  427.                         }
  428.                     }
  429.                 }
  430.             }
  431.         }
  432.  
  433.         void OnItemAddedToContainer(ItemContainer container, Item item)
  434.         {
  435.             if(container.playerOwner is BasePlayer) {
  436.                 OnlinePlayer onlinePlayer;
  437.                 if (onlinePlayers.TryGetValue(container.playerOwner, out onlinePlayer) && onlinePlayer.Trade != null)
  438.                 {
  439.                     OpenTrade t = onlinePlayers[container.playerOwner].Trade;
  440.  
  441.                     if (!t.complete)
  442.                     {
  443.                         t.ResetAcceptance();
  444.  
  445.                         if (t.IsValid())
  446.                         {
  447.                             ShowTrades(t, "Trade: Pending");
  448.                         }
  449.                         else
  450.                         {
  451.                             TradeCloseBoxes(t);
  452.                         }
  453.                     }
  454.                 }
  455.             }
  456.         }
  457.  
  458.         void OnItemRemovedFromContainer(ItemContainer container, Item item)
  459.         {
  460.             if(container.playerOwner is BasePlayer) {
  461.                 OnlinePlayer onlinePlayer;
  462.                 if (onlinePlayers.TryGetValue(container.playerOwner, out onlinePlayer) && onlinePlayer.Trade != null)
  463.                 {
  464.                     OpenTrade t = onlinePlayers[container.playerOwner].Trade;
  465.                     if (!t.complete)
  466.                     {
  467.                         t.ResetAcceptance();
  468.  
  469.                         if (t.IsValid())
  470.                         {
  471.                             ShowTrades(t, "Trade: Pending");
  472.                         }
  473.                         else
  474.                         {
  475.                             TradeCloseBoxes(t);
  476.                         }
  477.                     }
  478.                 }
  479.             }
  480.         }
  481.  
  482.         #endregion
  483.  
  484.         #region Commands
  485.  
  486.         [ChatCommand("trade")]
  487.         void cmdTrade(BasePlayer player, string command, string[] args)
  488.         {
  489.             if(args.Length == 1) {
  490.                 if(args[0] == "accept") {
  491.                     if(!CanPlayerTrade(player, "trade.accept"))
  492.                         return;
  493.  
  494.                     AcceptTrade(player);
  495.                     return;
  496.                 }
  497.             }
  498.  
  499.             if(args.Length != 1) {
  500.                 if(pendingTrades.ContainsKey(player)) {
  501.                     SendReply(player, GetMsg("Syntax: Trade Accept", player));
  502.                 } else {
  503.                     SendReply(player, GetMsg("Syntax: Trade", player));
  504.                 }
  505.                
  506.                 return;
  507.             }
  508.  
  509.             var targetPlayer = FindPlayerByPartialName(args[0]);
  510.             if (targetPlayer == null)
  511.             {
  512.                 SendReply(player, GetMsg("Player: Not Found", player));
  513.                 return;
  514.             }
  515.  
  516.             if (targetPlayer == player)
  517.             {
  518.                 SendReply(player, GetMsg("Player: Yourself", player));
  519.                 return;
  520.             }
  521.  
  522.             if (!CheckCooldown(player))
  523.             {
  524.                 return;
  525.             }
  526.  
  527.             if (Ignore != null)
  528.             {
  529.                 var IsIgnored = Ignore.Call("IsIgnoredS", player.UserIDString, targetPlayer.UserIDString);
  530.                 if ((bool)IsIgnored == true)
  531.                 {
  532.                     SendReply(player, GetMsg("Denied: They Ignored You", player));
  533.                     return;
  534.                 }
  535.             }
  536.  
  537.             OnlinePlayer onlineTargetPlayer;
  538.             if (onlinePlayers.TryGetValue(targetPlayer, out onlineTargetPlayer) && onlineTargetPlayer.Trade != null)
  539.             {
  540.                 SendReply(player, GetMsg("Denied: They Busy", player));
  541.                 return;
  542.             }
  543.  
  544.             if (maxRadius > 0)
  545.             {
  546.                 if (targetPlayer.Distance(player) > maxRadius)
  547.                 {
  548.                     SendReply(player, GetMsg("Denied: Distance", player));
  549.                     return;
  550.                 }
  551.             }
  552.  
  553.             if(!CanPlayerTrade(player, "trade.use"))
  554.                 return;
  555.  
  556.             if(pendingTrades.ContainsKey(player))
  557.             {
  558.                 SendReply(player, GetMsg("Status: Pending", player));
  559.             }
  560.             else
  561.             {
  562.                 SendReply(targetPlayer, GetMsg("Status: Received", targetPlayer), player.displayName);
  563.                 SendReply(player, GetMsg("Trade: Sent", player));
  564.                 var pendingTrade = new PendingTrade(targetPlayer);
  565.                 pendingTrades.Add(player, pendingTrade);
  566.  
  567.                 pendingTrade.Timer = timer.In(pendingSeconds, delegate()
  568.                 {
  569.                     if(pendingTrades.ContainsKey(player)) {
  570.                         pendingTrades.Remove(player);
  571.                         SendReply(player, GetMsg("Trade: They Declined", player));
  572.                         SendReply(targetPlayer, GetMsg("Trade: You Declined", targetPlayer));
  573.                     }
  574.                 });
  575.             }
  576.         }
  577.  
  578.         [ConsoleCommand("trade")]
  579.         void ccTrade(ConsoleSystem.Arg arg)
  580.         {
  581.             cmdTrade(arg.Connection.player as BasePlayer, arg.cmd.Name, arg.Args);
  582.         }
  583.  
  584.         [ConsoleCommand("trade.decline")]
  585.         void ccTradeDecline(ConsoleSystem.Arg arg)
  586.         {
  587.             var player = arg.Connection.player as BasePlayer;
  588.  
  589.             OnlinePlayer onlinePlayer;
  590.             if (onlinePlayers.TryGetValue(player, out onlinePlayer) && onlinePlayer.Trade != null)
  591.             {
  592.                 onlinePlayer.Trade.closing = true;
  593.                 var target = onlinePlayer.Trade.GetOther(player);
  594.                 SendReply(player, GetMsg("Trade: You Declined", player));
  595.                 SendReply(target, GetMsg("Trade: They Declined", target));
  596.  
  597.                 TradeCloseBoxes(onlinePlayer.Trade);
  598.             } else if(player is BasePlayer) {
  599.                 HideTrade(player);
  600.             }
  601.         }
  602.  
  603.         [ConsoleCommand("trade.accept")]
  604.         void ccTradeAccept(ConsoleSystem.Arg arg)
  605.         {
  606.             var player = arg.Connection.player as BasePlayer;
  607.  
  608.             OnlinePlayer onlinePlayer;
  609.             if (onlinePlayers.TryGetValue(player, out onlinePlayer) && onlinePlayer.Trade != null)
  610.             {
  611.                 var t = onlinePlayers[player].Trade;
  612.                 if(t.sourcePlayer == player) {
  613.                     var i = t.target.View.inventory.itemList.Count;
  614.                     var f = t.source.containerMain.capacity - t.source.containerMain.itemList.Count;
  615.                     if(i > f) {
  616.  
  617.                         TradeReply(t, "Inventory: Them", "Inventory: You");
  618.                        
  619.                         t.sourceAccept = false;
  620.                         ShowTrades(t, "Inventory: Generic");
  621.                         return;
  622.                     }
  623.                    
  624.                     t.sourceAccept = true;
  625.                 } else if(t.targetPlayer == player) {
  626.                     var i = t.source.View.inventory.itemList.Count;
  627.                     var f = t.target.containerMain.capacity - t.target.containerMain.itemList.Count;
  628.                     if(i > f) {
  629.                         TradeReply(t, "Inventory: You", "Inventory: Them");
  630.                         t.targetAccept = false;
  631.                         ShowTrades(t, "Inventory: Generic");
  632.                         return;
  633.                     }
  634.  
  635.                     t.targetAccept = true;
  636.                 }
  637.  
  638.                 if(t.targetAccept == true && t.sourceAccept == true) {
  639.                     if(t.IsInventorySufficient()) {
  640.                             t.ResetAcceptance();
  641.                             ShowTrades(t, "Inventory: Generic");
  642.                         return;
  643.                     }
  644.                     if(t.complete) {
  645.                         return;
  646.                     }
  647.                     t.complete = true;
  648.  
  649.                     TradeCooldown(t);
  650.  
  651.                     TradeReply(t, "Status: Completing");
  652.  
  653.                     timer.In(0.1f, () => FinishTrade(t));
  654.                 } else {
  655.                     ShowTrades(t, "Trade: Pending");
  656.                 }
  657.             } else if(player is BasePlayer) {
  658.                 HideTrade(player);
  659.             }
  660.         }
  661.  
  662.         #endregion
  663.  
  664.         #region GUI
  665.  
  666.         public string jsonTrade = @"[{""name"":""TradeMsg"",""parent"":""Overlay"",""components"":[{""type"":""UnityEngine.UI.Image"",""color"":""0 0 0 0.76"",""imagetype"":""Filled""},{""type"":""RectTransform"",""anchormax"":""0.77 0.91"",""anchormin"":""0.24 0.52""}]},{""name"":""SourceLabel{1}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{sourcename}"",""fontSize"":""16"",""align"":""UpperLeft""},{""type"":""RectTransform"",""anchormax"":""0.48 0.98"",""anchormin"":""0.03 0.91""}]},{""name"":""TargetLabel{2}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{targetname}"",""fontSize"":""17""},{""type"":""RectTransform"",""anchormax"":""0.97 0.98"",""anchormin"":""0.52 0.91""}]},{""name"":""SourceItemsPanel{3}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.RawImage"",""color"":""0 0 0 0.52"",""imagetype"":""Filled""},{""type"":""RectTransform"",""anchormax"":""0.47 0.9"",""anchormin"":""0.03 0.13""}]},{""name"":""SourceItemsText"",""parent"":""SourceItemsPanel{3}"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{sourceitems}"",""fontSize"":""14"",""align"":""UpperLeft""},{""type"":""RectTransform"",""anchormax"":""0.99 0.99"",""anchormin"":""0.01 0.01""}]},{""name"":""TargetItemsPanel{4}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.RawImage"",""color"":""0 0 0 0.52"",""imagetype"":""Filled""},{""type"":""RectTransform"",""anchormax"":""0.96 0.9"",""anchormin"":""0.52 0.13""}]},{""name"":""TargetItemsText"",""parent"":""TargetItemsPanel{4}"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{targetitems}"",""fontSize"":""14"",""align"":""UpperLeft""},{""type"":""RectTransform"",""anchormax"":""0.99 0.99"",""anchormin"":""0.01 0.01""}]},{""name"":""AcceptTradeButton{5}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.Button"",""color"":""0 0.95 0.14 0.54"",""command"":""trade.accept""},{""type"":""RectTransform"",""anchormax"":""0.47 0.09"",""anchormin"":""0.35 0.03""}]},{""name"":""AcceptTradeLabel"",""parent"":""AcceptTradeButton{5}"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""Accept"",""fontSize"":""13"",""align"":""MiddleCenter""},{""type"":""RectTransform"",""anchormax"":""1 1"",""anchormin"":""0 0""}]},{""name"":""DeclineTradeButton{6}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.Button"",""color"":""0.95 0 0.02 0.61"",""command"":""trade.decline""},{""type"":""RectTransform"",""anchormax"":""0.15 0.09"",""anchormin"":""0.03 0.03""}]},{""name"":""DeclineTradeLabel"",""parent"":""DeclineTradeButton{6}"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""Decline"",""fontSize"":""13"",""align"":""MiddleCenter""},{""type"":""RectTransform"",""anchormax"":""1 1"",""anchormin"":""0 0""}]},{""name"":""TargetStatusLabel{7}"",""parent"":""TradeMsg"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{targetstatus}"",""fontSize"":""14"",""align"":""UpperLeft""},{""type"":""RectTransform"",""anchormax"":""0.97 0.09"",""anchormin"":""0.52 0.01""}]}]
  667. ";
  668.         private void ShowTrade(BasePlayer player, OpenTrade trade, string status) {
  669.             HideTrade(player);
  670.  
  671.             OnlinePlayer onlinePlayer;
  672.             if(!onlinePlayers.TryGetValue(player, out onlinePlayer)) {
  673.                 return;
  674.             }
  675.  
  676.             if (onlinePlayer.View == null)
  677.             {
  678.                 return;
  679.             }
  680.  
  681.             StorageContainer sourceContainer = onlinePlayer.View;
  682.             StorageContainer targetContainer = null;
  683.             BasePlayer target = null;
  684.  
  685.             if (trade.sourcePlayer == player && trade.target.View != null)
  686.             {
  687.                 targetContainer = trade.target.View;
  688.                 target = trade.targetPlayer;
  689.                 if(target is BasePlayer) {
  690.                     if(trade.targetAccept) {
  691.                         status += string.Format(GetMsg("Trade: They Accepted", player), CleanName(target.displayName));
  692.                     } else if(trade.sourceAccept) {
  693.                         status += GetMsg("Trade: You Accepted", player);
  694.                     }
  695.                 } else {
  696.                     return;
  697.                 }
  698.             }
  699.             else if (trade.targetPlayer == player && trade.source.View != null)
  700.             {
  701.                 targetContainer = trade.source.View;
  702.                 target = trade.sourcePlayer;
  703.                 if(target is BasePlayer) {
  704.                     if(trade.sourceAccept) {
  705.                         status += string.Format(GetMsg("Trade: They Accepted", player), CleanName(target.displayName));
  706.                     } else if (trade.targetAccept) {
  707.                         status += GetMsg("Trade: You Accepted", player);
  708.                     }
  709.                 } else {
  710.                     return;
  711.                 }
  712.             }
  713.  
  714.             if(targetContainer == null || target == null) {
  715.                 return;
  716.             }
  717.  
  718.             string send = jsonTrade;
  719.             for (int i = 1; i < 100; i++)
  720.             {
  721.                 send = send.Replace("{" + i + "}", Oxide.Core.Random.Range(9999, 99999).ToString());
  722.             }
  723.  
  724.             send = send.Replace("{sourcename}", CleanName(player.displayName));
  725.             if(target != null) {
  726.                 send = send.Replace("{targetname}", CleanName(target.displayName));
  727.             } else {
  728.                 send = send.Replace("{targetname}", GetMsg("Player: Unknown", player));
  729.             }
  730.             send = send.Replace("{targetstatus}", status);
  731.  
  732.             var slotsAvailable = target.inventory.containerMain.capacity - (target.inventory.containerMain.itemList.Count);
  733.             List<string> sourceItems = new List<string>();
  734.             var x = 1;
  735.             foreach(Item i in sourceContainer.inventory.itemList) {
  736.                 string n = "";
  737.                 if(i.IsBlueprint()) {
  738.                     n = i.amount + " x <color=lightblue>" + i.blueprintTargetDef.displayName.english + " [" + GetMsg("Item: BP", player) + "]</color>";
  739.                 } else {
  740.                     n = i.amount + " x "+ i.info.displayName.english;
  741.                 }
  742.  
  743.                 if(x > slotsAvailable) {
  744.                     n = "<color=red>" + n + "</color>";
  745.                 }
  746.                 x++;
  747.                
  748.                 sourceItems.Add(n);
  749.             }
  750.  
  751.             send = send.Replace("{sourceitems}", string.Join("\n", sourceItems.ToArray()));
  752.  
  753.             if(player != target) {
  754.                 slotsAvailable = player.inventory.containerMain.capacity - (player.inventory.containerMain.itemList.Count);
  755.                 List<string> targetItems = new List<string>();
  756.                 x = 1;
  757.                 if(targetContainer != null) {
  758.                     foreach(Item i in targetContainer.inventory.itemList) {
  759.                         string n2 = "";
  760.                         if(i.IsBlueprint()) {
  761.                             n2 = i.amount + " x <color=lightblue>" + i.blueprintTargetDef.displayName.english + " [" + GetMsg("Item: BP", player) + "]</color>";
  762.                         } else {
  763.                             n2 = i.amount + " x "+ i.info.displayName.english;
  764.                         }
  765.                         if(x > slotsAvailable) {
  766.                             n2 = "<color=red>" + n2 + "</color>";
  767.                         }
  768.                         x++;
  769.                         targetItems.Add(n2);
  770.                     }
  771.                 }
  772.  
  773.                 send = send.Replace("{targetitems}", string.Join("\n", targetItems.ToArray()));
  774.             } else {
  775.                 send = send.Replace("{targetitems}", "");
  776.             }
  777.  
  778.             CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo {connection = player.net.connection}, null, "AddUI", send);
  779.         }
  780.  
  781.         private void HideTrade(BasePlayer player) {
  782.             if (player.IsConnected)
  783.             {
  784.                 CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo { connection = player.net.connection }, null, "DestroyUI", "TradeMsg");
  785.             }
  786.         }
  787.  
  788.         #endregion
  789.  
  790.         #region Core Methods
  791.  
  792.         bool CheckCooldown(BasePlayer player)
  793.         {
  794.             if (cooldownMinutes > 0)
  795.             {
  796.                 DateTime startTime;
  797.                 if (tradeCooldowns.TryGetValue(player.UserIDString, out startTime))
  798.                 {
  799.                     var endTime = DateTime.Now;
  800.  
  801.                     var span = endTime.Subtract(startTime);
  802.                     if (span.TotalMinutes > 0 && span.TotalMinutes < Convert.ToDouble(cooldownMinutes))
  803.                     {
  804.                         double timeleft = System.Math.Round(Convert.ToDouble(cooldownMinutes) - span.TotalMinutes, 2);
  805.                         if (timeleft < 1)
  806.                         {
  807.                             double timelefts = System.Math.Round((Convert.ToDouble(cooldownMinutes) * 60) - span.TotalSeconds);
  808.                             SendReply(player, string.Format(GetMsg("Cooldown: Seconds", player), timelefts.ToString()));
  809.                         }
  810.                         else
  811.                         {
  812.                             SendReply(player, string.Format(GetMsg("Cooldown: Minutes", player), System.Math.Round(timeleft).ToString()));
  813.                         }
  814.                         return false;
  815.                     }
  816.                     else
  817.                     {
  818.                         tradeCooldowns.Remove(player.UserIDString);
  819.                     }
  820.                 }
  821.             }
  822.  
  823.             return true;
  824.         }
  825.  
  826.         void TradeCloseBoxes(OpenTrade trade)
  827.         {
  828.             if (trade.IsSourceValid())
  829.             {
  830.                 CloseBoxView(trade.sourcePlayer, trade.source.View);
  831.             }
  832.  
  833.             if (trade.IsTargetValid() && trade.targetPlayer != trade.sourcePlayer)
  834.             {
  835.                 CloseBoxView(trade.targetPlayer, trade.target.View);
  836.             }
  837.         }
  838.  
  839.         void TradeReply(OpenTrade trade, string msg, string msg2 = null)
  840.         {
  841.             if (msg2 == null)
  842.             {
  843.                 msg2 = msg;
  844.             }
  845.             SendReply(trade.targetPlayer, GetMsg(msg, trade.targetPlayer));
  846.             SendReply(trade.sourcePlayer, GetMsg(msg2, trade.sourcePlayer));
  847.         }
  848.  
  849.         void ShowTrades(OpenTrade trade, string msg)
  850.         {
  851.             ShowTrade(trade.sourcePlayer, trade, GetMsg(msg, trade.sourcePlayer));
  852.             ShowTrade(trade.targetPlayer, trade, GetMsg(msg, trade.targetPlayer));
  853.         }
  854.  
  855.         void TradeCooldown(OpenTrade trade)
  856.         {
  857.             PlayerCooldown(trade.targetPlayer);
  858.             PlayerCooldown(trade.sourcePlayer);
  859.         }
  860.  
  861.         void PlayerCooldown(BasePlayer player)
  862.         {
  863.             if (player.IsAdmin)
  864.             {
  865.                 return;
  866.             }
  867.             if (tradeCooldowns.ContainsKey(player.UserIDString))
  868.             {
  869.                 tradeCooldowns.Remove(player.UserIDString);
  870.             }
  871.  
  872.             tradeCooldowns.Add(player.UserIDString, DateTime.Now);
  873.         }
  874.  
  875.         void FinishTrade(OpenTrade t) {
  876.             var source = t.source.View;
  877.             var target = t.target.View;
  878.  
  879.             foreach(var i in source.inventory.itemList.ToArray()) {
  880.                 i.MoveToContainer(t.target.containerMain);
  881.             }
  882.  
  883.             foreach(var i in target.inventory.itemList.ToArray()) {
  884.                 i.MoveToContainer(t.source.containerMain);
  885.             }
  886.  
  887.             TradeCloseBoxes(t);
  888.         }
  889.  
  890.         void AcceptTrade(BasePlayer player) {
  891.             BasePlayer source = null;
  892.  
  893.             PendingTrade pendingTrade = null;
  894.  
  895.             foreach(KeyValuePair<BasePlayer, PendingTrade> kvp in pendingTrades) {
  896.                 if(kvp.Value.Target == player) {
  897.                     pendingTrade = kvp.Value;
  898.                     source = kvp.Key;
  899.                     break;
  900.                 }
  901.             }
  902.  
  903.             if(source != null && pendingTrade != null) {
  904.                 pendingTrade.Destroy();
  905.                 pendingTrades.Remove(source);
  906.                 StartTrades(source, player);
  907.             }
  908.             else
  909.             {
  910.                 SendReply(player, GetMsg("Status: No Pending", player));
  911.             }
  912.         }
  913.  
  914.         void StartTrades(BasePlayer source, BasePlayer target)
  915.         {
  916.             var trade = new OpenTrade(onlinePlayers[source], onlinePlayers[target]);
  917.             StartTrade(source, target, trade);
  918.             if (source != target)
  919.             {
  920.                 StartTrade(target, source, trade);
  921.             }
  922.         }
  923.  
  924.         void StartTrade(BasePlayer source, BasePlayer target, OpenTrade trade)
  925.         {
  926.             OpenBox(source, source);
  927.  
  928.             if (!openTrades.Contains(trade))
  929.             {
  930.                 openTrades.Add(trade);
  931.             }
  932.             onlinePlayers[source].Trade = trade;
  933.  
  934.             timer.In(0.1f, () => ShowTrade(source, trade, GetMsg("Trade: Pending", source)));
  935.         }
  936.  
  937.         void OpenBox(BasePlayer player, BaseEntity target)
  938.         {
  939.             SubscribeAll();
  940.             var ply = onlinePlayers[player];
  941.             if (ply.View == null)
  942.             {
  943.                 OpenBoxView(player, target);
  944.                 return;
  945.             }
  946.  
  947.             CloseBoxView(player, ply.View);
  948.             timer.In(1f, () => OpenBoxView(player, target));
  949.         }
  950.  
  951.         void OpenBoxView(BasePlayer player, BaseEntity targArg)
  952.         {
  953.             var pos = new Vector3(player.transform.position.x, player.transform.position.y-1, player.transform.position.z);
  954.             var boxContainer = GameManager.server.CreateEntity(box,pos) as StorageContainer;
  955.             boxContainer.transform.position = pos;
  956.  
  957.             if (!boxContainer) return;
  958.  
  959.             StorageContainer view = boxContainer as StorageContainer;
  960.             view.limitNetworking = true;
  961.             player.EndLooting();
  962.             if(targArg is BasePlayer) {
  963.                
  964.                 BasePlayer target = targArg as BasePlayer;
  965.                 ItemContainer container = new ItemContainer();
  966.                 container.playerOwner = player;
  967.                 container.ServerInitialize(null, slots);
  968.                 if (container.uid == 0)
  969.                     container.GiveUID();
  970.  
  971.                 view.enableSaving = false;
  972.                 view.Spawn();
  973.                 view.inventory = container;
  974.  
  975.                 onlinePlayers[player].View = view;
  976.                 timer.In(0.1f, () => view.PlayerOpenLoot(player));
  977.             }
  978.         }
  979.  
  980.         void CloseBoxView(BasePlayer player, StorageContainer view)
  981.         {
  982.            
  983.             OnlinePlayer onlinePlayer;
  984.             if (!onlinePlayers.TryGetValue(player, out onlinePlayer)) return;
  985.             if (onlinePlayer.View == null) return;
  986.  
  987.             HideTrade(player);
  988.             if (onlinePlayer.Trade != null)
  989.             {
  990.                 OpenTrade t = onlinePlayer.Trade;
  991.                 t.closing = true;
  992.  
  993.                 if (t.sourcePlayer == player && t.targetPlayer != player && t.target.View != null)
  994.                 {
  995.                     t.target.Trade = null;
  996.                     CloseBoxView(t.targetPlayer, t.target.View);
  997.                 }
  998.                 else if (t.targetPlayer == player && t.sourcePlayer != player && t.source.View != null)
  999.                 {
  1000.                     t.source.Trade = null;
  1001.                     CloseBoxView(t.sourcePlayer, t.source.View);
  1002.                 }
  1003.  
  1004.                 if (openTrades.Contains(t))
  1005.                 {
  1006.                     openTrades.Remove(t);
  1007.                 }
  1008.             }
  1009.  
  1010.             if (view.inventory.itemList.Count > 0)
  1011.             {
  1012.                 foreach (Item item in view.inventory.itemList.ToArray())
  1013.                 {
  1014.                     if (item.position != -1)
  1015.                     {
  1016.                         item.MoveToContainer(player.inventory.containerMain);
  1017.                     }
  1018.                 }
  1019.             }
  1020.  
  1021.             if (view.inventory.itemList.Count > 0)
  1022.             {
  1023.                 foreach (Item item in view.inventory.itemList.ToArray())
  1024.                 {
  1025.                     if (item.position != -1)
  1026.                     {
  1027.                         item.MoveToContainer(player.inventory.containerBelt);
  1028.                     }
  1029.                 }
  1030.             }
  1031.  
  1032.             if (player.inventory.loot.entitySource != null)
  1033.             {
  1034.                 player.inventory.loot.Invoke("SendUpdate", 0.1f);
  1035.                 view.SendMessage("PlayerStoppedLooting", player, SendMessageOptions.DontRequireReceiver);
  1036.                 player.SendConsoleCommand("inventory.endloot", null);
  1037.             }
  1038.  
  1039.             player.inventory.loot.entitySource = null;
  1040.             player.inventory.loot.itemSource = null;
  1041.             player.inventory.loot.containers = new List<ItemContainer>();
  1042.  
  1043.             view.inventory = new ItemContainer();
  1044.  
  1045.             onlinePlayer.Clear();
  1046.  
  1047.             view.Kill(BaseNetworkable.DestroyMode.None);
  1048.  
  1049.             if (onlinePlayers.Values.Count(p => p.View != null) <= 0)
  1050.             {
  1051.                 UnsubscribeAll();
  1052.             }
  1053.         }
  1054.  
  1055.         bool CanPlayerTrade(BasePlayer player, string perm) {
  1056.             if(!permission.UserHasPermission(player.UserIDString, perm)) {
  1057.                 SendReply(player, GetMsg("Denied: Permission", player));
  1058.                 return false;
  1059.             }
  1060.             if(!player.CanBuild()) {
  1061.                 SendReply(player, GetMsg("Denied: Privilege", player));
  1062.                 return false;
  1063.             }
  1064.             if (radiationMax > 0 && player.radiationLevel > radiationMax)
  1065.             {
  1066.                 SendReply(player, GetMsg("Denied: Irradiated", player));
  1067.                 return false;
  1068.             }
  1069.             if(player.IsSwimming()) {
  1070.                 SendReply(player, GetMsg("Denied: Swimming", player));
  1071.                 return false;
  1072.             }
  1073.             if(!player.IsOnGround()) {
  1074.                 SendReply(player, GetMsg("Denied: Falling", player));
  1075.                 return false;
  1076.             }
  1077.             if (player.IsFlying)
  1078.             {
  1079.                 SendReply(player, GetMsg("Denied: Falling", player));
  1080.                 return false;
  1081.             }
  1082.             if(player.IsWounded()) {
  1083.                 SendReply(player, GetMsg("Denied: Wounded", player));
  1084.                 return false;
  1085.             }
  1086.  
  1087.             var canTrade = Interface.Call("CanTrade", player);
  1088.             if (canTrade != null)
  1089.             {
  1090.                 if (canTrade is string)
  1091.                 {
  1092.                     SendReply(player, Convert.ToString(canTrade));
  1093.                 }
  1094.                 else
  1095.                 {
  1096.                     SendReply(player, GetMsg("Denied: Generic", player));
  1097.                 }
  1098.                 return false;
  1099.             }
  1100.  
  1101.             return true;
  1102.         }
  1103.  
  1104.         #endregion
  1105.  
  1106.         #region HelpText
  1107.         private void SendHelpText(BasePlayer player)
  1108.         {
  1109.             var sb = new StringBuilder()
  1110.                .Append("Trade by <color=#ce422b>http://rustservers.io</color>\n")
  1111.                .Append("  ").Append("<color=\"#ffd479\">/trade \"Player Name\"</color> - Send trade request").Append("\n")
  1112.                .Append("  ").Append("<color=\"#ffd479\">/trade accept</color> - Accept trade request").Append("\n");
  1113.             player.ChatMessage(sb.ToString());
  1114.         }
  1115.         #endregion
  1116.  
  1117.         #region Helper methods
  1118.  
  1119.         private bool IsTradeBox(BaseNetworkable entity)
  1120.         {
  1121.             foreach (KeyValuePair<BasePlayer, OnlinePlayer> kvp in onlinePlayers)
  1122.             {
  1123.                 if (kvp.Value.View != null && kvp.Value.View.net != null && entity.net != null && kvp.Value.View.net.ID == entity.net.ID)
  1124.                 {
  1125.                     return true;
  1126.                 }
  1127.             }
  1128.  
  1129.             return false;
  1130.         }
  1131.  
  1132.         bool hasAccess(BasePlayer player, string permissionname)
  1133.         {
  1134.             if (player.IsAdmin) return true;
  1135.             return permission.UserHasPermission(player.UserIDString, permissionname);
  1136.         }
  1137.  
  1138.         private BasePlayer FindPlayerByPartialName(string name)
  1139.         {
  1140.             if (string.IsNullOrEmpty(name))
  1141.                 return null;
  1142.             BasePlayer player = null;
  1143.             name = name.ToLower();
  1144.             var awakePlayers = BasePlayer.activePlayerList.ToArray();
  1145.             foreach (var p in awakePlayers)
  1146.             {
  1147.                 if (p.net == null || p.net.connection == null)
  1148.                     continue;
  1149.  
  1150.                 if (p.displayName == name)
  1151.                 {
  1152.                     if (player != null)
  1153.                         return null;
  1154.                     player = p;
  1155.                 }
  1156.             }
  1157.  
  1158.             if (player != null)
  1159.                 return player;
  1160.             foreach (var p in awakePlayers)
  1161.             {
  1162.                 if (p.net == null || p.net.connection == null)
  1163.                     continue;
  1164.  
  1165.                 if (p.displayName.ToLower().IndexOf(name) >= 0)
  1166.                 {
  1167.                     if (player != null)
  1168.                         return null;
  1169.                     player = p;
  1170.                 }
  1171.             }
  1172.  
  1173.             return player;
  1174.         }
  1175.  
  1176.         private T GetConfig<T>(string name, T defaultValue)
  1177.         {
  1178.             if (Config[name] == null)
  1179.             {
  1180.                 return defaultValue;
  1181.             }
  1182.  
  1183.             return (T)Convert.ChangeType(Config[name], typeof(T));
  1184.         }
  1185.  
  1186.         private T GetConfig<T>(string name, string name2, T defaultValue)
  1187.         {
  1188.             if (Config[name, name2] == null)
  1189.             {
  1190.                 return defaultValue;
  1191.             }
  1192.  
  1193.             return (T)Convert.ChangeType(Config[name, name2], typeof(T));
  1194.         }
  1195.  
  1196.         string GetMsg(string key, BasePlayer player = null)
  1197.         {
  1198.             return lang.GetMessage(key, this, player == null ? null : player.UserIDString);
  1199.         }
  1200.  
  1201.         private string CleanName(string name) {
  1202.             return JsonConvert.ToString(name.Trim()).Replace("\"","");
  1203.         }
  1204.  
  1205.         #endregion
  1206.     }
  1207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement