PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Heart.cs

https://github.com/cazzar/MCaznowl-Build
C# | 332 lines | 240 code | 28 blank | 64 comment | 53 complexity | 5d81e10c29fed73a4cbfc8365cbff637 MD5 | raw file
  1. /*
  2. Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCForge)
  3. Dual-licensed under the Educational Community License, Version 2.0 and
  4. the GNU General Public License, Version 3 (the "Licenses"); you may
  5. not use this file except in compliance with the Licenses. You may
  6. obtain a copy of the Licenses at
  7. http://www.opensource.org/licenses/ecl2.php
  8. http://www.gnu.org/licenses/gpl-3.0.html
  9. Unless required by applicable law or agreed to in writing,
  10. software distributed under the Licenses are distributed on an "AS IS"
  11. BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  12. or implied. See the Licenses for the specific language governing
  13. permissions and limitations under the Licenses.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Diagnostics;
  18. using System.Text;
  19. using System.Net;
  20. using System.IO;
  21. using System.Threading;
  22. namespace MCForge
  23. {
  24. public static class Heart
  25. {
  26. //static int _timeout = 60 * 1000;
  27. private static int max_retries = 3;
  28. static string hash = null;
  29. public static string serverURL;
  30. static string DefaultParameters;
  31. //static string players = "";
  32. //static string worlds = "";
  33. //static BackgroundWorker worker;
  34. static Random MCForgeBeatSeed = new Random(Process.GetCurrentProcess().Id);
  35. static StreamWriter beatlogger;
  36. static System.Timers.Timer MinecraftBeatTimer = new System.Timers.Timer(500);
  37. static System.Timers.Timer MCForgeBeatTimer;
  38. static object Lock = new object();
  39. public static void Init()
  40. {
  41. if(Server.logbeat)
  42. {
  43. if(!File.Exists("heartbeat.log"))
  44. {
  45. File.Create("heartbeat.log").Close();
  46. }
  47. }
  48. MCForgeBeatTimer = new System.Timers.Timer(1000 + MCForgeBeatSeed.Next(0, 2500));
  49. DefaultParameters = "port=" + Server.port +
  50. "&max=" + Server.players +
  51. "&name=" + UrlEncode(Server.name) +
  52. "&public=" + Server.pub +
  53. "&version=" + Server.version;
  54. Thread backupThread = new Thread(new ThreadStart(delegate
  55. {
  56. MinecraftBeatTimer.Elapsed += delegate
  57. {
  58. MinecraftBeatTimer.Interval = 50000;
  59. try
  60. {
  61. Pump(new MinecraftBeat());
  62. Pump(new WOMBeat());
  63. }
  64. catch (Exception e) { Server.ErrorLog(e); }
  65. };
  66. MinecraftBeatTimer.Start();
  67. Thread.Sleep(5000);
  68. MCForgeBeatTimer.Elapsed += delegate
  69. {
  70. MCForgeBeatTimer.Interval = 10*60*1000; // 10 minutes
  71. try
  72. {
  73. Pump(new MCForgeBeat());
  74. }
  75. catch (Exception e)
  76. {
  77. Server.ErrorLog(e);
  78. }
  79. };
  80. MCForgeBeatTimer.Start();
  81. }));
  82. backupThread.Start();
  83. }
  84. public static bool Pump(Beat beat)
  85. {
  86. //lock (Lock)
  87. //{
  88. String beattype = beat.GetType().Name;
  89. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(beat.URL));
  90. beat.Parameters = DefaultParameters;
  91. if (beat.Log)
  92. {
  93. beatlogger = new StreamWriter("heartbeat.log", true);
  94. }
  95. int totalTries = 0;
  96. int totalTriesStream = 0;
  97. retry: try
  98. {
  99. totalTries++;
  100. totalTriesStream = 0;
  101. beat.Prepare();
  102. if (beat.GetType() == typeof(MinecraftBeat))
  103. File.WriteAllText("text/heartbeaturl.txt", beat.URL + "?" + beat.Parameters, Encoding.UTF8);
  104. // Set all the request settings
  105. //Server.s.Log(beat.Parameters);
  106. request.Method = "POST";
  107. request.ContentType = "application/x-www-form-urlencoded";
  108. request.UserAgent = "Mozilla/5.0 (compatible; Konqueror/3.5; Windows NT 6.0) KHTML/3.5.6 (like Gecko)";
  109. request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
  110. byte[] formData = Encoding.ASCII.GetBytes(beat.Parameters);
  111. request.ContentLength = formData.Length;
  112. request.Timeout = 15000; // 15 seconds
  113. retryStream: try
  114. {
  115. totalTriesStream++;
  116. using (Stream requestStream = request.GetRequestStream())
  117. {
  118. requestStream.Write(formData, 0, formData.Length);
  119. if (Server.logbeat && beat.Log)
  120. {
  121. BeatLog(beat, beattype + " request sent at " + DateTime.Now.ToString());
  122. }
  123. requestStream.Flush();
  124. requestStream.Close();
  125. }
  126. }
  127. catch (WebException e)
  128. {
  129. //Server.ErrorLog(e);
  130. if (e.Status == WebExceptionStatus.Timeout)
  131. {
  132. if (Server.logbeat && beat.Log)
  133. {
  134. #if DEBUG
  135. Server.s.Log(beattype + " timeout detected at " + DateTime.Now.ToString());
  136. #endif
  137. BeatLog(beat, beattype + " timeout detected at " + DateTime.Now.ToString());
  138. }
  139. if (totalTriesStream < max_retries)
  140. {
  141. goto retryStream;
  142. }
  143. else
  144. {
  145. if (Server.logbeat && beat.Log)
  146. BeatLog(beat, beattype + " timed out " + max_retries + " times. Aborting this request. " + DateTime.Now.ToString());
  147. Server.s.Log(beattype + " timed out " + max_retries + " times. Aborting this request.");
  148. //throw new WebException("Failed during request.GetRequestStream()", e.InnerException, e.Status, e.Response);
  149. beatlogger.Close();
  150. return false;
  151. }
  152. }
  153. else if (Server.logbeat && beat.Log)
  154. {
  155. #if DEBUG
  156. Server.s.Log(beattype + " non-timeout exception detected: " + e.Message);
  157. #endif
  158. BeatLog(beat, beattype + " non-timeout exception detected: " + e.Message);
  159. BeatLog(beat, "Stack Trace: " + e.StackTrace);
  160. }
  161. }
  162. //if (hash == null)
  163. //{
  164. using (WebResponse response = request.GetResponse())
  165. {
  166. using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
  167. {
  168. if (Server.logbeat && beat.Log)
  169. {
  170. #if DEBUG
  171. Server.s.Log(beattype + " response received at " + DateTime.Now.ToString());
  172. #endif
  173. BeatLog(beat, beattype + " response received at " + DateTime.Now.ToString());
  174. }
  175. if (String.IsNullOrEmpty(hash) && response.ContentLength > 0)
  176. {
  177. // Instead of getting a single line, get the whole damn thing and we'll strip stuff out
  178. string line = responseReader.ReadToEnd().Trim();
  179. if (Server.logbeat && beat.Log)
  180. {
  181. BeatLog(beat, "Received: " + line);
  182. }
  183. beat.OnPump(line);
  184. }
  185. else
  186. {
  187. beat.OnPump(String.Empty);
  188. }
  189. }
  190. }
  191. }
  192. catch (WebException e)
  193. {
  194. if (e.Status == WebExceptionStatus.Timeout)
  195. {
  196. if (Server.logbeat && beat.Log)
  197. {
  198. #if DEBUG
  199. Server.s.Log(beattype + " timeout detected at " + DateTime.Now.ToString());
  200. #endif
  201. BeatLog(beat, "Timeout detected at " + DateTime.Now.ToString());
  202. }
  203. Pump(beat);
  204. }
  205. }
  206. catch (Exception)
  207. {
  208. if (Server.logbeat && beat.Log)
  209. {
  210. BeatLog(beat, beattype + " failure #" + totalTries + " at " + DateTime.Now.ToString());
  211. }
  212. if (totalTries < max_retries) goto retry;
  213. if (Server.logbeat && beat.Log)
  214. {
  215. #if DEBUG
  216. Server.s.Log(beattype + " failed " + max_retries + " times. Stopping.");
  217. #endif
  218. BeatLog(beat, "Failed " + max_retries + " times. Stopping.");
  219. beatlogger.Close();
  220. }
  221. return false;
  222. }
  223. finally
  224. {
  225. request.Abort();
  226. }
  227. if (beatlogger != null)
  228. {
  229. beatlogger.Close();
  230. }
  231. //}
  232. return true;
  233. }
  234. public static string UrlEncode(string input)
  235. {
  236. StringBuilder output = new StringBuilder();
  237. for (int i = 0; i < input.Length; i++)
  238. {
  239. if ((input[i] >= '0' && input[i] <= '9') ||
  240. (input[i] >= 'a' && input[i] <= 'z') ||
  241. (input[i] >= 'A' && input[i] <= 'Z') ||
  242. input[i] == '-' || input[i] == '_' || input[i] == '.' || input[i] == '~')
  243. {
  244. output.Append(input[i]);
  245. }
  246. else if (Array.IndexOf<char>(reservedChars, input[i]) != -1)
  247. {
  248. output.Append('%').Append(((int)input[i]).ToString("X"));
  249. }
  250. }
  251. return output.ToString();
  252. }
  253. private static void BeatLog(Beat beat, string text)
  254. {
  255. if (Server.logbeat && beat.Log && beatlogger != null)
  256. {
  257. try
  258. {
  259. beatlogger.WriteLine(text);
  260. }
  261. catch { }
  262. }
  263. }
  264. /* public static Int32 MACToInt()
  265. {
  266. var nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
  267. if (Server.mono)
  268. {
  269. foreach (var nic in nics)
  270. {
  271. if (nic.Name != "l0")
  272. {
  273. nics[0] = nic;
  274. break;
  275. }
  276. }
  277. }
  278. string MAC = nics[0].GetPhysicalAddress().ToString();
  279. Regex regex = new Regex(@"[^0-9a-f]");
  280. MAC = regex.Replace(MAC, "");
  281. Int32 seed = 0;
  282. retry: try
  283. {
  284. seed = Convert.ToInt32(MAC);
  285. }
  286. catch (OverflowException)
  287. {
  288. MAC = MAC.Remove(MAC.Length - 1);
  289. goto retry;
  290. }
  291. catch(FormatException)
  292. {
  293. seed = new Random().Next();
  294. }
  295. return seed;
  296. } */
  297. public static char[] reservedChars = { ' ', '!', '*', '\'', '(', ')', ';', ':', '@', '&',
  298. '=', '+', '$', ',', '/', '?', '%', '#', '[', ']' };
  299. }
  300. public enum BeatType { Minecraft, MCForge }
  301. }