Functions.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. using System.Drawing;
  2. using System.IO.Compression;
  3. using System.Runtime.Serialization.Formatters.Binary;
  4. public static class Functions
  5. {
  6. public static bool CompareBytes(byte[] a, byte[] b)
  7. {
  8. if (a == b) return true;
  9. if (a == null || b == null || a.Length != b.Length) return false;
  10. for (int i = 0; i < a.Length; i++) if (a[i] != b[i]) return false;
  11. return true;
  12. }
  13. public static string ConvertByteSize(double byteCount)
  14. {
  15. string size = "0 Bytes";
  16. if (byteCount >= 1073741824.0)
  17. size = String.Format("{0:##.##}", byteCount / 1073741824.0) + " GB";
  18. else if (byteCount >= 1048576.0)
  19. size = String.Format("{0:##.##}", byteCount / 1048576.0) + " MB";
  20. else if (byteCount >= 1024.0)
  21. size = String.Format("{0:##.##}", byteCount / 1024.0) + " KB";
  22. else if (byteCount > 0 && byteCount < 1024.0)
  23. size = byteCount.ToString() + " Bytes";
  24. return size;
  25. }
  26. public static bool TryParse(string s, out Point temp)
  27. {
  28. temp = Point.Empty;
  29. if (String.IsNullOrWhiteSpace(s)) return false;
  30. string[] data = s.Split(',');
  31. if (data.Length <= 1) return false;
  32. if (!Int32.TryParse(data[0], out int tempX))
  33. return false;
  34. if (!Int32.TryParse(data[1], out int tempY))
  35. return false;
  36. temp = new Point(tempX, tempY);
  37. return true;
  38. }
  39. public static Point Subtract(this Point p1, Point p2)
  40. {
  41. return new Point(p1.X - p2.X, p1.Y - p2.Y);
  42. }
  43. public static Point Subtract(this Point p1, int x, int y)
  44. {
  45. return new Point(p1.X - x, p1.Y - y);
  46. }
  47. public static Point Add(this Point p1, Point p2)
  48. {
  49. return new Point(p1.X + p2.X, p1.Y + p2.Y);
  50. }
  51. public static Point Add(this Point p1, int x, int y)
  52. {
  53. return new Point(p1.X + x, p1.Y + y);
  54. }
  55. public static string PointToString(Point p)
  56. {
  57. return String.Format("{0}, {1}", p.X, p.Y);
  58. }
  59. public static bool InRange(Point a, Point b, int i)
  60. {
  61. return Math.Abs(a.X - b.X) <= i && Math.Abs(a.Y - b.Y) <= i;
  62. }
  63. public static bool FacingEachOther(MirDirection dirA, Point pointA, MirDirection dirB, Point pointB)
  64. {
  65. if (dirA == DirectionFromPoint(pointA, pointB) && dirB == DirectionFromPoint(pointB, pointA))
  66. {
  67. return true;
  68. }
  69. return false;
  70. }
  71. public static string PrintTimeSpanFromSeconds(double secs, bool accurate = true)
  72. {
  73. TimeSpan t = TimeSpan.FromSeconds(secs);
  74. string answer;
  75. if (t.TotalMinutes < 1.0)
  76. {
  77. answer = string.Format("{0}s", t.Seconds);
  78. }
  79. else if (t.TotalHours < 1.0)
  80. {
  81. answer = accurate ? string.Format("{0}m {1:D2}s", t.Minutes, t.Seconds) : string.Format("{0}m", t.Minutes);
  82. }
  83. else if (t.TotalDays < 1.0)
  84. {
  85. answer = accurate ? string.Format("{0}h {1:D2}m {2:D2}s", (int)t.Hours, t.Minutes, t.Seconds) : string.Format("{0}h {1:D2}m", (int)t.TotalHours, t.Minutes);
  86. }
  87. else // more than 1 day
  88. {
  89. answer = accurate ? string.Format("{0}d {1:D2}h {2:D2}m {3:D2}s", (int)t.Days, (int)t.Hours, t.Minutes, t.Seconds) : string.Format("{0}d {1}h {2:D2}m", (int)t.TotalDays, (int)t.Hours, t.Minutes);
  90. }
  91. return answer;
  92. }
  93. public static string PrintTimeSpanFromMilliSeconds(double milliSeconds)
  94. {
  95. TimeSpan t = TimeSpan.FromMilliseconds(milliSeconds);
  96. string answer;
  97. if (t.TotalMinutes < 1.0)
  98. {
  99. answer = string.Format("{0}.{1}s", t.Seconds, (decimal)(t.Milliseconds / 100));
  100. }
  101. else if (t.TotalHours < 1.0)
  102. {
  103. answer = string.Format("{0}m {1:D2}s", t.TotalMinutes, t.Seconds);
  104. }
  105. else if (t.TotalDays < 1.0)
  106. {
  107. answer = string.Format("{0}h {1:D2}m {2:D2}s", (int)t.TotalHours, t.Minutes, t.Seconds);
  108. }
  109. else
  110. {
  111. answer = string.Format("{0}d {1}h {2:D2}m {3:D2}s", (int)t.Days, (int)t.Hours, t.Minutes, t.Seconds);
  112. }
  113. return answer;
  114. }
  115. public static MirDirection PreviousDir(MirDirection d)
  116. {
  117. switch (d)
  118. {
  119. case MirDirection.Up:
  120. return MirDirection.UpLeft;
  121. case MirDirection.UpRight:
  122. return MirDirection.Up;
  123. case MirDirection.Right:
  124. return MirDirection.UpRight;
  125. case MirDirection.DownRight:
  126. return MirDirection.Right;
  127. case MirDirection.Down:
  128. return MirDirection.DownRight;
  129. case MirDirection.DownLeft:
  130. return MirDirection.Down;
  131. case MirDirection.Left:
  132. return MirDirection.DownLeft;
  133. case MirDirection.UpLeft:
  134. return MirDirection.Left;
  135. default: return d;
  136. }
  137. }
  138. public static MirDirection NextDir(MirDirection d)
  139. {
  140. switch (d)
  141. {
  142. case MirDirection.Up:
  143. return MirDirection.UpRight;
  144. case MirDirection.UpRight:
  145. return MirDirection.Right;
  146. case MirDirection.Right:
  147. return MirDirection.DownRight;
  148. case MirDirection.DownRight:
  149. return MirDirection.Down;
  150. case MirDirection.Down:
  151. return MirDirection.DownLeft;
  152. case MirDirection.DownLeft:
  153. return MirDirection.Left;
  154. case MirDirection.Left:
  155. return MirDirection.UpLeft;
  156. case MirDirection.UpLeft:
  157. return MirDirection.Up;
  158. default: return d;
  159. }
  160. }
  161. public static MirDirection DirectionFromPoint(Point source, Point dest)
  162. {
  163. if (source.X < dest.X)
  164. {
  165. if (source.Y < dest.Y)
  166. return MirDirection.DownRight;
  167. if (source.Y > dest.Y)
  168. return MirDirection.UpRight;
  169. return MirDirection.Right;
  170. }
  171. if (source.X > dest.X)
  172. {
  173. if (source.Y < dest.Y)
  174. return MirDirection.DownLeft;
  175. if (source.Y > dest.Y)
  176. return MirDirection.UpLeft;
  177. return MirDirection.Left;
  178. }
  179. return source.Y < dest.Y ? MirDirection.Down : MirDirection.Up;
  180. }
  181. public static MirDirection ShiftDirection(MirDirection dir, int i)
  182. {
  183. return (MirDirection)(((int)dir + i + 8) % 8);
  184. }
  185. public static Size Add(this Size p1, Size p2)
  186. {
  187. return new Size(p1.Width + p2.Width, p1.Height + p2.Height);
  188. }
  189. public static Size Add(this Size p1, int width, int height)
  190. {
  191. return new Size(p1.Width + width, p1.Height + height);
  192. }
  193. public static Point PointMove(Point p, MirDirection d, int i)
  194. {
  195. switch (d)
  196. {
  197. case MirDirection.Up:
  198. p.Offset(0, -i);
  199. break;
  200. case MirDirection.UpRight:
  201. p.Offset(i, -i);
  202. break;
  203. case MirDirection.Right:
  204. p.Offset(i, 0);
  205. break;
  206. case MirDirection.DownRight:
  207. p.Offset(i, i);
  208. break;
  209. case MirDirection.Down:
  210. p.Offset(0, i);
  211. break;
  212. case MirDirection.DownLeft:
  213. p.Offset(-i, i);
  214. break;
  215. case MirDirection.Left:
  216. p.Offset(-i, 0);
  217. break;
  218. case MirDirection.UpLeft:
  219. p.Offset(-i, -i);
  220. break;
  221. }
  222. return p;
  223. }
  224. public static Point Left(Point p, MirDirection d)
  225. {
  226. switch (d)
  227. {
  228. case MirDirection.Up:
  229. p.Offset(-1, 0);
  230. break;
  231. case MirDirection.UpRight:
  232. p.Offset(-1, -1);
  233. break;
  234. case MirDirection.Right:
  235. p.Offset(0, -1);
  236. break;
  237. case MirDirection.DownRight:
  238. p.Offset(1, -1);
  239. break;
  240. case MirDirection.Down:
  241. p.Offset(1, 0);
  242. break;
  243. case MirDirection.DownLeft:
  244. p.Offset(1, 1);
  245. break;
  246. case MirDirection.Left:
  247. p.Offset(0, 1);
  248. break;
  249. case MirDirection.UpLeft:
  250. p.Offset(-1, 1);
  251. break;
  252. }
  253. return p;
  254. }
  255. public static Point Right(Point p, MirDirection d)
  256. {
  257. switch (d)
  258. {
  259. case MirDirection.Up:
  260. p.Offset(1, 0);
  261. break;
  262. case MirDirection.UpRight:
  263. p.Offset(1, 1);
  264. break;
  265. case MirDirection.Right:
  266. p.Offset(0, 1);
  267. break;
  268. case MirDirection.DownRight:
  269. p.Offset(-1, 1);
  270. break;
  271. case MirDirection.Down:
  272. p.Offset(-1, 0);
  273. break;
  274. case MirDirection.DownLeft:
  275. p.Offset(-1, -1);
  276. break;
  277. case MirDirection.Left:
  278. p.Offset(0, -1);
  279. break;
  280. case MirDirection.UpLeft:
  281. p.Offset(1, -1);
  282. break;
  283. }
  284. return p;
  285. }
  286. public static int MaxDistance(Point p1, Point p2)
  287. {
  288. return Math.Max(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
  289. }
  290. public static MirDirection ReverseDirection(MirDirection dir)
  291. {
  292. switch (dir)
  293. {
  294. case MirDirection.Up:
  295. return MirDirection.Down;
  296. case MirDirection.UpRight:
  297. return MirDirection.DownLeft;
  298. case MirDirection.Right:
  299. return MirDirection.Left;
  300. case MirDirection.DownRight:
  301. return MirDirection.UpLeft;
  302. case MirDirection.Down:
  303. return MirDirection.Up;
  304. case MirDirection.DownLeft:
  305. return MirDirection.UpRight;
  306. case MirDirection.Left:
  307. return MirDirection.Right;
  308. case MirDirection.UpLeft:
  309. return MirDirection.DownRight;
  310. default:
  311. return dir;
  312. }
  313. }
  314. public static ItemInfo GetRealItem(ItemInfo Origin, ushort Level, MirClass job, List<ItemInfo> ItemList)
  315. {
  316. if (Origin.ClassBased && Origin.LevelBased)
  317. return GetClassAndLevelBasedItem(Origin, job, Level, ItemList);
  318. if (Origin.ClassBased)
  319. return GetClassBasedItem(Origin, job, ItemList);
  320. if (Origin.LevelBased)
  321. return GetLevelBasedItem(Origin, Level, ItemList);
  322. return Origin;
  323. }
  324. public static ItemInfo GetLevelBasedItem(ItemInfo Origin, ushort level, List<ItemInfo> ItemList)
  325. {
  326. ItemInfo output = Origin;
  327. for (int i = 0; i < ItemList.Count; i++)
  328. {
  329. ItemInfo info = ItemList[i];
  330. if (info.Name.StartsWith(Origin.Name))
  331. if ((info.RequiredType == RequiredType.Level) && (info.RequiredAmount <= level) && (output.RequiredAmount < info.RequiredAmount) && (Origin.RequiredGender == info.RequiredGender))
  332. output = info;
  333. }
  334. return output;
  335. }
  336. public static ItemInfo GetClassBasedItem(ItemInfo Origin, MirClass job, List<ItemInfo> ItemList)
  337. {
  338. for (int i = 0; i < ItemList.Count; i++)
  339. {
  340. ItemInfo info = ItemList[i];
  341. if (info.Name.StartsWith(Origin.Name))
  342. if (((byte)info.RequiredClass == (1 << (byte)job)) && (Origin.RequiredGender == info.RequiredGender))
  343. return info;
  344. }
  345. return Origin;
  346. }
  347. public static ItemInfo GetClassAndLevelBasedItem(ItemInfo Origin, MirClass job, ushort level, List<ItemInfo> ItemList)
  348. {
  349. ItemInfo output = Origin;
  350. for (int i = 0; i < ItemList.Count; i++)
  351. {
  352. ItemInfo info = ItemList[i];
  353. if (info.Name.StartsWith(Origin.Name))
  354. if ((byte)info.RequiredClass == (1 << (byte)job))
  355. if ((info.RequiredType == RequiredType.Level) && (info.RequiredAmount <= level) && (output.RequiredAmount <= info.RequiredAmount) && (Origin.RequiredGender == info.RequiredGender))
  356. output = info;
  357. }
  358. return output;
  359. }
  360. public static string StringOverLines(string line, int maxWordsPerLine, int maxLettersPerLine)
  361. {
  362. string newString = string.Empty;
  363. string[] words = line.Split(' ');
  364. int lineLength = 0;
  365. for (int i = 0; i < words.Length; i++)
  366. {
  367. lineLength += words[i].Length + 1;
  368. newString += words[i] + " ";
  369. if (i > 0 && i % maxWordsPerLine == 0 && lineLength > maxLettersPerLine)
  370. {
  371. lineLength = 0;
  372. newString += "\r\n";
  373. }
  374. }
  375. return newString;
  376. }
  377. public static IEnumerable<byte[]> SplitArray(byte[] value, int bufferLength)
  378. {
  379. int countOfArray = value.Length / bufferLength;
  380. if (value.Length % bufferLength > 0)
  381. countOfArray++;
  382. for (int i = 0; i < countOfArray; i++)
  383. {
  384. yield return value.Skip(i * bufferLength).Take(bufferLength).ToArray();
  385. }
  386. }
  387. public static byte[] CombineArray(List<byte[]> arrays)
  388. {
  389. byte[] rv = new byte[arrays.Sum(x => x.Length)];
  390. int offset = 0;
  391. foreach (byte[] array in arrays)
  392. {
  393. System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
  394. offset += array.Length;
  395. }
  396. return rv;
  397. }
  398. public static byte[] SerializeToBytes<T>(T item)
  399. {
  400. #pragma warning disable SYSLIB0011
  401. var formatter = new BinaryFormatter();
  402. using (var stream = new MemoryStream())
  403. {
  404. formatter.Serialize(stream, item);
  405. stream.Seek(0, SeekOrigin.Begin);
  406. #pragma warning restore SYSLIB0011
  407. return stream.ToArray();
  408. }
  409. }
  410. public static object DeserializeFromBytes(byte[] bytes)
  411. {
  412. #pragma warning disable SYSLIB0011
  413. var formatter = new BinaryFormatter();
  414. using (var stream = new MemoryStream(bytes))
  415. {
  416. var deserialized = formatter.Deserialize(stream);
  417. #pragma warning restore SYSLIB0011
  418. return deserialized;
  419. }
  420. }
  421. /// <summary>
  422. /// Chop a List into chunks
  423. /// </summary>
  424. /// <param name="width">The amount of Chunks desired</param>
  425. /// <param name="originalList">The list to Chop into Chunks</param>
  426. /// <returns>Original List in Chunks within a List</returns>
  427. public static List<List<T>> SplitList<T>(int width, List<T> originalList)
  428. {
  429. var _tempChunks = new List<List<T>>();
  430. if (width == 0)
  431. _tempChunks.Add(originalList);
  432. else
  433. {
  434. // Determine how many lists are required
  435. var numberOfLists = (originalList.Count / width);
  436. for (var i = 0; i <= numberOfLists; i++)
  437. {
  438. var newChunk = originalList.Skip(i * width).Take(width).ToList();
  439. _tempChunks.Add(newChunk);
  440. }
  441. }
  442. return _tempChunks;
  443. }
  444. public static byte[] CompressBytes(byte[] raw)
  445. {
  446. using (var memory = new MemoryStream())
  447. {
  448. using (var gzip = new GZipStream(memory, CompressionMode.Compress, true))
  449. {
  450. gzip.Write(raw, 0, raw.Length);
  451. }
  452. return memory.ToArray();
  453. }
  454. }
  455. public static byte[] DecompressBytes(byte[] gzip)
  456. {
  457. using (var stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
  458. {
  459. using (var memory = new MemoryStream())
  460. {
  461. stream.CopyTo(memory, 4096);
  462. return memory.ToArray();
  463. }
  464. }
  465. }
  466. }