· 5 years ago · Jul 17, 2020, 02:12 PM
1using System;
2using System.Collections.Generic;
3using System.Globalization;
4using System.Linq;
5using Newtonsoft.Json;
6using Newtonsoft.Json.Converters;
7using Oxide.Core;
8using Oxide.Core.Plugins;
9using Oxide.Game.Rust;
10using Oxide.Game.Rust.Cui;
11using UnityEngine;
12
13namespace 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}