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