Program.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. using System;
  2. using System.Diagnostics;
  3. using System.Threading.Tasks;
  4. using DiscordBot;
  5. using RestSharp;
  6. using System.Collections.Generic;
  7. using System.Threading;
  8. using System.Text;
  9. using System.Linq;
  10. using TFABot.Git;
  11. using LibGit2Sharp;
  12. using System.Reflection;
  13. namespace TFABot
  14. {
  15. public class Program
  16. {
  17. static enumRunState RunState = enumRunState.Run;
  18. public enum enumRunState : int
  19. {
  20. Stop=0,
  21. Run=1,
  22. Restart=2,
  23. Update=3,
  24. PreviousVersion=4,
  25. MonoArgs=5,
  26. Error = 100
  27. }
  28. static uint AlarmOffWarningMinutes=30;
  29. static public Dictionary<string,string> SettingsList = new Dictionary<string, string>();
  30. static public Dictionary<string,clsUser> UserList = new Dictionary<string, clsUser>();
  31. static public Dictionary<string,clsNetwork> NetworkList = new Dictionary<string, clsNetwork>();
  32. static public Dictionary<string,clsNode> NodesList = new Dictionary<string, clsNode>();
  33. static public Dictionary<string,clsNodeGroup> NodeGroupList = new Dictionary<string, clsNodeGroup>();
  34. static public Dictionary<string,clsNotificationPolicy> NotificationPolicyList = new Dictionary<string, clsNotificationPolicy>();
  35. static public DateTime AppStarted = DateTime.UtcNow;
  36. static public clsAlarmManager AlarmManager = new clsAlarmManager();
  37. static public ManualResetEvent ApplicationHold = new ManualResetEvent(false);
  38. static public clsSpreadsheet Spreadsheet;
  39. static public clsBotClient Bot;
  40. static public String BotURL {get; private set;}
  41. public enum EnumAlarmState { Off, On, Silent }
  42. static public DateTime AlarmOffTime;
  43. static public uint AlarmOffWarningMultiplier;
  44. static public EnumAlarmState _alarmState = EnumAlarmState.On;
  45. static public EnumAlarmState AlarmState
  46. { get
  47. {
  48. return _alarmState;
  49. }
  50. set
  51. {
  52. if (_alarmState != value)
  53. {
  54. _alarmState = value;
  55. if (value == EnumAlarmState.Off)
  56. {
  57. AlarmOffTime = DateTime.UtcNow;
  58. AlarmOffWarningMultiplier=0;
  59. }
  60. }
  61. }
  62. }
  63. public static int Main(string[] args)
  64. {
  65. AlarmState = EnumAlarmState.On;
  66. try
  67. {
  68. Console.WriteLine($"Git commit: {clsVersion.GitCommitHash}");
  69. if (clsVersion.VersionChangeFlag) Console.WriteLine("NEW VERSION DETECTED");
  70. Console.WriteLine($"ARGS={Environment.CommandLine}");
  71. BotURL = Environment.GetEnvironmentVariable("BOTURL");
  72. if (String.IsNullOrEmpty(BotURL))
  73. {
  74. Console.WriteLine("'BOTURL' Google Spreadsheet URL missing.");
  75. return (int)enumRunState.Error;
  76. }
  77. Console.WriteLine($"URL={BotURL}");
  78. Spreadsheet = new clsSpreadsheet(BotURL);
  79. var log = Spreadsheet.LoadSettings();
  80. Console.WriteLine(log);
  81. String value;
  82. if (SettingsList.TryGetValue("AlarmOffWarningMinutes", out value)) uint.TryParse(value,out AlarmOffWarningMinutes);
  83. String DiscordToken;
  84. if (!SettingsList.TryGetValue("Discord-Token", out DiscordToken))
  85. {
  86. Console.WriteLine("Discord-Token not found");
  87. return (int)enumRunState.Error;
  88. }
  89. Console.WriteLine("Starting monitoring");
  90. const int apiTimeout = 2000;
  91. using (Bot = new clsBotClient(DiscordToken))
  92. {
  93. Bot.RunAsync();
  94. if (log.Contains("rror:")) Bot.SendAlert($"```{log}```");
  95. while (RunState == enumRunState.Run)
  96. {
  97. //Query every node.
  98. foreach (var node in Program.NodesList.Values.Where(x=>x.Monitor))
  99. {
  100. node.GetHeightAsync(apiTimeout);
  101. }
  102. ApplicationHold.WaitOne(apiTimeout); //Wait for the timeout
  103. foreach (var group in NodeGroupList.Values)
  104. {
  105. group.Monitor();
  106. }
  107. foreach(var network in NetworkList.Values)
  108. {
  109. network.CheckStall();
  110. }
  111. if (AlarmState == EnumAlarmState.Off && (DateTime.UtcNow - AlarmOffTime).TotalMinutes > (AlarmOffWarningMinutes*(AlarmOffWarningMultiplier+1)))
  112. {
  113. Bot.Our_BotAlert.SendMessageAsync($"Warning, the Alarm has been off {(DateTime.UtcNow - AlarmOffTime).TotalMinutes:0} minutes. Forget to reset it?");
  114. AlarmOffWarningMultiplier++;
  115. }
  116. AlarmManager.Process();
  117. ApplicationHold.WaitOne(3000);
  118. }
  119. Console.WriteLine($"Exit Code: {RunState} ({(int)RunState})");
  120. switch(RunState)
  121. {
  122. case enumRunState.Update:
  123. Program.Bot.Our_BotAlert.SendMessageAsync("Shutting down to update. Back soon. :grin:").Wait(1000);
  124. break;
  125. case enumRunState.Restart:
  126. Program.Bot.Our_BotAlert.SendMessageAsync("Shutting down to restart. :relieved:").Wait(1000);
  127. break;
  128. case enumRunState.MonoArgs:
  129. Program.Bot.Our_BotAlert.SendMessageAsync("Shutting down to restart in Debug mode. :spy:").Wait(1000);
  130. break;
  131. case enumRunState.Stop:
  132. Program.Bot.Our_BotAlert.SendMessageAsync("Goodbye! :sleeping:").Wait(1000);
  133. break;
  134. }
  135. }
  136. return (int)RunState;
  137. } catch (Exception ex)
  138. {
  139. Console.WriteLine($"ERROR: {ex.Message}");
  140. return (int)enumRunState.Error;
  141. }
  142. }
  143. static public void SendAlert(String message)
  144. {
  145. if (AlarmState == EnumAlarmState.On || AlarmState == EnumAlarmState.Silent)
  146. Bot.Our_BotAlert.SendMessageAsync(message);
  147. }
  148. static public void CallAlert()
  149. {
  150. if (AlarmState == EnumAlarmState.On) clsDialler.CallAlertList();
  151. }
  152. static public void SetRunState(enumRunState runState)
  153. {
  154. RunState = runState;
  155. ApplicationHold.Set();
  156. }
  157. static public String GetNodes()
  158. {
  159. var cd = new clsColumnDisplay();
  160. cd.AppendCol("Node");
  161. cd.AppendCol("Host");
  162. cd.AppendCol("Ver");
  163. cd.AppendCol("Height");
  164. cd.AppendCol("Ave reply");
  165. cd.AppendCharLine('-');
  166. foreach (var group in NodeGroupList)
  167. {
  168. foreach (var node in NodesList.Values.Where(x=>x.Group == group.Key))
  169. {
  170. node.AppendDisplayColumns(ref cd);
  171. cd.NewLine();
  172. }
  173. }
  174. return cd.ToString();
  175. }
  176. }
  177. }