MONaH-Rasta

InfoPanel

Jul 17th, 2020
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 110.02 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using Newtonsoft.Json;
  6. using Newtonsoft.Json.Converters;
  7. using Oxide.Core;
  8. using Oxide.Core.Plugins;
  9. using Oxide.Game.Rust;
  10. using Oxide.Game.Rust.Cui;
  11. using UnityEngine;
  12.  
  13. namespace Oxide.Plugins
  14. {
  15.     [Info("InfoPanel", "Default", "1.0.1")]
  16.     [Description("A little panel with useful information.")]
  17.     public class InfoPanel : RustPlugin
  18.     {
  19.         #region DefaultConfigs
  20.         private static string DefaultFontColor = "1 1 1 1";
  21.         public bool IsReady;
  22.         #endregion
  23.  
  24.         private Timer TestTimer;
  25.  
  26.         private Dictionary<string, Dictionary<string, IPanel>> PlayerPanels = new Dictionary<string, Dictionary<string, IPanel>>();
  27.         private Dictionary<string, Dictionary<string, IPanel>> PlayerDockPanels = new Dictionary<string, Dictionary<string, IPanel>>();
  28.  
  29.         private Dictionary<string, List<string>> LoadedPluginPanels = new Dictionary<string, List<string>>();
  30.  
  31.         #region DefaultConfig
  32.  
  33.         private static PluginConfig Settings;
  34.  
  35.         private readonly List<string> TimeFormats = new List<string>
  36.         {
  37.             "H:mm",
  38.             "HH:mm",
  39.             "h:mm",
  40.             "h:mm tt",
  41.         };
  42.  
  43.         PluginConfig DefaultConfig()
  44.         {
  45.             var DefaultConfig = new PluginConfig
  46.             {
  47.                 ThirdPartyPanels = new Dictionary<string, Dictionary<string, PanelConfig>>(),
  48.  
  49.                 Messages = Messages,
  50.                 TimeFormats = TimeFormats,
  51.                 CompassDirections = new Dictionary<string, string>
  52.                 {
  53.                     {"n","North"},
  54.                     {"ne","Northeast"},
  55.                     {"e","East"},
  56.                     {"se","Southeast"},
  57.                     {"s","South"},
  58.                     {"sw","Southwest"},
  59.                     {"w","West"},
  60.                     {"nw","Northwest"},
  61.                 },
  62.                 Docks = new Dictionary<string, DockConfig>
  63.                 {
  64.                     { "BottomLeftDock", new DockConfig
  65.                         {
  66.                             Available = true,
  67.                             Width = 0.18f,
  68.                             Height = 0.03f,
  69.                             AnchorX = "Left",
  70.                             AnchorY = "Bottom",
  71.                             Margin = "0.005 0.165 0.005 0.005",
  72.                             BackgroundColor = "0 0 0 0.4",
  73.                         }
  74.                     },
  75.                     { "BottomRightDock", new DockConfig
  76.                         {
  77.                             Available = true,
  78.                             Width = 0.19f,
  79.                             Height = 0.03f,
  80.                             AnchorX = "Right",
  81.                             AnchorY = "Bottom",
  82.                             Margin = "0.005 0.005 0.005 0.165",
  83.                             BackgroundColor = "0 0 0 0.4",
  84.                         }
  85.                     },
  86.                     { "TopLeftDock", new DockConfig
  87.                         {
  88.                             Available = true,
  89.                             Width = 0.175f,
  90.                             Height = 0.03f,
  91.                             AnchorX = "Left",
  92.                             AnchorY = "Top",
  93.                             Margin = "0.005 0.005 0.005 0.005",
  94.                             BackgroundColor = "0 0 0 0.4",
  95.                         }
  96.                     },
  97.                     { "TopRightDock", new DockConfig
  98.                         {
  99.                             Available = true,
  100.                             Width = 0.29f,
  101.                             Height = 0.03f,
  102.                             AnchorX = "Right",
  103.                             AnchorY = "Top",
  104.                             Margin = "0.005 0.005 0.005 0.005",
  105.                             BackgroundColor = "0 0 0 0.4",
  106.                         }
  107.                     }
  108.                 },
  109.  
  110.                 Panels = new Dictionary<string, PanelConfig>
  111.                 {
  112.                     {"Clock", new PanelConfig
  113.                         {
  114.                             Available = true,
  115.                             Dock = "BottomLeftDock",
  116.                             Order = 1,
  117.                             AnchorX = "Left",
  118.                             AnchorY = "Bottom",
  119.                             Margin = "0 0 0 0.01",
  120.                             Width = 0.2f,
  121.                             Height = 0.95f,
  122.                             BackgroundColor = "0.1 0.1 0.1 0",
  123.                             Text = new PanelTextConfig
  124.                             {
  125.                                 Align = TextAnchor.MiddleCenter,
  126.                                 FontColor = DefaultFontColor,
  127.                                 FontSize = 14,
  128.                                 Margin = "0 0.01 0 0.01",
  129.                             },
  130.                             PanelSettings = new Dictionary<string,object>
  131.                             {
  132.                                 { "ClockUpdateFrequency (seconds)" , ClockUpdateFrequency },
  133.                                 { "TimeFormat", "HH:mm" }
  134.                             }
  135.                         }
  136.                     },
  137.                     { "MessageBox", new PanelConfig
  138.                         {
  139.                             Available = true,
  140.                             Dock = "TopRightDock",
  141.                             Order = 7,
  142.                             AnchorX = "Right",
  143.                             AnchorY = "Bottom",
  144.                             Margin = "0 0 0 0.005",
  145.                             Width = 1f,
  146.                             Height = 0.95f,
  147.                             BackgroundColor = "0 0 0 0.4",
  148.                             Text = new PanelTextConfig
  149.                             {
  150.                                 Align = TextAnchor.MiddleCenter,
  151.                                 FontColor = DefaultFontColor,
  152.                                 FontSize = 14,
  153.                             },
  154.                             PanelSettings = new Dictionary<string,object>
  155.                             {
  156.                                 { "MessageUpdateFrequency (seconds)", MessageUpdateFrequency },
  157.                                 { "MsgOrder","normal" }
  158.                             }
  159.                         }
  160.                     },
  161.                     { "Balance", new PanelConfig
  162.                         {
  163.                             Available = true,
  164.                             Dock = "BottomLeftDock",
  165.                             Order = 7,
  166.                             AnchorX = "Left",
  167.                             AnchorY = "Bottom",
  168.                             Margin = "0 0 0 0.01",
  169.                             Width = 0.4f,
  170.                             Height = 0.95f,
  171.                             BackgroundColor = "0 0 0 0.4" ,
  172.                             Image = new PanelImageConfig
  173.                             {
  174.                                 Order =  1,
  175.                                 Width = 0.2f,
  176.                                 Height = 0.8f,
  177.                                 Margin = "0 0.01 0.1 0.01",
  178.                                 Url = "http://i.imgur.com/HhL5TvU.png",
  179.                             },
  180.                             Text = new PanelTextConfig
  181.                             {
  182.                                 Order =  2,
  183.                                 Width = 0.848f,
  184.                                 Height = 1f,
  185.                                 Align = TextAnchor.MiddleCenter,
  186.                                 FontColor = DefaultFontColor,
  187.                                 FontSize = 12,
  188.                                 Margin = "0 0.02 0 0",
  189.                             },
  190.                             PanelSettings = new Dictionary<string,object>
  191.                             {
  192.                                 { "RefreshRate(s)", "5" },
  193.                             }
  194.                         }
  195.                     },
  196.                     { "Points", new PanelConfig
  197.                         {
  198.                             Available = true,
  199.                             Dock = "BottomLeftDock",
  200.                             Order = 8,
  201.                             AnchorX = "Left",
  202.                             AnchorY = "Bottom",
  203.                             Margin = "0 0 0 0.01",
  204.                             Width = 0.4f,
  205.                             Height = 0.95f,
  206.                             BackgroundColor = "0 0 0 0.4" ,
  207.                             Image = new PanelImageConfig
  208.                             {
  209.                                 Order =  1,
  210.                                 Width = 0.2f,
  211.                                 Height = 0.8f,
  212.                                 Margin = "0 0.01 0.1 0.01",
  213.                                 Url = "http://i.imgur.com/dwzul4T.png",
  214.                             },
  215.                             Text = new PanelTextConfig
  216.                             {
  217.                                 Order =  2,
  218.                                 Width = 0.848f,
  219.                                 Height = 1f,
  220.                                 Align = TextAnchor.MiddleCenter,
  221.                                 FontColor = DefaultFontColor,
  222.                                 FontSize = 12,
  223.                                 Margin = "0 0.02 0 0",
  224.                             },
  225.                             PanelSettings = new Dictionary<string,object>
  226.                             {
  227.                                 { "RefreshRate(s)", "5" },
  228.                             }
  229.                         }
  230.                     },
  231.                     { "Coordinates", new PanelConfig
  232.                         {
  233.                             Available = true,
  234.                             Dock = "TopLeftDock",
  235.                             Order = 7,
  236.                             AnchorX = "Left",
  237.                             AnchorY = "Bottom",
  238.                             Margin = "0 0 0 0.01",
  239.                             Width = 0.5f,
  240.                             Height = 0.95f,
  241.                             BackgroundColor = "0 0 0 0.4" ,
  242.                             Image = new PanelImageConfig
  243.                             {
  244.                                 Order =  1,
  245.                                 Width = 0.13f,
  246.                                 Height = 0.8f,
  247.                                 Margin = "0 0.01 0.1 0.01",
  248.                                 Url = "http://i.imgur.com/Kr1pQ5b.png",
  249.                             },
  250.                             Text = new PanelTextConfig
  251.                             {
  252.                                 Order =  2,
  253.                                 Width = 0.848f,
  254.                                 Height = 1f,
  255.                                 Align = TextAnchor.MiddleCenter,
  256.                                 FontColor = DefaultFontColor,
  257.                                 FontSize = 12,
  258.                                 Margin = "0 0.02 0 0",
  259.                             },
  260.                             PanelSettings = new Dictionary<string,object>
  261.                             {
  262.                                 { "RefreshRate(s)", "3" },
  263.                             }
  264.                         }
  265.                     },
  266.                     { "Compass", new PanelConfig
  267.                         {
  268.                             Available = false,
  269.                             Dock = "BottomRightDock",
  270.                             Order = 8,
  271.                             AnchorX = "Left",
  272.                             AnchorY = "Bottom",
  273.                             Margin = "0 0 0 0.01",
  274.                             Width = 0.5f,
  275.                             Height = 0.95f,
  276.                             BackgroundColor = "0 0 0 0.4" ,
  277.                             Image = new PanelImageConfig
  278.                             {
  279.                                 Order =  1,
  280.                                 Width = 0.188f,
  281.                                 Height = 0.8f,
  282.                                 Margin = "0 0.01 0.1 0.03",
  283.                                 Url = "http://i.imgur.com/dG5nOOJ.png",
  284.                             },
  285.                             Text = new PanelTextConfig
  286.                             {
  287.                                 Order =  2,
  288.                                 Width = 0.76f,
  289.                                 Height = 1f,
  290.                                 Align = TextAnchor.MiddleCenter,
  291.                                 FontColor = DefaultFontColor,
  292.                                 FontSize = 12,
  293.                                 Margin = "0 0.02 0 0",
  294.                             },
  295.                             PanelSettings = new Dictionary<string,object>
  296.                             {
  297.                                 { "RefreshRate(s)", "1" },
  298.                                 { "TextOrAngle", "text" }
  299.                             }
  300.                         }
  301.                     },
  302.                     { "OPlayers", new PanelConfig
  303.                         {
  304.                             Available = true,
  305.                             Dock = "TopLeftDock",
  306.                             Order = 2,
  307.                             AnchorX = "Left",
  308.                             AnchorY = "Bottom",
  309.                             Margin = "0 0 0 0.01",
  310.                             Width = 0.31f,
  311.                             Height = 0.95f,
  312.                             BackgroundColor = "0 0 0 0.4" ,
  313.                             Image = new PanelImageConfig
  314.                             {
  315.                                 Order =  1,
  316.                                 Width = 0.35f,
  317.                                 Height = 0.8f,
  318.                                 Margin = "0 0.05 0.1 0.05",
  319.                                 Url = "http://i.imgur.com/n9EYIWi.png",
  320.                             },
  321.                             Text = new PanelTextConfig
  322.                             {
  323.                                 Order =  2,
  324.                                 Width = 0.68f,
  325.                                 Height = 1f,
  326.                                 Align = TextAnchor.MiddleCenter,
  327.                                 FontColor = DefaultFontColor,
  328.                                 FontSize = 14,
  329.                             }
  330.                         }
  331.                     },
  332.                     { "Sleepers", new PanelConfig
  333.                         {
  334.                             Available = true,
  335.                             Dock = "TopLeftDock",
  336.                             Order = 3,
  337.                             AnchorX = "Left",
  338.                             AnchorY = "Bottom",
  339.                             Margin = "0 0 0 0.01",
  340.                             Width = 0.225f,
  341.                             Height = 0.95f,
  342.                             BackgroundColor = "0 0 0 0.4",
  343.                             Image = new PanelImageConfig
  344.                             {
  345.                                 Order =  1,
  346.                                 Width = 0.4f,
  347.                                 Height = 0.8f,
  348.                                 Margin = "0 0.05 0.1 0.05",
  349.                                 Url = "http://i.imgur.com/XIIZkqD.png",
  350.                             },
  351.                             Text = new PanelTextConfig
  352.                             {
  353.                                 Order =  2,
  354.                                 Width = 0.63f,
  355.                                 Height = 1f,
  356.                                 Align = TextAnchor.MiddleCenter,
  357.                                 FontColor = DefaultFontColor,
  358.                                 FontSize = 14,
  359.                             }
  360.                         }
  361.                     },
  362.                     { "AirdropEvent", new PanelConfig
  363.                         {
  364.                             Available = true,
  365.                             Dock = "TopLeftDock",
  366.                             Order =  4,
  367.                             AnchorX = "Left",
  368.                             AnchorY = "Bottom",
  369.                             Margin = "0 0 0 0.01",
  370.                             Width = 0.1f,
  371.                             Height = 0.95f,
  372.                             BackgroundColor = "0 0 0 0.4",
  373.                             Image = new PanelImageConfig
  374.                                 {
  375.                                     Order =  1,
  376.                                     Width = 0.8f,
  377.                                     Height = 0.8f,
  378.                                     Margin = "0 0.1 0.1 0.1",
  379.                                     Url = "http://i.imgur.com/dble6vf.png",
  380.                                 },
  381.                             PanelSettings = new Dictionary<string,object>
  382.                             {
  383.                                 { "InactiveColor", "1 1 1 0.1" },
  384.                                 { "ActiveColor", "0 1 0 1" },
  385.                             }
  386.                         }
  387.                     },
  388.                     { "BradleyEvent", new PanelConfig
  389.                         {
  390.                             Available = true,
  391.                             Dock = "TopLeftDock",
  392.                             Order = 5,
  393.                             AnchorX = "Left",
  394.                             AnchorY = "Bottom",
  395.                             Margin = "0 0 0 0.01",
  396.                             Width = 0.1f,
  397.                             Height = 0.95f,
  398.                             BackgroundColor = "0 0 0 0.4",
  399.                             Image = new PanelImageConfig
  400.                             {
  401.                                 Order =  1,
  402.                                 Width = 0.75f,
  403.                                 Height = 0.8f,
  404.                                 Margin = "0 0.15 0.1 0.1",
  405.                                 Url = "https://i.imgur.com/8kBSdIe.png",
  406.                             },
  407.                             PanelSettings = new Dictionary<string,object>
  408.                             {
  409.                                 { "InactiveColor", "1 1 1 0.1" },
  410.                                 { "ActiveColor", "0.7 0.2 0.2 1" },
  411.                             }
  412.  
  413.                         }
  414.                     },
  415.                     { "HelicopterEvent", new PanelConfig
  416.                         {
  417.                             Available = true,
  418.                             Dock = "TopLeftDock",
  419.                             Order = 5,
  420.                             AnchorX = "Left",
  421.                             AnchorY = "Bottom",
  422.                             Margin = "0 0 0 0.01",
  423.                             Width = 0.1f,
  424.                             Height = 0.95f,
  425.                             BackgroundColor = "0 0 0 0.4",
  426.                             Image = new PanelImageConfig
  427.                             {
  428.                                 Order =  1,
  429.                                 Width = 0.75f,
  430.                                 Height = 0.8f,
  431.                                 Margin = "0 0.15 0.1 0.1",
  432.                                 Url = "http://i.imgur.com/hTTyTTx.png",
  433.                             },
  434.                             PanelSettings = new Dictionary<string,object>
  435.                             {
  436.                                 { "InactiveColor", "1 1 1 0.1" },
  437.                                 { "ActiveColor", "0.7 0.2 0.2 1" },
  438.                             }
  439.  
  440.                         }
  441.                     },
  442.                    
  443.                     { "ChinookEvent", new PanelConfig
  444.                         {
  445.                             Available = true,
  446.                             Dock = "TopLeftDock",
  447.                             Order = 5,
  448.                             AnchorX = "Left",
  449.                             AnchorY = "Bottom",
  450.                             Margin = "0 0 0 0.01",
  451.                             Width = 0.1f,
  452.                             Height = 0.95f,
  453.                             BackgroundColor = "0 0 0 0.4",
  454.                             Image = new PanelImageConfig
  455.                             {
  456.                                 Order =  1,
  457.                                 Width = 0.75f,
  458.                                 Height = 0.8f,
  459.                                 Margin = "0 0.15 0.1 0.1",
  460.                                 Url = "https://i.imgur.com/49d8ZcK.png",
  461.                             },
  462.                             PanelSettings = new Dictionary<string,object>
  463.                             {
  464.                                 { "InactiveColor", "1 1 1 0.1" },
  465.                                 { "ActiveColor", "0.7 0.2 0.2 1" },
  466.                             }
  467.  
  468.                         }
  469.                     },
  470.                     { "CargoShipEvent", new PanelConfig
  471.                         {
  472.                             Available = true,
  473.                             Dock = "TopLeftDock",
  474.                             Order = 5,
  475.                             AnchorX = "Left",
  476.                             AnchorY = "Bottom",
  477.                             Margin = "0 0 0 0.01",
  478.                             Width = 0.1f,
  479.                             Height = 0.95f,
  480.                             BackgroundColor = "0 0 0 0.4",
  481.                             Image = new PanelImageConfig
  482.                             {
  483.                                 Order =  1,
  484.                                 Width = 0.75f,
  485.                                 Height = 0.8f,
  486.                                 Margin = "0 0.15 0.1 0.1",
  487.                                 Url = "https://i.imgur.com/WQiNxyM.png",
  488.                             },
  489.                             PanelSettings = new Dictionary<string,object>
  490.                             {
  491.                                 { "InactiveColor", "1 1 1 0.1" },
  492.                                  { "ActiveColor", "0 1 0 1" },
  493.                             }
  494.  
  495.                         }
  496.                     },
  497.                    
  498.                     { "Radiation", new PanelConfig
  499.                         {
  500.                             Available = false,
  501.                             Dock = "TopLeftDock",
  502.                             Order = 6,
  503.                             AnchorX = "Left",
  504.                             AnchorY = "Bottom",
  505.                             Margin = "0 0 0 0.01",
  506.                             Width = 0.1f,
  507.                             Height = 0.95f,
  508.                             BackgroundColor = "0 0 0 0.4",
  509.                             Image = new PanelImageConfig
  510.                             {
  511.                                 Order =  1,
  512.                                 Width = 0.75f,
  513.                                 Height = 0.8f,
  514.                                 Margin = "0 0.15 0.1 0.1",
  515.                                 Url = "http://i.imgur.com/owVdFsK.png",
  516.                             },
  517.                             PanelSettings = new Dictionary<string,object>
  518.                             {
  519.                                 { "InactiveColor", "1 1 1 0.1" },
  520.                                 { "ActiveColor", "1 1 0 1" },
  521.                                 { "RefreshRate(s)", "3"}
  522.                             }
  523.  
  524.                         }
  525.                     }
  526.                 }
  527.             };
  528.  
  529.             return DefaultConfig;
  530.         }
  531.  
  532.         class PluginConfig
  533.         {
  534.             //public Dictionary<string, string> Settings { get; set; }
  535.  
  536.             public Dictionary<string, DockConfig> Docks { get; set; }
  537.             public Dictionary<string, PanelConfig> Panels { get; set; }
  538.  
  539.             public Dictionary<string, Dictionary<string, PanelConfig>> ThirdPartyPanels { get; set; }
  540.  
  541.             public List<string> Messages { get; set; }
  542.             public List<string> TimeFormats { get; set; }
  543.             public Dictionary<string, string> CompassDirections { get; set; }
  544.  
  545.             public T GetPanelSettingsValue<T>(string Panel, string Setting, T defaultValue)
  546.             {
  547.                 PanelConfig panelConfig;
  548.                 if (!Panels.TryGetValue(Panel, out panelConfig))
  549.                     return defaultValue;
  550.  
  551.                 if (panelConfig.PanelSettings == null)
  552.                     return defaultValue;
  553.  
  554.                 object value;
  555.                 if (!panelConfig.PanelSettings.TryGetValue(Setting, out value))
  556.                     return defaultValue;
  557.  
  558.                 return (T)Convert.ChangeType(value, typeof(T));
  559.             }
  560.  
  561.             public bool CheckPanelAvailability(string Panel)
  562.             {
  563.                 PanelConfig panelConfig;
  564.                 if (!Panels.TryGetValue(Panel, out panelConfig))
  565.                     return false;
  566.  
  567.                 if (!panelConfig.Available)
  568.                     return false;
  569.  
  570.                 DockConfig dockConfig;
  571.                 return Docks.TryGetValue(panelConfig.Dock, out dockConfig) && dockConfig.Available;
  572.             }
  573.  
  574.         }
  575.  
  576.         class DockConfig
  577.         {
  578.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  579.             public bool Available { get; set; } = true;
  580.  
  581.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  582.             public string AnchorX { get; set; } = "Left";
  583.  
  584.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  585.             public string AnchorY { get; set; } = "Bottom";
  586.  
  587.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  588.             public float Width { get; set; } = 0.05f;
  589.  
  590.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  591.             public float Height { get; set; } = 0.95f;
  592.  
  593.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  594.             public string BackgroundColor { get; set; } = "0 0 0 0.4";
  595.  
  596.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  597.             public string Margin { get; set; } = "0 0 0 0.005";
  598.  
  599.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  600.             public PanelImageConfig Image { get; set; }
  601.         }
  602.  
  603.         class BasePanelConfig
  604.         {
  605.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  606.             public bool Available { get; set; } = true;
  607.  
  608.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  609.             public string AnchorX { get; set; } = "Left";
  610.  
  611.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  612.             public string AnchorY { get; set; } = "Bottom";
  613.  
  614.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  615.             public float Width { get; set; } = 0.05f;
  616.  
  617.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  618.             public float Height { get; set; } = 0.95f;
  619.  
  620.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  621.             public int Order { get; set; }
  622.  
  623.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  624.             public string BackgroundColor { get; set; } = "0 0 0 0.4";
  625.  
  626.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  627.             public string Margin { get; set; } = "0 0 0 0.005";
  628.         }
  629.  
  630.         class PanelConfig : BasePanelConfig
  631.         {
  632.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  633.             public bool Autoload { get; set; } = true;
  634.  
  635.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  636.             public string Dock { get; set; } = "BottomLeftDock";
  637.  
  638.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  639.             public Dictionary<string, object> PanelSettings { get; set; }
  640.  
  641.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  642.             public PanelImageConfig Image { get; set; }
  643.  
  644.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  645.             public PanelTextConfig Text { get; set; }
  646.  
  647.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  648.             public float FadeOut { get; set; }
  649.         }
  650.  
  651.         class PanelTextConfig : BasePanelConfig
  652.         {
  653.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  654.             public new float Width { get; set; } = 1f;
  655.  
  656.             [JsonConverter(typeof(StringEnumConverter))]
  657.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  658.             public TextAnchor Align { get; set; } = TextAnchor.MiddleCenter;
  659.  
  660.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  661.             public string FontColor { get; set; } = "1 1 1 1";
  662.  
  663.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  664.             public int FontSize { get; set; } = 14;
  665.  
  666.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  667.             public string Content { get; set; } = "No Content";
  668.  
  669.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  670.             public float FadeIn { get; set; }
  671.  
  672.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  673.             public float FadeOut { get; set; }
  674.         }
  675.  
  676.         class PanelImageConfig : BasePanelConfig
  677.         {
  678.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  679.             public new float Width { get; set; } = 1f;
  680.  
  681.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  682.             public string Url { get; set; }
  683.  
  684.             [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
  685.             public string Color { get; set; } = null;
  686.         }
  687.  
  688.         protected void LoadConfigValues()
  689.         {
  690.             Settings = Config.ReadObject<PluginConfig>();
  691.  
  692.             var UnOrderPanels = Settings.Panels.Where(p => p.Value.Order == 0).ToDictionary(s => s.Key, s => s.Value);
  693.  
  694.             if (UnOrderPanels.Count == 0)
  695.                 return;
  696.  
  697.             PrintWarning("Reordering Panels.");
  698.  
  699.             foreach (var PanelCfg in UnOrderPanels)
  700.             {
  701.                 //int HighestSiblingOrder = Settings.Panels.Where(p => p.Value.Dock == Settings.Panels[PanelName].Dock && p.Value.AnchorX == Settings.Panels[PanelName].AnchorX).Max(m => m.Value.Order);
  702.                 Settings.Panels[PanelCfg.Key].Order = PanelReOrder(PanelCfg.Value.Dock, PanelCfg.Value.AnchorX);
  703.             }
  704.  
  705.             Config.WriteObject(Settings, true);
  706.             PrintWarning("Config Saved.");
  707.         }
  708.  
  709.         int PanelReOrder(string DockName, string AnchorX)
  710.         {
  711.             var SiblingPanels = Settings.Panels.Where(p => p.Value.Dock == DockName && p.Value.AnchorX == AnchorX);
  712.  
  713.             var Max = 0;
  714.             if (SiblingPanels.Any())
  715.                 Max = SiblingPanels.Max(m => m.Value.Order);
  716.  
  717.             foreach (var pPanelCfg in Settings.ThirdPartyPanels)
  718.             {
  719.                 if (pPanelCfg.Value.Count == 0) { continue; }
  720.  
  721.                 var SiblingPluginPAnels = pPanelCfg.Value.Where(p => p.Value.Dock == DockName && p.Value.AnchorX == AnchorX);
  722.  
  723.                 if (SiblingPluginPAnels.Any())
  724.                 {
  725.                     var PluginMax = pPanelCfg.Value.Where(p => p.Value.Dock == DockName && p.Value.AnchorX == AnchorX).Max(m => m.Value.Order);
  726.                     if (PluginMax > Max)
  727.                         Max = PluginMax;
  728.                 }
  729.             }
  730.             return Max + 1;
  731.         }
  732.  
  733.         #endregion
  734.  
  735.         #region Hooks
  736.  
  737.         protected override void LoadDefaultConfig()
  738.         {
  739.             Config.Clear();
  740.             Config.WriteObject(DefaultConfig(), true);
  741.             PrintWarning("Default configuration file created.");
  742.         }
  743.  
  744.         void Init()
  745.         {
  746.             LoadConfigValues();
  747.             LoadData();
  748.         }
  749.  
  750.         void OnServerInitialized()
  751.         {
  752.             Clock = new Watch
  753.             (
  754.                 Settings.GetPanelSettingsValue("Clock", "ClockUpdateFrequency (seconds)", ClockUpdateFrequency),
  755.                 Settings.CheckPanelAvailability("Clock")
  756.             );
  757.  
  758.             MessageBox = new Messenger
  759.             (
  760.                 Settings.Messages,
  761.                 Settings.GetPanelSettingsValue("MessageBox", "MessageUpdateFrequency (seconds)", MessageUpdateFrequency),
  762.                 Settings.GetPanelSettingsValue("MessageBox", "MsgOrder", "normal")
  763.             );
  764.  
  765.             Airplane = new AirplaneEvent();
  766.             Bradley = new BradleyEvent();
  767.             Helicopter = new HelicopterEvent();
  768.             Cargoship = new CargoshipEvent();
  769.             Chinook = new ChinookEvent();
  770.  
  771.             CompassObj = new Compass
  772.             (
  773.                 Settings.GetPanelSettingsValue("Compass", "RefreshRate(s)", 1)
  774.             );
  775.  
  776.             Rad = new Radiation
  777.             (
  778.                 Settings.GetPanelSettingsValue("Radiation", "RefreshRate(s)", 3)
  779.             );
  780.  
  781.             Poi = new Points
  782.             (
  783.                 Settings.GetPanelSettingsValue("Points", "RefreshRate(s)", 3)
  784.             );
  785.            
  786.             Bala = new Balance
  787.             (
  788.                 Settings.GetPanelSettingsValue("Balance", "RefreshRate(s)", 3)
  789.             );
  790.            
  791.             Coord = new Coordinates
  792.             (
  793.                 Settings.GetPanelSettingsValue("Coordinates", "RefreshRate(s)", 3)
  794.             );
  795.  
  796.             foreach (var player in BasePlayer.activePlayerList)
  797.             {
  798.                 LoadPanels(player);
  799.                 InitializeGUI(player);
  800.             }
  801.  
  802.             if (Settings.CheckPanelAvailability("Radiation"))
  803.             {
  804.                 RadiationUpdater = timer.Repeat(Rad.RefreshRate, 0, () => Rad.Refresh(storedData, PlayerPanels));
  805.             }
  806.  
  807.             if (Settings.CheckPanelAvailability("Points"))
  808.             {
  809.                 PointsUpdater = timer.Repeat(Poi.RefreshRate, 0, () => Poi.Refresh(storedData, PlayerPanels));
  810.             }
  811.            
  812.             if (Settings.CheckPanelAvailability("Balance"))
  813.             {
  814.                 BalanceUpdater = timer.Repeat(Bala.RefreshRate, 0, () => Bala.Refresh(storedData, PlayerPanels));
  815.             }
  816.            
  817.             if (Settings.CheckPanelAvailability("Coordinates"))
  818.             {
  819.                 CoordUpdater = timer.Repeat(Coord.RefreshRate, 0, () => Coord.Refresh(storedData, PlayerPanels));
  820.             }
  821.  
  822.             if (Settings.CheckPanelAvailability("MessageBox"))
  823.             {
  824.                 MsgUpdater = timer.Repeat(MessageBox.RefreshRate, 0, () => MessageBox.Refresh(storedData, PlayerPanels));
  825.             }
  826.  
  827.             if (Settings.CheckPanelAvailability("Clock"))
  828.             {
  829.                 TimeUpdater = timer.Repeat(Clock.RefresRate, 0, () => Clock.Refresh(storedData, PlayerPanels));
  830.             }
  831.  
  832.             if (Settings.CheckPanelAvailability("Compass"))
  833.             {
  834.                 CompassUpdater = timer.Repeat(CompassObj.RefreshRate, 0, () => CompassObj.Refresh(storedData, PlayerPanels));
  835.             }
  836.  
  837.             //TestTimer = timer.Repeat(5, 0, () => TestSH());
  838.  
  839.             ActivePlanes = UnityEngine.Object.FindObjectsOfType<CargoPlane>().ToList();
  840.  
  841.             if (ActivePlanes.Count > 0)
  842.             {
  843.                 CheckAirplane();
  844.             }
  845.             else
  846.             {
  847.                 Airplane.Refresh(storedData, PlayerPanels);
  848.             }
  849.  
  850.             ActiveBradleys = UnityEngine.Object.FindObjectsOfType<BradleyAPC>().ToList();
  851.  
  852.             if (ActiveBradleys.Count > 0)
  853.             {
  854.                 CheckBradley();
  855.             }
  856.             else
  857.             {
  858.                 Bradley.Refresh(storedData, PlayerPanels);
  859.             }
  860.  
  861.             ActiveHelicopters = UnityEngine.Object.FindObjectsOfType<BaseHelicopter>().ToList();
  862.  
  863.             if (ActiveHelicopters.Count > 0)
  864.             {
  865.                 CheckHelicopter();
  866.             }
  867.             else
  868.             {
  869.                 Helicopter.Refresh(storedData, PlayerPanels);
  870.             }
  871.            
  872.             ActiveChinooks = UnityEngine.Object.FindObjectsOfType<CH47Helicopter>().ToList();
  873.  
  874.             if (ActiveChinooks.Count > 0)
  875.             {
  876.                 CheckChinook();
  877.             }
  878.             else
  879.             {
  880.                 Chinook.Refresh(storedData, PlayerPanels);
  881.             }
  882.  
  883.             ActiveCargoships = UnityEngine.Object.FindObjectsOfType<CargoShip>().ToList();
  884.  
  885.             if (ActiveCargoships.Count > 0)
  886.             {
  887.                 CheckCargoship();
  888.             }
  889.             else
  890.             {
  891.                 Cargoship.Refresh(storedData, PlayerPanels);
  892.             }
  893.  
  894.             IsReady = true;
  895.         }
  896.  
  897.         void OnPlayerConnected(BasePlayer player)
  898.         {
  899.             if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot))
  900.             {
  901.                 timer.Once(2, () => OnPlayerConnected(player));
  902.                 return;
  903.             }
  904.             if (PlayerPanels.ContainsKey(player.UserIDString))
  905.             {
  906.                 PlayerPanels.Remove(player.UserIDString);
  907.             }
  908.  
  909.             if (PlayerDockPanels.ContainsKey(player.UserIDString))
  910.             {
  911.                 PlayerDockPanels.Remove(player.UserIDString);
  912.             }
  913.  
  914.             timer.In(1, () => GUITimerInit(player));
  915.         }
  916.  
  917.         void OnPlayerDisconnected(BasePlayer player)
  918.         {
  919.             PlayerPanels.Remove(player.UserIDString);
  920.             PlayerDockPanels.Remove(player.UserIDString);
  921.  
  922.             timer.Once(2, RefreshOnlinePlayers);
  923.             timer.Once(2, RefreshSleepers);
  924.         }
  925.  
  926.         void OnPlayerSleepEnded(BasePlayer player)
  927.         {
  928.             timer.Once(2, RefreshSleepers);
  929.         }
  930.  
  931.         private void OnEntitySpawned(BaseEntity Entity)
  932.         {
  933.             if (!IsReady)
  934.             {
  935.                 timer.In(10, () => OnEntitySpawned(Entity));
  936.                 return;
  937.             }
  938.  
  939.             if (Entity == null) return;
  940.             if (Entity is BradleyAPC && Settings.Panels["BradleyEvent"].Available)
  941.             {
  942.                 ActiveBradleys.Add((BradleyAPC) Entity);
  943.  
  944.                 if (BradleyTimer == false)
  945.                 {
  946.                     CheckBradley();
  947.                 }
  948.             }
  949.  
  950.             if (Entity is BaseHelicopter && Settings.Panels["HelicopterEvent"].Available)
  951.             {
  952.                 ActiveHelicopters.Add((BaseHelicopter) Entity);
  953.  
  954.                 if (HelicopterTimer == false)
  955.                 {
  956.                     CheckHelicopter();
  957.                 }
  958.             }
  959.  
  960.             if (Entity is CargoPlane && Settings.Panels["AirdropEvent"].Available)
  961.             {
  962.                 ActivePlanes.Add((CargoPlane) Entity);
  963.  
  964.                 if (AirplaneTimer == false)
  965.                 {
  966.                     CheckAirplane();
  967.                 }
  968.             }
  969.            
  970.             if (Entity is CargoShip && Settings.Panels["CargoShipEvent"].Available)
  971.             {
  972.                 ActiveCargoships.Add((CargoShip)Entity);
  973.  
  974.                 if (CargoshipTimer == false)
  975.                 {
  976.                     CheckCargoship();
  977.                 }
  978.             }
  979.  
  980.             if (Entity is CH47Helicopter && Settings.Panels["ChinookEvent"].Available)
  981.             {
  982.                 ActiveChinooks.Add((CH47Helicopter)Entity);
  983.  
  984.                 if (ChinookTimer == false)
  985.                 {
  986.                     CheckChinook();
  987.                 }
  988.             }
  989.            
  990.         }
  991.  
  992.  
  993.  
  994.         private void Unload()
  995.         {
  996.             foreach (var player in BasePlayer.activePlayerList)
  997.                 DestroyGUI(player);
  998.  
  999.             SaveData();
  1000.  
  1001.             PlayerPanels.Clear();
  1002.             PlayerDockPanels.Clear();
  1003.  
  1004.             Err.Clear();
  1005.             ErrD.Clear();
  1006.             ErrB.Clear();
  1007.             ErrA.Clear();
  1008.  
  1009.             storedData = null;
  1010.             Settings = null;
  1011.         }
  1012.  
  1013.         void OnPluginUnloaded(Plugin plugin)
  1014.         {
  1015.             if (!Settings.ThirdPartyPanels.ContainsKey(plugin.Title)) return;
  1016.             var PluginPanels = LoadedPluginPanels[plugin.Title];
  1017.  
  1018.             foreach(var PanelName in PluginPanels)
  1019.             {
  1020.                 foreach (var pair in PlayerPanels)
  1021.                 {
  1022.                     pair.Value[PanelName].DestroyPanel();
  1023.                     pair.Value[PanelName].Remover();
  1024.                 }
  1025.             }
  1026.  
  1027.             LoadedPluginPanels.Remove(plugin.Title);
  1028.         }
  1029.  
  1030.         void OnServerSave()
  1031.         {
  1032.             SaveData();
  1033.         }
  1034.  
  1035.         void OnServerShutdown()
  1036.         {
  1037.             SaveData();
  1038.         }
  1039.  
  1040.         #endregion
  1041.  
  1042.         #region PanelLoad
  1043.         /// <summary>
  1044.         /// </summary>
  1045.         /// <param name="Player"></param>
  1046.         private void LoadPanels(BasePlayer Player)
  1047.         {
  1048.             foreach(var Docks in Settings.Docks)
  1049.             {
  1050.                 if (!Settings.Docks[Docks.Key].Available)
  1051.                     continue;
  1052.                 LoadDockPanel(Docks.Key, Player);
  1053.             }
  1054.  
  1055.             var playerDockPanel = PlayerDockPanels[Player.UserIDString];
  1056.             foreach (var grouppedByDock in Settings.Panels.GroupBy(g => g.Value.Dock).ToDictionary(gd => gd.Key, gd => gd.Select(p => p).ToDictionary(gk => gk.Key, gk => gk.Value)))
  1057.             {
  1058.                 if (!Settings.Docks[grouppedByDock.Key].Available)
  1059.                     continue;
  1060.  
  1061.                 foreach (var panelCfg in grouppedByDock.Value)
  1062.                 {
  1063.                     if (!Settings.CheckPanelAvailability(panelCfg.Key))
  1064.                         continue;
  1065.  
  1066.                     LoadPanel(playerDockPanel[grouppedByDock.Key], panelCfg.Key, panelCfg.Value);
  1067.                 }
  1068.             }
  1069.  
  1070.             foreach(var loadedPluginPanel in LoadedPluginPanels)
  1071.             {
  1072.                 foreach(var panelName in loadedPluginPanel.Value)
  1073.                 {
  1074.                     Dictionary<string, PanelConfig> panelConfigs;
  1075.                     PanelConfig panelConfig;
  1076.                     if (!Settings.ThirdPartyPanels.TryGetValue(loadedPluginPanel.Key, out panelConfigs)
  1077.                         || !panelConfigs.TryGetValue(panelName, out panelConfig)
  1078.                         || !panelConfig.Available)
  1079.                         continue;
  1080.  
  1081.                     LoadPanel(playerDockPanel[panelConfig.Dock], panelName, panelConfig);
  1082.                 }
  1083.             }
  1084.         }
  1085.  
  1086.         private IPanel LoadDockPanel(string DockName, BasePlayer Player)
  1087.         {
  1088.             var dockConfig = Settings.Docks[DockName];
  1089.             var DockPanel = new IPanel(DockName, Player, PlayerPanels, PlayerDockPanels)
  1090.             {
  1091.                 Width = dockConfig.Width,
  1092.                 Height = dockConfig.Height,
  1093.                 AnchorX = dockConfig.AnchorX,
  1094.                 AnchorY = dockConfig.AnchorY,
  1095.                 Margin = Vector4Parser(dockConfig.Margin),
  1096.                 BackgroundColor = ColorEx.Parse(dockConfig.BackgroundColor),
  1097.                 IsDock = true
  1098.             };
  1099.  
  1100.             //LoadedDocks.Add(DockName, DockPanel);
  1101.  
  1102.             Dictionary<string, IPanel> panels;
  1103.             if(!PlayerDockPanels.TryGetValue(Player.UserIDString, out panels))
  1104.                 PlayerDockPanels.Add(Player.UserIDString, panels = new Dictionary<string, IPanel>());
  1105.             panels.Add(DockName, DockPanel);
  1106.  
  1107.             return DockPanel;
  1108.         }
  1109.  
  1110.         private void LoadPanel(IPanel Dock, string PanelName, PanelConfig PCfg)
  1111.         {
  1112.             var Panel = Dock.AddPanel(PanelName);
  1113.             Panel.Width = PCfg.Width;
  1114.             Panel.Height = PCfg.Height;
  1115.             Panel.AnchorX = PCfg.AnchorX;
  1116.             Panel.AnchorY = PCfg.AnchorY;
  1117.             Panel.Margin = Vector4Parser(PCfg.Margin);
  1118.             Panel.BackgroundColor = ColorEx.Parse(PCfg.BackgroundColor);
  1119.             Panel.Order = PCfg.Order;
  1120.             Panel.Autoload = PCfg.Autoload;
  1121.             Panel.IsPanel = true;
  1122.             Panel.DockName = Dock.Name;
  1123.             Panel.FadeOut = Dock.FadeOut;
  1124.  
  1125.             if (PCfg.Text != null)
  1126.             {
  1127.                 var Text = Panel.AddText(PanelName + "Text");
  1128.                 Text.Width = PCfg.Text.Width;
  1129.                 Text.Height = PCfg.Text.Height;
  1130.                 Text.Margin = Vector4Parser(PCfg.Text.Margin);
  1131.                 Text.Content = PCfg.Text.Content;
  1132.                 Text.FontColor = ColorEx.Parse(PCfg.Text.FontColor);
  1133.                 Text.FontSize = PCfg.Text.FontSize;
  1134.                 Text.Align = PCfg.Text.Align;
  1135.                 Text.Order = PCfg.Text.Order;
  1136.                 Text.FadeOut = PCfg.Text.FadeOut;
  1137.                 Text.TextComponent.FadeIn = PCfg.Text.FadeIn;
  1138.             }
  1139.  
  1140.             if (PCfg.Image != null)
  1141.             {
  1142.                 var Image = Panel.AddImage(PanelName + "Image");
  1143.                 Image.Width = PCfg.Image.Width;
  1144.                 Image.Height = PCfg.Image.Height;
  1145.                 Image.Margin = Vector4Parser(PCfg.Image.Margin);
  1146.                 Image.Url = PCfg.Image.Url;
  1147.                 Image.Order = PCfg.Image.Order;
  1148.                 if (PCfg.Image.Color != null)
  1149.                     Image.Color = ColorEx.Parse(PCfg.Image.Color);
  1150.             }
  1151.         }
  1152.  
  1153.         #endregion
  1154.  
  1155.         #region Clock
  1156.  
  1157.         private Watch Clock;
  1158.         private int ClockUpdateFrequency = 4;
  1159.         private Timer TimeUpdater;
  1160.  
  1161.         public class Watch
  1162.         {
  1163.             string ClockFormat = "HH:mm";
  1164.             public int RefresRate = 4;
  1165.             public bool Available = true;
  1166.  
  1167.             TOD_Sky Sky = TOD_Sky.Instance;
  1168.  
  1169.             public Watch(int RefreshRate, bool Available)
  1170.             {
  1171.                 RefresRate = RefreshRate;
  1172.                 this.Available = Available;
  1173.             }
  1174.  
  1175.             public string GetServerTime(string PlayerID, StoredData storedData)
  1176.             {
  1177.                 return DateTime.Now.AddHours(storedData.GetPlayerPanelSettings(PlayerID, "Clock", "Offset", 0)).ToString(storedData.GetPlayerPanelSettings(PlayerID, "Clock", "TimeFormat", ClockFormat), CultureInfo.InvariantCulture);
  1178.             }
  1179.  
  1180.             public string GetSkyTime(string PlayerID, StoredData storedData)
  1181.             {
  1182.                 return Sky.Cycle.DateTime.ToString(storedData.GetPlayerPanelSettings(PlayerID, "Clock", "TimeFormat", ClockFormat), CultureInfo.InvariantCulture);
  1183.             }
  1184.  
  1185.             public string ShowTime(string PlayerID, StoredData storedData)
  1186.             {
  1187.                 if (storedData.GetPlayerPanelSettings(PlayerID, "Clock", "Type", "Game") == "Server")
  1188.                     return GetServerTime(PlayerID, storedData);
  1189.  
  1190.                 return GetSkyTime(PlayerID, storedData);
  1191.             }
  1192.  
  1193.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1194.             {
  1195.                 if (!Settings.CheckPanelAvailability("Clock"))
  1196.                     return;
  1197.  
  1198.                 foreach (var panel in panels)
  1199.                 {
  1200.                     IPanel iPanel;
  1201.                     if (!panel.Value.TryGetValue("ClockText", out iPanel)) continue;
  1202.                     var showTime = ShowTime(panel.Key, storedData);
  1203.                     var panelText = (IPanelText)iPanel;
  1204.                     if (!showTime.Equals(panelText.Content))
  1205.                     {
  1206.                         panelText.Content = showTime;
  1207.                         panelText.Refresh();
  1208.                     }
  1209.                 }
  1210.             }
  1211.         }
  1212.  
  1213.         #endregion
  1214.  
  1215.         #region MessageBox
  1216.  
  1217.         private Messenger MessageBox;
  1218.         private Timer MsgUpdater;
  1219.         private int MessageUpdateFrequency = 20;
  1220.         private List<string> Messages = new List<string> { "Welcome!", "Beware! You Are Not Alone!", "Leeeeeeeeeeeroy Jenkins" };
  1221.         private bool MessageBoxAvailable = true;
  1222.  
  1223.  
  1224.         public class Messenger
  1225.         {
  1226.             List<string> Messages;
  1227.             public int RefreshRate = 20;
  1228.             private int Counter = 0;
  1229.             private string MsgOrder = "normal";
  1230.  
  1231.             public Messenger(List<string> msgs, int RefreshRate,string MsgOrder)
  1232.             {
  1233.                 Messages = msgs;
  1234.                 this.RefreshRate = RefreshRate;
  1235.                 this.MsgOrder = MsgOrder;
  1236.  
  1237.                 if (MsgOrder == "random")
  1238.                 {
  1239.                     Counter = Core.Random.Range(0, Messages.Count - 1);
  1240.                 }
  1241.  
  1242.             }
  1243.  
  1244.             public string GetMessage()
  1245.             {
  1246.                 return Messages[Counter];
  1247.             }
  1248.  
  1249.             private void RefreshCounter()
  1250.             {
  1251.                 if (MsgOrder == "random")
  1252.                 {
  1253.                     var OldCounter = Counter;
  1254.                     var NewCounter = Core.Random.Range(0, Messages.Count - 1);
  1255.  
  1256.                     if(OldCounter == NewCounter)
  1257.                     {
  1258.                         if(NewCounter+1 <= Messages.Count-1)
  1259.                         {
  1260.                             Counter = NewCounter + 1;
  1261.                             return;
  1262.                         }
  1263.                         else if(NewCounter - 1 >= 0)
  1264.                         {
  1265.                             Counter = NewCounter - 1;
  1266.                             return;
  1267.                         }
  1268.                     }
  1269.  
  1270.                     Counter = NewCounter;
  1271.                     return;
  1272.                 }
  1273.  
  1274.                 Counter++;
  1275.                 if (Counter >= Messages.Count)
  1276.                     Counter = 0;
  1277.             }
  1278.  
  1279.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1280.             {
  1281.                 if (!Settings.CheckPanelAvailability("MessageBox"))
  1282.                     return;
  1283.  
  1284.                 foreach (var panel in panels)
  1285.                 {
  1286.                     IPanel iPanel;
  1287.                     if (!panel.Value.TryGetValue("MessageBoxText", out iPanel)) continue;
  1288.                     var message = GetMessage();
  1289.                     var panelText = (IPanelText)iPanel;
  1290.                     if (!message.Equals(panelText.Content))
  1291.                     {
  1292.                         panelText.Content = message;
  1293.                         panelText.Refresh();
  1294.                     }
  1295.                 }
  1296.  
  1297.                 RefreshCounter();
  1298.             }
  1299.  
  1300.         }
  1301.         #endregion
  1302.  
  1303.         #region Events
  1304.         private Timer BradleyActive;
  1305.         private Timer HeliAttack;
  1306.         private Timer RadiationUpdater;
  1307.  
  1308.         private AirplaneEvent Airplane;
  1309.         private List<CargoPlane> ActivePlanes;
  1310.         private bool AirplaneTimer = false;
  1311.  
  1312.         private BradleyEvent Bradley;
  1313.         private List<BradleyAPC> ActiveBradleys;
  1314.         private bool BradleyTimer = false;
  1315.  
  1316.         private HelicopterEvent Helicopter;
  1317.         private List<BaseHelicopter> ActiveHelicopters;
  1318.         private bool HelicopterTimer = false;
  1319.  
  1320.         private CargoshipEvent Cargoship;
  1321.         private List<CargoShip> ActiveCargoships;
  1322.         private bool CargoshipTimer = false;
  1323.  
  1324.         private ChinookEvent Chinook;
  1325.         private List<CH47Helicopter> ActiveChinooks;
  1326.         private bool ChinookTimer = false;
  1327.        
  1328.         private Radiation Rad;
  1329.  
  1330.         private BradleyAPC ActiveBradley;
  1331.         private BaseHelicopter ActiveHelicopter;
  1332.         private CH47Helicopter ActiveChinook;
  1333.         private CargoShip ActiveCargoship;
  1334.  
  1335.         public class AirplaneEvent
  1336.         {
  1337.             public bool isActive = false;
  1338.             public Color ImageColor;
  1339.  
  1340.             public AirplaneEvent()
  1341.             {
  1342.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("AirdropEvent", "InactiveColor", "1 1 1 0.1"));
  1343.             }
  1344.  
  1345.             public void SetActivity(bool active)
  1346.             {
  1347.                 isActive = active;
  1348.  
  1349.                 if (isActive)
  1350.                 {
  1351.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("AirdropEvent", "ActiveColor", "0 1 0 1"));
  1352.                     return;
  1353.                 }
  1354.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("AirdropEvent", "InactiveColor", "1 1 1 0.1"));
  1355.                 return;
  1356.             }
  1357.  
  1358.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1359.             {
  1360.                 if (!Settings.CheckPanelAvailability("AirdropEvent"))
  1361.                     return;
  1362.  
  1363.                 foreach (var panel in panels)
  1364.                 {
  1365.                     IPanel iPanel;
  1366.                     if (!panel.Value.TryGetValue("AirdropEventImage", out iPanel)) continue;
  1367.                     var panelRawImage = (IPanelRawImage)iPanel;
  1368.                     if (panelRawImage.Color != ImageColor)
  1369.                     {
  1370.                         panelRawImage.Color = ImageColor;
  1371.                         panelRawImage.Refresh();
  1372.                     }
  1373.                 }
  1374.             }
  1375.         }
  1376.  
  1377.         public class BradleyEvent
  1378.         {
  1379.             public bool isActive = false;
  1380.             public Color ImageColor;
  1381.  
  1382.             public BradleyEvent()
  1383.             {
  1384.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("BradleyEvent", "InactiveColor", "1 1 1 0.1"));
  1385.             }
  1386.  
  1387.             public void SetActivity(bool active)
  1388.             {
  1389.                 isActive = active;
  1390.  
  1391.                 if (isActive)
  1392.                 {
  1393.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("BradleyEvent", "ActiveColor", "1 0 0 1"));
  1394.                     return;
  1395.                 }
  1396.  
  1397.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("BradleyEvent", "InactiveColor", "1 1 1 0.1"));
  1398.             }
  1399.  
  1400.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1401.             {
  1402.                 if (!Settings.CheckPanelAvailability("BradleyEvent"))
  1403.                     return;
  1404.  
  1405.                 foreach (var panel in panels)
  1406.                 {
  1407.                     IPanel iPanel;
  1408.                     if (!panel.Value.TryGetValue("BradleyEventImage", out iPanel)) continue;
  1409.                     var panelRawImage = (IPanelRawImage)iPanel;
  1410.                     if (panelRawImage.Color != ImageColor)
  1411.                     {
  1412.                         panelRawImage.Color = ImageColor;
  1413.                         panelRawImage.Refresh();
  1414.                     }
  1415.                 }
  1416.             }
  1417.         }
  1418.  
  1419.         public class HelicopterEvent
  1420.         {
  1421.             public bool isActive = false;
  1422.             public Color ImageColor;
  1423.  
  1424.             public HelicopterEvent()
  1425.             {
  1426.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("HelicopterEvent", "InactiveColor", "1 1 1 0.1"));
  1427.             }
  1428.  
  1429.             public void SetActivity(bool active)
  1430.             {
  1431.                 isActive = active;
  1432.  
  1433.                 if (isActive)
  1434.                 {
  1435.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("HelicopterEvent", "ActiveColor", "1 0 0 1"));
  1436.                     return;
  1437.                 }
  1438.  
  1439.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("HelicopterEvent", "InactiveColor", "1 1 1 0.1"));
  1440.             }
  1441.  
  1442.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1443.             {
  1444.                 if (!Settings.CheckPanelAvailability("HelicopterEvent"))
  1445.                     return;
  1446.  
  1447.                 foreach (var panel in panels)
  1448.                 {
  1449.                     IPanel iPanel;
  1450.                     if (!panel.Value.TryGetValue("HelicopterEventImage", out iPanel)) continue;
  1451.                     var panelRawImage = (IPanelRawImage)iPanel;
  1452.                     if (panelRawImage.Color != ImageColor)
  1453.                     {
  1454.                         panelRawImage.Color = ImageColor;
  1455.                         panelRawImage.Refresh();
  1456.                     }
  1457.                 }
  1458.             }
  1459.         }
  1460.        
  1461.        
  1462.         public class CargoshipEvent
  1463.         {
  1464.             public bool isActive = false;
  1465.             public Color ImageColor;
  1466.  
  1467.             public CargoshipEvent()
  1468.             {
  1469.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("CargoShipEvent", "InactiveColor", "1 1 1 0.1"));
  1470.             }
  1471.  
  1472.             public void SetActivity(bool active)
  1473.             {
  1474.                 isActive = active;
  1475.  
  1476.                 if (isActive)
  1477.                 {
  1478.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("CargoShipEvent", "ActiveColor", "1 0 0 1"));
  1479.                     return;
  1480.                 }
  1481.  
  1482.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("CargoShipEvent", "InactiveColor", "1 1 1 0.1"));
  1483.             }
  1484.  
  1485.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1486.             {
  1487.                 if (!Settings.CheckPanelAvailability("CargoShipEvent"))
  1488.                     return;
  1489.  
  1490.                 foreach (var panel in panels)
  1491.                 {
  1492.                     IPanel iPanel;
  1493.                     if (!panel.Value.TryGetValue("CargoShipEventImage", out iPanel)) continue;
  1494.                     var panelRawImage = (IPanelRawImage)iPanel;
  1495.                     if (panelRawImage.Color != ImageColor)
  1496.                     {
  1497.                         panelRawImage.Color = ImageColor;
  1498.                         panelRawImage.Refresh();
  1499.                     }
  1500.                 }
  1501.             }
  1502.         }
  1503.  
  1504.         public class ChinookEvent
  1505.         {
  1506.             public bool isActive = false;
  1507.             public Color ImageColor;
  1508.  
  1509.             public ChinookEvent()
  1510.             {
  1511.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("ChinookEvent", "InactiveColor", "1 1 1 0.1"));
  1512.             }
  1513.  
  1514.             public void SetActivity(bool active)
  1515.             {
  1516.                 isActive = active;
  1517.  
  1518.                 if (isActive)
  1519.                 {
  1520.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("ChinookEvent", "ActiveColor", "1 0 0 1"));
  1521.                     return;
  1522.                 }
  1523.  
  1524.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("ChinookEvent", "InactiveColor", "1 1 1 0.1"));
  1525.             }
  1526.  
  1527.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1528.             {
  1529.                 if (!Settings.CheckPanelAvailability("ChinookEvent"))
  1530.                     return;
  1531.  
  1532.                 foreach (var panel in panels)
  1533.                 {
  1534.                     IPanel iPanel;
  1535.                     if (!panel.Value.TryGetValue("ChinookEventImage", out iPanel)) continue;
  1536.                     var panelRawImage = (IPanelRawImage)iPanel;
  1537.                     if (panelRawImage.Color != ImageColor)
  1538.                     {
  1539.                         panelRawImage.Color = ImageColor;
  1540.                         panelRawImage.Refresh();
  1541.                     }
  1542.                 }
  1543.             }
  1544.         }
  1545.  
  1546.         public class Radiation
  1547.         {
  1548.             bool isActive = false;
  1549.             public Color ImageColor;
  1550.             public int RefreshRate = 3;
  1551.  
  1552.             public Radiation(int RefreshRate)
  1553.             {
  1554.                 isActive = ConVar.Server.radiation;
  1555.                 this.RefreshRate = RefreshRate;
  1556.                 if (isActive)
  1557.                 {
  1558.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("Radiation", "ActiveColor", "1 1 0 1"));
  1559.                 }
  1560.                 else
  1561.                 {
  1562.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("Radiation", "InactiveColor", "1 1 1 0.1"));
  1563.                 }
  1564.             }
  1565.  
  1566.             public void SetActivity(bool active)
  1567.             {
  1568.                 isActive = active;
  1569.  
  1570.                 if (isActive)
  1571.                 {
  1572.                     ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("Radiation", "ActiveColor", "1 0 0 1"));
  1573.                     return;
  1574.                 }
  1575.  
  1576.                 ImageColor = ColorEx.Parse(Settings.GetPanelSettingsValue("Radiation", "InactiveColor", "1 1 1 0.1"));
  1577.             }
  1578.  
  1579.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1580.             {
  1581.                 if (isActive == ConVar.Server.radiation)
  1582.                     return;
  1583.  
  1584.                 SetActivity(ConVar.Server.radiation);
  1585.  
  1586.                 if (!Settings.CheckPanelAvailability("Radiation"))
  1587.                     return;
  1588.  
  1589.                 foreach (var panel in panels)
  1590.                 {
  1591.                     IPanel iPanel;
  1592.                     if (!panel.Value.TryGetValue("RadiationImage", out iPanel)) continue;
  1593.                     var panelRawImage = (IPanelRawImage)iPanel;
  1594.                     if (panelRawImage.Color != ImageColor)
  1595.                     {
  1596.                         panelRawImage.Color = ImageColor;
  1597.                         panelRawImage.Refresh();
  1598.                     }
  1599.                 }
  1600.             }
  1601.         }
  1602.  
  1603.         public void CheckAirplane()
  1604.         {
  1605.             ActivePlanes.RemoveAll(p => !p.IsValid() || !p.gameObject.activeInHierarchy);
  1606.             if (ActivePlanes.Count > 0)
  1607.             {
  1608.                 if(Airplane.isActive == false)
  1609.                 {
  1610.                     Airplane.SetActivity(true);
  1611.                     Airplane.Refresh(storedData, PlayerPanels);
  1612.                 }
  1613.  
  1614.                 AirplaneTimer = true;
  1615.                 timer.In(10, CheckAirplane);
  1616.                 return;
  1617.             }
  1618.  
  1619.             Airplane.SetActivity(false);
  1620.             Airplane.Refresh(storedData, PlayerPanels);
  1621.             AirplaneTimer = false;
  1622.         }
  1623.  
  1624.         public void CheckBradley()
  1625.         {
  1626.             ActiveBradleys.RemoveAll(p => !p.IsValid() || !p.gameObject.activeInHierarchy);
  1627.  
  1628.             if (ActiveBradleys.Count > 0)
  1629.             {
  1630.  
  1631.                 if (Bradley.isActive == false)
  1632.                 {
  1633.                     Bradley.SetActivity(true);
  1634.                     Bradley.Refresh(storedData, PlayerPanels);
  1635.                 }
  1636.  
  1637.                 BradleyTimer = true;
  1638.                 timer.In(5, CheckBradley);
  1639.                 return;
  1640.             }
  1641.  
  1642.             Bradley.SetActivity(false);
  1643.             Bradley.Refresh(storedData, PlayerPanels);
  1644.             BradleyTimer = false;
  1645.         }
  1646.  
  1647.         public void CheckHelicopter()
  1648.         {
  1649.             ActiveHelicopters.RemoveAll(p => !p.IsValid() || !p.gameObject.activeInHierarchy);
  1650.  
  1651.             if (ActiveHelicopters.Count > 0)
  1652.             {
  1653.  
  1654.                 if (Helicopter.isActive == false)
  1655.                 {
  1656.                     Helicopter.SetActivity(true);
  1657.                     Helicopter.Refresh(storedData, PlayerPanels);
  1658.                 }
  1659.  
  1660.                 HelicopterTimer = true;
  1661.                 timer.In(5, CheckHelicopter);
  1662.                 return;
  1663.             }
  1664.  
  1665.             Helicopter.SetActivity(false);
  1666.             Helicopter.Refresh(storedData, PlayerPanels);
  1667.             HelicopterTimer = false;
  1668.         }
  1669.        
  1670.         public void CheckCargoship()
  1671.         {
  1672.             ActiveCargoships.RemoveAll(p => !p.IsValid() || !p.gameObject.activeInHierarchy);
  1673.  
  1674.             if (ActiveCargoships.Count > 0)
  1675.             {
  1676.  
  1677.                 if (Cargoship.isActive == false)
  1678.                 {
  1679.                     Cargoship.SetActivity(true);
  1680.                     Cargoship.Refresh(storedData, PlayerPanels);
  1681.                 }
  1682.  
  1683.                 CargoshipTimer = true;
  1684.                 timer.In(5, CheckCargoship);
  1685.                 return;
  1686.             }
  1687.  
  1688.             Cargoship.SetActivity(false);
  1689.             Cargoship.Refresh(storedData, PlayerPanels);
  1690.             CargoshipTimer = false;
  1691.         }
  1692.  
  1693.         public void CheckChinook()
  1694.         {
  1695.             ActiveChinooks.RemoveAll(p => !p.IsValid() || !p.gameObject.activeInHierarchy);
  1696.  
  1697.             if (ActiveChinooks.Count > 0)
  1698.             {
  1699.  
  1700.                 if (Chinook.isActive == false)
  1701.                 {
  1702.                     Chinook.SetActivity(true);
  1703.                     Chinook.Refresh(storedData, PlayerPanels);
  1704.                 }
  1705.  
  1706.                 ChinookTimer = true;
  1707.                 timer.In(5, CheckChinook);
  1708.                 return;
  1709.             }
  1710.  
  1711.             Chinook.SetActivity(false);
  1712.             Chinook.Refresh(storedData, PlayerPanels);
  1713.             ChinookTimer = false;
  1714.         }
  1715.  
  1716.         #endregion
  1717.  
  1718.         #region Balance
  1719.  
  1720.         private Balance Bala;
  1721.         private Timer BalanceUpdater;
  1722.         public class Balance
  1723.         {
  1724.             public int RefreshRate = 3;
  1725.  
  1726.             public Balance(int RefreshRate)
  1727.             {
  1728.                 this.RefreshRate = RefreshRate;
  1729.             }
  1730.  
  1731.             public double GetBalance(string PlayerID)
  1732.             {
  1733.                 var player = RustCore.FindPlayerByIdString(PlayerID);
  1734.                 if (player == null) return 0.0;
  1735.                 return (double)(Interface.Oxide.CallHook("Balance", player.UserIDString) ?? 0.0);
  1736.             }
  1737.  
  1738.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1739.             {
  1740.                 if (!Settings.CheckPanelAvailability("Balance"))
  1741.                     return;
  1742.  
  1743.                 foreach (var panel in panels)
  1744.                 {
  1745.                     IPanel iPanel;
  1746.                     if (!panel.Value.TryGetValue("BalanceText", out iPanel)) continue;
  1747.                     var balance = $"{GetBalance(panel.Key):N}";
  1748.                     var panelText = (IPanelText)iPanel;
  1749.                     if (!balance.Equals(panelText.Content))
  1750.                     {
  1751.                         panelText.Content = balance;
  1752.                         panelText.Refresh();
  1753.                     }
  1754.                 }
  1755.             }
  1756.         }
  1757.         #endregion
  1758.        
  1759.         #region Points
  1760.  
  1761.         private Points Poi;
  1762.         private Timer PointsUpdater;
  1763.         public class Points
  1764.         {
  1765.             public int RefreshRate = 3;
  1766.  
  1767.             public Points(int RefreshRate)
  1768.             {
  1769.                 this.RefreshRate = RefreshRate;
  1770.             }
  1771.  
  1772.             public int GetPoints(string PlayerID)
  1773.             {
  1774.                 var player = RustCore.FindPlayerByIdString(PlayerID);
  1775.                 if (player == null) return 0;
  1776.                 return (int)(Interface.Oxide.CallHook("CheckPoints", player.userID) ?? 0);
  1777.             }
  1778.  
  1779.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1780.             {
  1781.                 if (!Settings.CheckPanelAvailability("Points"))
  1782.                     return;
  1783.  
  1784.                 foreach (var panel in panels)
  1785.                 {
  1786.                     IPanel iPanel;
  1787.                     if (!panel.Value.TryGetValue("PointsText", out iPanel)) continue;
  1788.                     var points = $"{GetPoints(panel.Key)}";
  1789.                     var panelText = (IPanelText)iPanel;
  1790.                     if (!points.Equals(panelText.Content))
  1791.                     {
  1792.                         panelText.Content = points;
  1793.                         panelText.Refresh();
  1794.                     }
  1795.                 }
  1796.             }
  1797.         }
  1798.         #endregion
  1799.  
  1800.         #region Coordinates
  1801.  
  1802.         private Coordinates Coord;
  1803.  
  1804.         private Timer CoordUpdater;
  1805.  
  1806.         public class Coordinates
  1807.         {
  1808.             public int RefreshRate = 3;
  1809.  
  1810.             public Coordinates(int RefreshRate)
  1811.             {
  1812.                 this.RefreshRate = RefreshRate;
  1813.             }
  1814.  
  1815.             public string GetCoord(string PlayerID)
  1816.             {
  1817.                 var player = RustCore.FindPlayerByIdString(PlayerID);
  1818.                 if (player == null) return string.Empty;
  1819.                 return $"X: {player.transform.position.x.ToString("0")} | Z: {player.transform.position.z.ToString("0")}";
  1820.             }
  1821.  
  1822.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1823.             {
  1824.                 if (!Settings.CheckPanelAvailability("Coordinates"))
  1825.                     return;
  1826.  
  1827.                 foreach (var panel in panels)
  1828.                 {
  1829.                     IPanel iPanel;
  1830.                     if (!panel.Value.TryGetValue("CoordinatesText", out iPanel)) continue;
  1831.                     var coord = GetCoord(panel.Key);
  1832.                     var panelText = (IPanelText)iPanel;
  1833.                     if (!coord.Equals(panelText.Content))
  1834.                     {
  1835.                         panelText.Content = coord;
  1836.                         panelText.Refresh();
  1837.                     }
  1838.                 }
  1839.             }
  1840.         }
  1841.         #endregion
  1842.  
  1843.         #region Compass
  1844.  
  1845.         private Compass CompassObj;
  1846.  
  1847.         private Timer CompassUpdater;
  1848.  
  1849.         public class Compass
  1850.         {
  1851.             public int RefreshRate = 3;
  1852.  
  1853.             public Compass(int RefreshRate)
  1854.             {
  1855.                 this.RefreshRate = RefreshRate;
  1856.             }
  1857.  
  1858.             public string GetDirection(string PlayerID)
  1859.             {
  1860.                 var player = RustCore.FindPlayerByIdString(PlayerID);
  1861.  
  1862.                 if (player == null) return string.Empty;
  1863.  
  1864.                 var PCurrent = player.eyes.rotation.eulerAngles;
  1865.  
  1866.                 string str = $"{PCurrent.y.ToString("0")}\u00B0";
  1867.  
  1868.                 if (Settings.GetPanelSettingsValue("Compass", "TextOrAngle", "text") == "text")
  1869.                 {
  1870.                     if (PCurrent.y > 337.5 || PCurrent.y < 22.5)
  1871.                         str = Settings.CompassDirections["n"];
  1872.                     else if (PCurrent.y > 22.5 && PCurrent.y < 67.5)
  1873.                         str = Settings.CompassDirections["ne"];
  1874.                     else if (PCurrent.y > 67.5 && PCurrent.y < 112.5)
  1875.                         str = Settings.CompassDirections["e"];
  1876.                     else if (PCurrent.y > 112.5 && PCurrent.y < 157.5)
  1877.                         str = Settings.CompassDirections["se"];
  1878.                     else if (PCurrent.y > 157.5 && PCurrent.y < 202.5)
  1879.                         str = Settings.CompassDirections["s"];
  1880.                     else if (PCurrent.y > 202.5 && PCurrent.y < 247.5)
  1881.                         str = Settings.CompassDirections["sw"];
  1882.                     else if (PCurrent.y > 247.5 && PCurrent.y < 292.5)
  1883.                         str = Settings.CompassDirections["w"];
  1884.                     else if (PCurrent.y > 292.5 && PCurrent.y < 337.5)
  1885.                         str = Settings.CompassDirections["nw"];
  1886.                 }
  1887.  
  1888.                 return str;
  1889.             }
  1890.  
  1891.             public void Refresh(StoredData storedData, Dictionary<string, Dictionary<string, IPanel>> panels)
  1892.             {
  1893.                 if (!Settings.CheckPanelAvailability("Compass"))
  1894.                 {
  1895.                     return;
  1896.                 }
  1897.  
  1898.                 foreach (var panel in panels)
  1899.                 {
  1900.                     if (panel.Value.ContainsKey("CompassText"))
  1901.                     {
  1902.                         var direction = GetDirection(panel.Key);
  1903.                         var panelText = (IPanelText)panel.Value["CompassText"];
  1904.                         if (!direction.Equals(panelText.Content))
  1905.                         {
  1906.                             panelText.Content = direction;
  1907.                             panelText.Refresh();
  1908.                         }
  1909.                     }
  1910.                 }
  1911.             }
  1912.         }
  1913.  
  1914.         #endregion
  1915.  
  1916.         #region Commands
  1917.  
  1918.         [ChatCommand("ipanel")]
  1919.         private void IPanelCommand(BasePlayer player, string command, string[] args)
  1920.         {
  1921.             if (args.Length == 0)
  1922.             {
  1923.                 var Str = "InfoPanel Available Commands:\n";
  1924.                 Str += "<b><color=#ffa500ff>/ipanel</color></b> - Chat Command list \n";
  1925.                 Str += "<b><color=#ffa500ff>/ipanel <hide|show></color></b>- To hide or show the panel. \n";
  1926.                 Str += "<b><color=#ffa500ff>/ipanel clock game</color></b> - Change to game time. \n";
  1927.                 Str += "<b><color=#ffa500ff>/ipanel clock server <offset></color></b> - Change to server time.\n Offset: Add hours to the clock. (-23 - 23) \n";
  1928.                 Str += "<b><color=#ffa500ff>/ipanel timeformat</color></b> - To change time format. \n";
  1929.  
  1930.                 PrintToChat(player, Str);
  1931.  
  1932.                 return;
  1933.             }
  1934.  
  1935.             switch (args[0])
  1936.             {
  1937.                 case "hide":
  1938.                     if (!storedData.GetPlayerSettings(player.UserIDString, "enable", true))
  1939.                     {
  1940.                         break;
  1941.                     }
  1942.  
  1943.                     ChangePlayerSettings(player, "enable", "false");
  1944.                     DestroyGUI(player);
  1945.                     break;
  1946.                 case "show":
  1947.                     if (storedData.GetPlayerSettings(player.UserIDString, "enable", true))
  1948.                     {
  1949.                         break;
  1950.                     }
  1951.  
  1952.                     ChangePlayerSettings(player, "enable", "true");
  1953.                     RevealGUI(player);
  1954.                     break;
  1955.  
  1956.                 case "clock":
  1957.                     if (args[1] == "server")
  1958.                     {
  1959.                         ChangePlayerPanelSettings(player, "Clock", "Type", "Server");
  1960.  
  1961.                         if (args.Length == 3)
  1962.                         {
  1963.                             var offset = 0;
  1964.  
  1965.                             if (int.TryParse(args[2], out offset) && offset > -23 && offset < 23)
  1966.                             {
  1967.                                 ChangePlayerPanelSettings(player, "Clock", "Offset", offset.ToString());
  1968.                             }
  1969.                         }
  1970.  
  1971.                     }
  1972.                     else if (args[1] == "game")
  1973.                     {
  1974.                         ChangePlayerPanelSettings(player, "Clock", "Type", "Game");
  1975.                     }
  1976.                     break;
  1977.                 case "timeformat":
  1978.                     if (args.Length == 1)
  1979.                     {
  1980.                         var Str = "Available Time Formats:\n";
  1981.  
  1982.                         for (var index = 0; index < Settings.TimeFormats.Count; index++)
  1983.                         {
  1984.                             Str += $"[<color=#ffa500ff>{index}</color>] - {DateTime.Now.ToString(Settings.TimeFormats[index])}\n";
  1985.                         }
  1986.  
  1987.                         PrintToChat(player, Str+"Usage: /ipanel timeformat <color=#ffa500ff> NUMBER </color>");
  1988.                     }
  1989.                     else if(args.Length == 2)
  1990.                     {
  1991.                         var TimeFormat = 0;
  1992.                         if (int.TryParse(args[1], out TimeFormat) && TimeFormat >= 0 && TimeFormat < Settings.TimeFormats.Count)
  1993.                         {
  1994.                             ChangePlayerPanelSettings(player, "Clock", "TimeFormat", TimeFormats[TimeFormat]);
  1995.                         }
  1996.                     }
  1997.                     break;
  1998.                 default:
  1999.                     PrintToChat(player, "Wrong Command!");
  2000.                     break;
  2001.             };
  2002.  
  2003.         }
  2004.  
  2005.         [ChatCommand("iptest")]
  2006.         private void IPaCommand(BasePlayer player, string command, string[] args)
  2007.         {
  2008.  
  2009.         }
  2010.  
  2011.         [ChatCommand("iperr")]
  2012.         private void IPCommand(BasePlayer player, string command, string[] args)
  2013.         {
  2014.             /*
  2015.             foreach (string item in Err)
  2016.             {
  2017.                 Puts(item);
  2018.             }*/
  2019.  
  2020.             /*foreach (KeyValuePair<string,Dictionary<string,IPanel>> item in PlayerDockPanels)
  2021.             {
  2022.                 foreach (KeyValuePair<string, IPanel> itemm in item.Value)
  2023.                 {
  2024.                     Puts(itemm.Key);
  2025.                 }
  2026.             }*/
  2027.             /*
  2028.             foreach (KeyValuePair<string, int> item in ErrB.OrderBy(k => k.Key))
  2029.             {
  2030.                 Puts(item.Key + " - " + item.Value);
  2031.             }*/
  2032.            /*
  2033.             foreach (KeyValuePair<string, List<string>> item in ErrA)
  2034.             {
  2035.                 Puts(item.Key + " -> ");
  2036.  
  2037.                 foreach (string itemm in item.Value)
  2038.                 {
  2039.                     Puts(itemm);
  2040.                 }
  2041.  
  2042.                 Puts("--------");
  2043.             }*/
  2044.  
  2045.             Err.Clear();
  2046.             ErrA.Clear();
  2047.             ErrB.Clear();
  2048.         }
  2049.  
  2050.         #endregion
  2051.  
  2052.         #region StoredData
  2053.  
  2054.         public static StoredData storedData;
  2055.  
  2056.         public class StoredData
  2057.         {
  2058.             public Dictionary<string, PlayerSettings> Players;
  2059.  
  2060.             public StoredData()
  2061.             {
  2062.                 Players = new Dictionary<string, PlayerSettings>();
  2063.             }
  2064.  
  2065.             public bool CheckPlayerData(BasePlayer Player)
  2066.             {
  2067.                 return Players.ContainsKey(Player.UserIDString);
  2068.             }
  2069.  
  2070.             public T GetPlayerSettings<T>(string PlayerID, string Key, T DefaultValue)
  2071.             {
  2072.                 PlayerSettings playerSettings;
  2073.                 if (Players.TryGetValue(PlayerID, out playerSettings))
  2074.                     return playerSettings.GetSetting(Key, DefaultValue);
  2075.                 return DefaultValue;
  2076.             }
  2077.  
  2078.             public T GetPlayerPanelSettings<T>(BasePlayer Player, string Panel, string Key, T DefaultValue)
  2079.             {
  2080.                 PlayerSettings playerSettings;
  2081.                 if (Players.TryGetValue(Player.UserIDString, out playerSettings))
  2082.                     return playerSettings.GetPanelSetting(Panel, Key, DefaultValue);
  2083.                 return DefaultValue;
  2084.             }
  2085.  
  2086.             public T GetPlayerPanelSettings<T>(string PlayerID, string Panel, string Key, T DefaultValue)
  2087.             {
  2088.                 PlayerSettings playerSettings;
  2089.                 if (Players.TryGetValue(PlayerID, out playerSettings))
  2090.                     return playerSettings.GetPanelSetting(Panel, Key, DefaultValue);
  2091.                 return DefaultValue;
  2092.             }
  2093.  
  2094.         }
  2095.  
  2096.         public class PlayerSettings
  2097.         {
  2098.             public string UserId;
  2099.             public Dictionary<string, string> Settings;
  2100.             public Dictionary<string, Dictionary<string, string>> PanelSettings;
  2101.  
  2102.             public PlayerSettings()
  2103.             {
  2104.                 Settings = new Dictionary<string, string>();
  2105.                 PanelSettings = new Dictionary<string, Dictionary<string, string>>();
  2106.             }
  2107.  
  2108.             public PlayerSettings(BasePlayer player)
  2109.             {
  2110.                 UserId = player.UserIDString;
  2111.                 Settings = new Dictionary<string, string>();
  2112.                 PanelSettings = new Dictionary<string, Dictionary<string, string>>();
  2113.             }
  2114.  
  2115.             public void SetSetting(string Key, string Value)
  2116.             {
  2117.                 Settings[Key] = Value;
  2118.             }
  2119.  
  2120.             public void SetPanelSetting(string Panel, string Key, string Value)
  2121.             {
  2122.                 Dictionary<string, string> settings;
  2123.                 if (!PanelSettings.TryGetValue(Panel, out settings))
  2124.                     PanelSettings.Add(Panel, settings = new Dictionary<string, string>());
  2125.  
  2126.                 settings[Key] = Value;
  2127.             }
  2128.  
  2129.             public T GetPanelSetting<T>(string Panel, string Key, T DefaultValue)
  2130.             {
  2131.                 Dictionary<string, string> PanelConfig;
  2132.                 if (!PanelSettings.TryGetValue(Panel, out PanelConfig))
  2133.                     return DefaultValue;
  2134.  
  2135.                 string value;
  2136.                 if (!PanelConfig.TryGetValue(Key, out value))
  2137.                     return DefaultValue;
  2138.  
  2139.                 if (value == null)
  2140.                     return DefaultValue;
  2141.                 return (T)Convert.ChangeType(value, typeof(T));
  2142.             }
  2143.  
  2144.  
  2145.             public T GetSetting<T>(string Key, T DefaultValue)
  2146.             {
  2147.  
  2148.                 string value;
  2149.                 if (!Settings.TryGetValue(Key, out value))
  2150.                     return DefaultValue;
  2151.  
  2152.                 if (value == null)
  2153.                     return DefaultValue;
  2154.  
  2155.                 return (T)Convert.ChangeType(value, typeof(T));
  2156.             }
  2157.  
  2158.         }
  2159.  
  2160.         public void LoadData()
  2161.         {
  2162.             storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>("InfoPanel_db");
  2163.             if (storedData == null)
  2164.             {
  2165.                 storedData = new StoredData();
  2166.                 SaveData();
  2167.             }
  2168.         }
  2169.  
  2170.         public void SaveData()
  2171.         {
  2172.             Interface.Oxide.DataFileSystem.WriteObject("InfoPanel_db", storedData);
  2173.         }
  2174.  
  2175.         public void ChangePlayerSettings(BasePlayer player, string Key, string Value)
  2176.         {
  2177.             PlayerSettings playerSettings;
  2178.             if (!storedData.Players.TryGetValue(player.UserIDString, out playerSettings))
  2179.                 storedData.Players[player.UserIDString] = playerSettings = new PlayerSettings(player);
  2180.             playerSettings.SetSetting(Key, Value);
  2181.         }
  2182.  
  2183.         public void ChangePlayerPanelSettings(BasePlayer player, string Panel, string Key, string Value)
  2184.         {
  2185.             PlayerSettings playerSettings;
  2186.             if (!storedData.Players.TryGetValue(player.UserIDString, out playerSettings))
  2187.                 storedData.Players[player.UserIDString] = playerSettings = new PlayerSettings(player);
  2188.             playerSettings.SetPanelSetting(Panel, Key, Value);
  2189.         }
  2190.  
  2191.  
  2192.         #endregion
  2193.  
  2194.         public List<string> Err = new List<string>();
  2195.         public Dictionary<string, List<string>> ErrA = new Dictionary<string,List<string>>();
  2196.         public Dictionary<string, int> ErrB = new Dictionary<string, int>();
  2197.         public Dictionary<string,int> ErrD = new Dictionary<string,int>();
  2198.  
  2199.         #region IPanelClass
  2200.         [JsonObject(MemberSerialization.OptIn)]
  2201.         public class IPanel
  2202.         {
  2203.             #region Class Variables
  2204.  
  2205.             [JsonProperty("name")]
  2206.             public string Name { get; set; }
  2207.  
  2208.             [JsonProperty("parent")]
  2209.             public string ParentName { get; set; } = "Hud";
  2210.  
  2211.             [JsonProperty("components")]
  2212.             public List<ICuiComponent> Components = new List<ICuiComponent>();
  2213.  
  2214.             [JsonProperty("fadeOut")]
  2215.             public float FadeOut { get; set; }
  2216.  
  2217.             //Left-Right
  2218.             public Vector2 HorizontalPosition { get; set; } = new Vector2(0f, 1f);
  2219.  
  2220.             //Bottom-Top
  2221.             public Vector2 VerticalPosition { get; set; } = new Vector2(0f, 1f);
  2222.  
  2223.             public string AnchorX { get; set; } = "Left";
  2224.  
  2225.             public string AnchorY { get; set; } = "Bottom";
  2226.  
  2227.             public Vector4 Padding = Vector4.zero;
  2228.             public Vector4 Margin { get; set; } = Vector4.zero;
  2229.  
  2230.             public float Width { get; set; } = 1f;
  2231.  
  2232.             public float Height { get; set; } = 1f;
  2233.  
  2234.             public Color _BGColor = Color.black;
  2235.             public Color BackgroundColor
  2236.             {
  2237.                 get
  2238.                 {
  2239.                     return _BGColor;
  2240.                 }
  2241.                 set
  2242.                 {
  2243.                     _BGColor = value;
  2244.  
  2245.                     if (ImageComponent == null)
  2246.                     {
  2247.                         ImageComponent = new CuiImageComponent();
  2248.                         Components.Insert(0, ImageComponent);
  2249.                     }
  2250.  
  2251.                     ImageComponent.Color = $"{value.r} {value.g} {value.b} {value.a}";
  2252.                 }
  2253.             }
  2254.  
  2255.             public int Order = 0;
  2256.  
  2257.             public float _VerticalOffset = 0f;
  2258.             public float VerticalOffset
  2259.             {
  2260.                 get
  2261.                 {
  2262.                     return _VerticalOffset;
  2263.                 }
  2264.  
  2265.                 set
  2266.                 {
  2267.                     _VerticalOffset = value;
  2268.                     SetVerticalPosition();
  2269.                 }
  2270.             }
  2271.  
  2272.             //public Dictionary<string, IPanel> Childs = new Dictionary<string, IPanel>();
  2273.             public List<string> Childs = new List<string>();
  2274.  
  2275.             //Components
  2276.             public CuiRectTransformComponent RecTransform;
  2277.             public CuiImageComponent ImageComponent;
  2278.  
  2279.             //public bool ChildsChanged = false;
  2280.  
  2281.             BasePlayer Owner = null;
  2282.  
  2283.             public string DockName = null;
  2284.  
  2285.             public bool IsActive = false;
  2286.             public bool IsHidden = false;
  2287.  
  2288.             public bool IsPanel = false;
  2289.             public bool IsDock = false;
  2290.  
  2291.             public bool Autoload = true;
  2292.             private Dictionary<string, Dictionary<string, IPanel>> playerPanels;
  2293.             private Dictionary<string, Dictionary<string, IPanel>> playerDockPanels;
  2294.             #endregion
  2295.  
  2296.             public IPanel(string name, BasePlayer Player, Dictionary<string, Dictionary<string, IPanel>> playerPanels, Dictionary<string, Dictionary<string, IPanel>> playerDockPanels)
  2297.             {
  2298.  
  2299.                 Name = name;
  2300.                 Owner = Player;
  2301.                 this.playerPanels = playerPanels;
  2302.                 this.playerDockPanels = playerDockPanels;
  2303.  
  2304.                 //LoadedPanels.Add(this._Name, this);
  2305.  
  2306.                 Dictionary<string, IPanel> playerPanel;
  2307.                 if (!playerPanels.TryGetValue(Player.UserIDString, out playerPanel))
  2308.                     playerPanels.Add(Player.UserIDString, playerPanel = new Dictionary<string, IPanel>());
  2309.                 playerPanel.Add(name, this);
  2310.  
  2311.                 RecTransform = new CuiRectTransformComponent();
  2312.                 Components.Add(RecTransform);
  2313.             }
  2314.  
  2315.             public void SetAnchorXY(string Horizontal, string Vertical)
  2316.             {
  2317.                 AnchorX = Horizontal;
  2318.                 AnchorY = Vertical;
  2319.             }
  2320.  
  2321.             #region Positioning
  2322.  
  2323.             //x,y,z,w
  2324.             public void SetHorizontalPosition()
  2325.             {
  2326.                 float Left;
  2327.                 float Right;
  2328.                 var Offset = GetOffset();
  2329.  
  2330.                 if (AnchorX == "Right")
  2331.                 {
  2332.                     Right = 1f - Margin.w;
  2333.                     Left = Right - Width;
  2334.  
  2335.                     HorizontalPosition = new Vector2(Left, Right) - new Vector2(Offset , Offset);
  2336.                 }
  2337.                 else
  2338.                 {
  2339.                     Left = 0f + Margin.y;
  2340.                     Right = Left + Width;
  2341.  
  2342.                     HorizontalPosition = new Vector2(Left, Right) + new Vector2(Offset, Offset);
  2343.                 }
  2344.  
  2345.                 RecTransform.AnchorMin = $"{HorizontalPosition.x} {VerticalPosition.x}";
  2346.                 RecTransform.AnchorMax = $"{HorizontalPosition.y} {VerticalPosition.y}";
  2347.             }
  2348.  
  2349.             public void SetVerticalPosition()
  2350.             {
  2351.                 float Top;
  2352.                 float Bottom;
  2353.  
  2354.                 if (AnchorY == "Top")
  2355.                 {
  2356.                     Top = 1f - Margin.x;
  2357.                     Bottom = Top - Height;
  2358.                     VerticalPosition = new Vector2(Bottom, Top) + new Vector2(_VerticalOffset, _VerticalOffset);
  2359.                 }
  2360.                 else
  2361.                 {
  2362.                     Bottom = 0f + Margin.z;
  2363.                     Top = Bottom + Height;
  2364.  
  2365.                     VerticalPosition = new Vector2(Bottom, Top) + new Vector2(_VerticalOffset, _VerticalOffset);
  2366.                 }
  2367.  
  2368.                 RecTransform.AnchorMin = $"{HorizontalPosition.x} {VerticalPosition.x}";
  2369.                 RecTransform.AnchorMax = $"{HorizontalPosition.y} {VerticalPosition.y}";
  2370.             }
  2371.  
  2372.             float FullWidth()
  2373.             {
  2374.                 return Width + Margin.y + Margin.w;
  2375.             }
  2376.  
  2377.             float GetSiblingsFullWidth()
  2378.             {
  2379.                 return 1f;
  2380.             }
  2381.             #endregion
  2382.  
  2383.             #region Json
  2384.             public string ToJson()
  2385.             {
  2386.                 SetHorizontalPosition();
  2387.                 SetVerticalPosition();
  2388.  
  2389.                 return JsonConvert.SerializeObject(
  2390.                     this,
  2391.                     new JsonSerializerSettings
  2392.                     {
  2393.                         NullValueHandling = NullValueHandling.Ignore,
  2394.                         DefaultValueHandling = DefaultValueHandling.Ignore
  2395.                     }
  2396.                 );
  2397.             }
  2398.  
  2399.  
  2400.             public float GetOffset()
  2401.             {
  2402.                 var Offset = 0f;
  2403.  
  2404.                 var Parent = GetPanel(ParentName);
  2405.  
  2406.                 if (Parent == null)
  2407.                     return Offset;
  2408.  
  2409.                 var Siblings = Parent.GetChilds().Where(c => c.Value.AnchorX == AnchorX && c.Value.Order <= Order && c.Value.IsActive && c.Value.Name != Name).Select(c => c.Value).OrderBy(s => s.Order);
  2410.  
  2411.                 foreach (var Sibling in Siblings)
  2412.                     Offset += Sibling.Width + Sibling.Margin.y + Sibling.Margin.w;
  2413.  
  2414.                 return Offset;
  2415.             }
  2416.  
  2417.             public string GetJson(bool Brackets = true)
  2418.             {
  2419.                 var Panel = ToJson();
  2420.                 return Brackets ? $"[{Panel}]" : Panel;
  2421.             }
  2422.  
  2423.             #endregion
  2424.  
  2425.             #region Childs
  2426.  
  2427.             public int GetLastChild()
  2428.             {
  2429.                 if (Childs.Count == 0)
  2430.                 {
  2431.                     return 0;
  2432.                 }
  2433.                 else
  2434.                 {
  2435.                     return GetChilds().Max(p => p.Value.Order);
  2436.                 }
  2437.             }
  2438.  
  2439.             public IPanelText AddText(string Name)
  2440.             {
  2441.                 var Text = new IPanelText(Name, Owner, playerPanels, playerDockPanels) {ParentName = this.Name};
  2442.                 Childs.Add(Name);
  2443.                 return Text;
  2444.             }
  2445.  
  2446.             public IPanelRawImage AddImage(string Name)
  2447.             {
  2448.                 var Image = new IPanelRawImage(Name, Owner, playerPanels, playerDockPanels) {ParentName = this.Name};
  2449.                 Childs.Add(Name);
  2450.                 return Image;
  2451.             }
  2452.  
  2453.             public IPanel AddPanel(string Name)
  2454.             {
  2455.                 var Panel = new IPanel(Name, Owner, playerPanels, playerDockPanels) {ParentName = this.Name};
  2456.                 Childs.Add(Name);
  2457.                 return Panel;
  2458.             }
  2459.  
  2460.             #endregion
  2461.  
  2462.             #region Selectors
  2463.  
  2464.             List<string> GetActiveAfterThis()
  2465.             {
  2466.                 var Panels = playerPanels[Owner.UserIDString]
  2467.                     .Where(p => p.Value.IsActive && p.Value.Order > Order && p.Value.ParentName == ParentName && p.Value.AnchorX == AnchorX)
  2468.                     .OrderBy(s => s.Value.Order)
  2469.                     .Select(k => k.Key)
  2470.                     .ToList();
  2471.  
  2472.                 return Panels;
  2473.             }
  2474.  
  2475.             public Dictionary<string, IPanel> GetChilds()
  2476.             {
  2477.                 return playerPanels[Owner.UserIDString].Where(x => Childs.Contains(x.Key)).ToDictionary(se => se.Key, se => se.Value);
  2478.             }
  2479.  
  2480.             public IPanel GetParent()
  2481.             {
  2482.                 return GetPanel(ParentName);
  2483.             }
  2484.  
  2485.             public List<IPanel> GetSiblings()
  2486.             {
  2487.                 return GetPanel(ParentName)?.GetChilds().Where(c => c.Value.AnchorX == AnchorX && c.Value.Name != Name).Select(c => c.Value).OrderBy(s => s.Order).ToList() ?? new List<IPanel>();
  2488.             }
  2489.  
  2490.             public IPanel GetPanel(string PName)
  2491.             {
  2492.                 Dictionary<string, IPanel> panels;
  2493.                 IPanel panel;
  2494.                 if (playerPanels.TryGetValue(Owner.UserIDString, out panels) && panels.TryGetValue(PName, out panel))
  2495.                     return panel;
  2496.                 return null;
  2497.             }
  2498.  
  2499.             public IPanel GetDock()
  2500.             {
  2501.                 if (DockName == null) return null;
  2502.                 Dictionary<string, IPanel> panels;
  2503.                 IPanel panel;
  2504.                 if (playerDockPanels.TryGetValue(Owner.UserIDString, out panels) && panels.TryGetValue(DockName, out panel))
  2505.                     return panel;
  2506.                 return null;
  2507.             }
  2508.  
  2509.             #endregion
  2510.  
  2511.             #region GUI
  2512.  
  2513.  
  2514.             public void Hide()
  2515.             {
  2516.                 foreach (var Panel in GetChilds().Where(p => p.Value.IsActive))
  2517.                     Panel.Value.Hide();
  2518.  
  2519.                 CuiHelper.DestroyUi(Owner, Name);
  2520.                 //CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo(this.Owner.net.connection), null, "DestroyUI", new Facepunch.ObjectList(this._Name));
  2521.             }
  2522.  
  2523.             public void Reveal()
  2524.             {
  2525.  
  2526.                 //Interface.Oxide.LogInfo(GetJson()); //TODO
  2527.                 CuiHelper.AddUi(Owner, GetJson());
  2528.                 //CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo(this.Owner.net.connection), null, "AddUI", new Facepunch.ObjectList(GetJson()));
  2529.  
  2530.                 IsActive = true;
  2531.                 IsHidden = false;
  2532.  
  2533.                 foreach (var Child in GetChilds().Where(p => p.Value.Autoload || p.Value.IsActive).OrderBy(s => s.Value.Order))
  2534.                     Child.Value.Reveal();
  2535.             }
  2536.  
  2537.             void ReDrawPanels(List<string> PanelsName)
  2538.             {
  2539.                 foreach (var PanelName in PanelsName)
  2540.                     GetPanel(PanelName)?.DestroyPanel(false);
  2541.  
  2542.                 foreach (var PanelName in PanelsName)
  2543.                     GetPanel(PanelName)?.ShowPanel();
  2544.             }
  2545.  
  2546.             public void ShowPanel(bool Childs = true)
  2547.             {
  2548.                 if (storedData.GetPlayerSettings(Owner.UserIDString, "enable", true))
  2549.                 {
  2550.                     var Dock = GetDock();
  2551.                     if (Dock != null && Dock.IsActive == false)
  2552.                         Dock.ShowPanel(false);
  2553.  
  2554.                     var ActivePanelsAfterThis = GetActiveAfterThis();
  2555.  
  2556.                     foreach (var PanelName in ActivePanelsAfterThis)
  2557.                         GetPanel(PanelName)?.DestroyPanel(false);
  2558.  
  2559.                     //ErrB.Add(this.Name + ErrB.Count,ActivePanelsAfterThis.Count);
  2560.  
  2561.                     if (storedData.GetPlayerSettings(Owner.UserIDString, "enable", true))
  2562.                     {
  2563.                         //Interface.Oxide.LogInfo(GetJson()); //TODO
  2564.                         CuiHelper.AddUi(Owner, GetJson());
  2565.                         //CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo(this.Owner.net.connection), null, "AddUI", new Facepunch.ObjectList(GetJson()));
  2566.                     }
  2567.  
  2568.                     IsActive = true;
  2569.                     IsHidden = false;
  2570.  
  2571.                     if(Childs)
  2572.                     {
  2573.                         foreach (var Child in GetChilds().Where(p => p.Value.Autoload || p.Value.IsActive).OrderBy(s => s.Value.Order))
  2574.                             Child.Value.ShowPanel();
  2575.                     }
  2576.  
  2577.                     foreach (var PanelName in ActivePanelsAfterThis)
  2578.                         GetPanel(PanelName)?.ShowPanel();
  2579.                 }
  2580.                 else
  2581.                 {
  2582.                     ShowPanelIfHidden();
  2583.                 }
  2584.             }
  2585.  
  2586.             void ShowPanelIfHidden(bool Childs = true)
  2587.             {
  2588.                 IsActive = true;
  2589.                 IsHidden = true;
  2590.                 if (Childs)
  2591.                 {
  2592.                     foreach (var Child in GetChilds().Where(p => p.Value.Autoload || p.Value.IsActive).OrderBy(s => s.Value.Order))
  2593.                         Child.Value.ShowPanel();
  2594.                 }
  2595.             }
  2596.  
  2597.  
  2598.             public void DestroyPanel( bool Redraw = true)
  2599.             {
  2600.                 foreach (var Panel in GetChilds().Where(p => p.Value.IsActive))
  2601.                     Panel.Value.DestroyPanel(false);
  2602.  
  2603.                 CuiHelper.DestroyUi(Owner, Name);
  2604.                 //CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo(this.Owner.net.connection), null, "DestroyUI", new Facepunch.ObjectList(this._Name));
  2605.  
  2606.                 IsActive = false;
  2607.  
  2608.                 if (Redraw)
  2609.                     ReDrawPanels(GetActiveAfterThis());
  2610.  
  2611.                 var Dock = GetDock();
  2612.                 if(Dock?.GetChilds().Count(p => p.Value.IsActive) == 0) Dock.DestroyPanel();
  2613.             }
  2614.  
  2615.  
  2616.             public virtual void Refresh()
  2617.             {
  2618.                 DestroyPanel();
  2619.                 ShowPanel();
  2620.             }
  2621.  
  2622.             #endregion
  2623.  
  2624.             #region Util
  2625.  
  2626.             public void Remover()
  2627.             {
  2628.                 foreach (var Child in GetChilds())
  2629.                     Child.Value.Remover();
  2630.  
  2631.                 GetPanel(ParentName).Childs.Remove(Name);
  2632.                 playerPanels[Owner.UserIDString].Remove(Name);
  2633.             }
  2634.  
  2635.             protected string ColorToString(Color color)
  2636.             {
  2637.                 return $"{color.r} {color.g} {color.b} {color.a}";
  2638.             }
  2639.  
  2640.             #endregion
  2641.         }
  2642.  
  2643.         public class IPanelText : IPanel
  2644.         {
  2645.             public string Content
  2646.             {
  2647.                 get
  2648.                 {
  2649.                     return TextComponent.Text;
  2650.                 }
  2651.                 set
  2652.                 {
  2653.                     TextComponent.Text = value;
  2654.                 }
  2655.             }
  2656.             public TextAnchor Align
  2657.             {
  2658.                 get
  2659.                 {
  2660.                     return TextComponent.Align;
  2661.                 }
  2662.  
  2663.                 set
  2664.                 {
  2665.                     TextComponent.Align = value;
  2666.                 }
  2667.             }
  2668.             public int FontSize {
  2669.                 get
  2670.                 {
  2671.                     return TextComponent.FontSize;
  2672.                 }
  2673.                 set
  2674.                 {
  2675.                     TextComponent.FontSize = value;
  2676.                 }
  2677.             }
  2678.             public Color _FontColor = Color.white;
  2679.             public Color FontColor
  2680.             {
  2681.                 get
  2682.                 {
  2683.                     return _FontColor;
  2684.                 }
  2685.                 set
  2686.                 {
  2687.                     _FontColor = value;
  2688.                     TextComponent.Color = $"{value.r} {value.g} {value.b} {value.a}";
  2689.                 }
  2690.             }
  2691.  
  2692.             public CuiTextComponent TextComponent;
  2693.  
  2694.             public IPanelText(string Name, BasePlayer Player, Dictionary<string, Dictionary<string, IPanel>> playerPanels, Dictionary<string, Dictionary<string, IPanel>> playerDockPanels) : base(Name, Player, playerPanels, playerDockPanels)
  2695.             {
  2696.                 TextComponent = new CuiTextComponent();
  2697.                 Components.Insert(0, TextComponent);
  2698.             }
  2699.  
  2700.             public void RefreshText(BasePlayer player, string text)
  2701.             {
  2702.                 DestroyPanel();
  2703.                 Content = text;
  2704.                 ShowPanel();
  2705.             }
  2706.         }
  2707.  
  2708.         public class IPanelRawImage : IPanel
  2709.         {
  2710.             public string Url
  2711.             {
  2712.                 get
  2713.                 {
  2714.                     return RawImageComponent.Url;
  2715.                 }
  2716.                 set
  2717.                 {
  2718.                     RawImageComponent.Url = value;
  2719.                 }
  2720.             }
  2721.  
  2722.             public Color _Color;
  2723.             public Color Color
  2724.             {
  2725.                 get
  2726.                 {
  2727.                     return _Color;
  2728.                 }
  2729.                 set
  2730.                 {
  2731.                     _Color = value;
  2732.                     RawImageComponent.Color = ColorToString(value);
  2733.                 }
  2734.             }
  2735.  
  2736.             public CuiRawImageComponent RawImageComponent;
  2737.  
  2738.             public IPanelRawImage(string Name, BasePlayer Player, Dictionary<string, Dictionary<string, IPanel>> playerPanels, Dictionary<string, Dictionary<string, IPanel>> playerDockPanels) : base(Name, Player, playerPanels, playerDockPanels)
  2739.             {
  2740.                 RawImageComponent = new CuiRawImageComponent();
  2741.                 Components.Insert(0, RawImageComponent);
  2742.             }
  2743.         }
  2744.  
  2745.         #endregion
  2746.  
  2747.         #region GUI
  2748.  
  2749.         private void DestroyGUI(BasePlayer player)
  2750.         {
  2751.             foreach (var Dock in PlayerDockPanels[player.UserIDString])
  2752.             {
  2753.                 Dock.Value.DestroyPanel(false);
  2754.             }
  2755.         }
  2756.  
  2757.         void GUITimerInit(BasePlayer player)
  2758.         {
  2759.             if (player == null) return;
  2760.  
  2761.             if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot))
  2762.             {
  2763.                 timer.In(2, () => GUITimerInit(player));
  2764.             }
  2765.             else if (!PlayerDockPanels.ContainsKey(player.UserIDString))
  2766.             {
  2767.                 LoadPanels(player);
  2768.                 InitializeGUI(player);
  2769.  
  2770.                 RefreshOnlinePlayers();
  2771.             }
  2772.         }
  2773.  
  2774.         private void InitializeGUI(BasePlayer player)
  2775.         {
  2776.             if (!storedData.GetPlayerSettings(player.UserIDString, "enable", true))
  2777.                 return;
  2778.  
  2779.             foreach (var Panel in PlayerPanels[player.UserIDString])
  2780.             {
  2781.                 switch (Panel.Key)
  2782.                 {
  2783.                     case "ClockText":
  2784.                         ((IPanelText) Panel.Value).Content = Clock.ShowTime(player.UserIDString, storedData);
  2785.                         break;
  2786.                     case "OPlayersText":
  2787.                         ((IPanelText) Panel.Value).Content = BasePlayer.activePlayerList.Count + "/" + ConVar.Server.maxplayers;
  2788.                         break;
  2789.                     case "SleepersText":
  2790.                         ((IPanelText) Panel.Value).Content = BasePlayer.sleepingPlayerList.Count.ToString();
  2791.                         break;
  2792.                     case "MessageBoxText":
  2793.                         ((IPanelText) Panel.Value).Content = MessageBox.GetMessage();
  2794.                         break;
  2795.                     case "CoordinatesText":
  2796.                         ((IPanelText) Panel.Value).Content = Coord.GetCoord(player.UserIDString);
  2797.                         break;
  2798.                     case "BalanceText":
  2799.                         ((IPanelText) Panel.Value).Content = $"{Bala.GetBalance(player.UserIDString):N}";
  2800.                         break;
  2801.                     case "RadiationImage":
  2802.                         ((IPanelRawImage) Panel.Value).Color = Rad.ImageColor;
  2803.                         break;
  2804.                     case "AirdropEventImage":
  2805.                         ((IPanelRawImage) Panel.Value).Color = Airplane.ImageColor;
  2806.                         break;
  2807.                     case "BradleyEventImage":
  2808.                         ((IPanelRawImage) Panel.Value).Color = Bradley.ImageColor;
  2809.                         break;
  2810.                     case "HelicopterEventImage":
  2811.                         ((IPanelRawImage) Panel.Value).Color = Helicopter.ImageColor;
  2812.                         break;
  2813.                     case "ChinookEventImage":
  2814.                         ((IPanelRawImage)Panel.Value).Color = Chinook.ImageColor;
  2815.                         break;
  2816.                     case "CargoShipEventImage":
  2817.                         ((IPanelRawImage)Panel.Value).Color = Cargoship.ImageColor;
  2818.                         break;
  2819.                     case "CompassText":
  2820.                         ((IPanelText) Panel.Value).Content = CompassObj.GetDirection(player.UserIDString);
  2821.                         break;
  2822.                 }
  2823.             }
  2824.  
  2825.             foreach (var Dock in PlayerDockPanels[player.UserIDString])
  2826.             {
  2827.                 if (Dock.Value.Childs.Count != 0)
  2828.                     Dock.Value.ShowPanel();
  2829.             }
  2830.  
  2831.         }
  2832.  
  2833.         private void RevealGUI(BasePlayer player)
  2834.         {
  2835.             foreach (var Dock in PlayerDockPanels[player.UserIDString])
  2836.             {
  2837.                 if (Dock.Value.Childs.Count != 0)
  2838.                     Dock.Value.ShowPanel();
  2839.             }
  2840.         }
  2841.  
  2842.         private void RefreshOnlinePlayers()
  2843.         {
  2844.             foreach (var panel in PlayerPanels)
  2845.             {
  2846.                 if (Settings.GetPanelSettingsValue("OPlayers", "Available", true) && panel.Value.ContainsKey("OPlayersText"))
  2847.                 {
  2848.                     var panelText = (IPanelText)panel.Value["OPlayersText"];
  2849.                     panelText.Content = $"{BasePlayer.activePlayerList.Count}/{ConVar.Server.maxplayers}";
  2850.                     panelText.Refresh();
  2851.                 }
  2852.             }
  2853.         }
  2854.  
  2855.         private void RefreshSleepers()
  2856.         {
  2857.             foreach (var panel in PlayerPanels)
  2858.             {
  2859.                 if (Settings.GetPanelSettingsValue("Sleepers", "Available", true) && panel.Value.ContainsKey("SleepersText"))
  2860.                 {
  2861.                     var panelText = (IPanelText)panel.Value["SleepersText"];
  2862.                     panelText.Content = BasePlayer.sleepingPlayerList.Count.ToString();
  2863.                     panelText.Refresh();
  2864.                 }
  2865.             }
  2866.         }
  2867.  
  2868.         #endregion
  2869.  
  2870.         #region API
  2871.  
  2872.         private bool PanelRegister(string PluginName,string PanelName, string json)
  2873.         {
  2874.             List<string> loadedPlugin;
  2875.             if (LoadedPluginPanels.TryGetValue(PluginName, out loadedPlugin) && loadedPlugin.Contains(PanelName))
  2876.                 return true;
  2877.  
  2878.             var Cfg = JsonConvert.DeserializeObject<PanelConfig>(json);
  2879.  
  2880.             Dictionary<string, PanelConfig> thirdPartyPanel;
  2881.             if (!Settings.ThirdPartyPanels.TryGetValue(PluginName, out thirdPartyPanel))
  2882.                 Settings.ThirdPartyPanels.Add(PluginName, thirdPartyPanel = new Dictionary<string, PanelConfig>());
  2883.  
  2884.             if (!thirdPartyPanel.ContainsKey(PanelName))
  2885.             {
  2886.                 Cfg.Order = PanelReOrder(Cfg.Dock, Cfg.AnchorX);
  2887.                 thirdPartyPanel.Add(PanelName, Cfg);
  2888.  
  2889.                 Config.WriteObject(Settings, true);
  2890.                 PrintWarning($"New panel added to the config file: {PanelName}");
  2891.             }
  2892.  
  2893.             foreach (var Docks in PlayerDockPanels)
  2894.             {
  2895.                 if (Docks.Value.ContainsKey(Cfg.Dock))
  2896.                     LoadPanel(Docks.Value[Cfg.Dock], PanelName, Cfg);
  2897.             }
  2898.  
  2899.             if (!LoadedPluginPanels.TryGetValue(PluginName, out loadedPlugin))
  2900.                 LoadedPluginPanels.Add(PluginName, loadedPlugin = new List<string>());
  2901.             loadedPlugin.Add(PanelName);
  2902.  
  2903.             return true;
  2904.         }
  2905.  
  2906.         private bool ShowPanel(string PluginName,string PanelName, string PlayerId = null)
  2907.         {
  2908.             if (!Settings.ThirdPartyPanels[PluginName][PanelName].Available)
  2909.                 return false;
  2910.  
  2911.             if (PlayerId != null && PlayerPanels.ContainsKey(PlayerId))
  2912.             {
  2913.                 PlayerPanels[PlayerId][PanelName].ShowPanel();
  2914.                 return true;
  2915.             }
  2916.  
  2917.             foreach (var PlayerID in PlayerPanels.Keys)
  2918.                 PlayerPanels[PlayerID][PanelName].ShowPanel();
  2919.  
  2920.             return true;
  2921.         }
  2922.  
  2923.         private bool HidePanel(string PluginName,string PanelName, string PlayerId = null)
  2924.         {
  2925.             if (!Settings.ThirdPartyPanels[PluginName][PanelName].Available)
  2926.                 return false;
  2927.  
  2928.             if (PlayerId != null && PlayerPanels.ContainsKey(PlayerId))
  2929.             {
  2930.                 PlayerPanels[PlayerId][PanelName].DestroyPanel();
  2931.                 return true;
  2932.             }
  2933.  
  2934.             foreach (var PlayerID in PlayerPanels.Keys)
  2935.                 PlayerPanels[PlayerID][PanelName].DestroyPanel();
  2936.  
  2937.             return true;
  2938.         }
  2939.  
  2940.         private bool RefreshPanel(string PluginName,string PanelName, string PlayerId = null)
  2941.         {
  2942.             if (!Settings.ThirdPartyPanels[PluginName][PanelName].Available)
  2943.                 return false;
  2944.  
  2945.             if (PlayerId != null && PlayerPanels.ContainsKey(PlayerId))
  2946.             {
  2947.                 PlayerPanels[PlayerId][PanelName].DestroyPanel();
  2948.                 PlayerPanels[PlayerId][PanelName].ShowPanel();
  2949.                 return true;
  2950.             }
  2951.  
  2952.             foreach (var PlayerID in PlayerPanels.Keys)
  2953.             {
  2954.                 PlayerPanels[PlayerID][PanelName].DestroyPanel();
  2955.                 PlayerPanels[PlayerID][PanelName].ShowPanel();
  2956.             }
  2957.  
  2958.             return true;
  2959.         }
  2960.  
  2961.         private void SetPanelAttribute(string PluginName,string PanelName, string Attribute, string Value, string PlayerId = null )
  2962.         {
  2963.             if (PlayerId != null && PlayerPanels.ContainsKey(PlayerId))
  2964.             {
  2965.                 var Panel = PlayerPanels[PlayerId][PanelName];
  2966.                 var PropInfo = Panel.GetType().GetProperty(Attribute);
  2967.  
  2968.                 if (PropInfo == null)
  2969.                 {
  2970.                     PrintWarning("Wrong Attribute name: " + Attribute);
  2971.                     return;
  2972.                 }
  2973.  
  2974.                 if (Attribute == "FontColor" || Attribute == "BackgroundColor")
  2975.                 {
  2976.                     PropInfo.SetValue(Panel, ColorEx.Parse(Value), null);
  2977.                 }
  2978.                 else if (Attribute == "Margin")
  2979.                 {
  2980.                     PropInfo.SetValue(Panel, Vector4Parser(Value), null);
  2981.                 }
  2982.                 else
  2983.                 {
  2984.                     var ConvertedValue = Convert.ChangeType(Value, PropInfo.PropertyType);
  2985.  
  2986.                     PropInfo.SetValue(Panel, ConvertedValue, null);
  2987.                 }
  2988.  
  2989.                 return;
  2990.             }
  2991.  
  2992.             foreach (var playerID in PlayerPanels.Keys)
  2993.             {
  2994.                 var Panel = PlayerPanels[playerID][PanelName];
  2995.                 var PropInfo = Panel.GetType().GetProperty(Attribute);
  2996.  
  2997.                 if (PropInfo == null)
  2998.                 {
  2999.                     PrintWarning("Wrong Attribute name: " + Attribute);
  3000.                     return;
  3001.                 }
  3002.  
  3003.                 if (Attribute == "FontColor" || Attribute == "BackgroundColor")
  3004.                 {
  3005.                     PropInfo.SetValue(Panel, ColorEx.Parse(Value), null);
  3006.                 }
  3007.                 else if (Attribute == "Margin")
  3008.                 {
  3009.                     PropInfo.SetValue(Panel, Vector4Parser(Value), null);
  3010.                 }
  3011.                 else
  3012.                 {
  3013.                     var ConvertedValue = Convert.ChangeType(Value, PropInfo.PropertyType);
  3014.  
  3015.                     PropInfo.SetValue(Panel, ConvertedValue, null);
  3016.                 }
  3017.             }
  3018.         }
  3019.  
  3020.         private bool SendPanelInfo(string PluginName, List<string> Panels)
  3021.         {
  3022.             Dictionary<string, PanelConfig> panelConfig;
  3023.             if(!Settings.ThirdPartyPanels.TryGetValue(PluginName, out panelConfig))
  3024.             {
  3025.                 return false;
  3026.             }
  3027.  
  3028.             var Removable =panelConfig.Keys.Except(Panels).ToList();
  3029.  
  3030.             foreach(var item in Removable)
  3031.             {
  3032.                 panelConfig.Remove(item);
  3033.             }
  3034.  
  3035.             if(Removable.Count > 0)
  3036.             {
  3037.                 Config.WriteObject(Settings, true);
  3038.                 PrintWarning($"Config File refreshed! {Removable.Count} panel removed!");
  3039.             }
  3040.  
  3041.             return true;
  3042.         }
  3043.  
  3044.         private bool IsPlayerGUILoaded(string PlayerId)
  3045.         {
  3046.             return PlayerPanels.ContainsKey(PlayerId);
  3047.         }
  3048.  
  3049.         #endregion
  3050.  
  3051.         #region Utility
  3052.         internal static Vector4 Vector4Parser(string p)
  3053.         {
  3054.             var strArrays = p.Split(' ');
  3055.             if (strArrays.Length != 4)
  3056.                 return Vector4.zero;
  3057.             return new Vector4(float.Parse(strArrays[0]), float.Parse(strArrays[1]), float.Parse(strArrays[2]), float.Parse(strArrays[3]));
  3058.         }
  3059.         #endregion
  3060.     }
  3061. }
Add Comment
Please, Sign In to add comment