AMain.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. using System.Diagnostics;
  2. using System.Net;
  3. using Client;
  4. using Microsoft.Web.WebView2.Core;
  5. using System.Net.Http.Headers;
  6. using System.Net.Http.Handlers;
  7. using Client.Utils;
  8. namespace Launcher
  9. {
  10. public partial class AMain : Form
  11. {
  12. long _totalBytes, _completedBytes;
  13. private int _fileCount, _currentCount;
  14. public bool Completed, Checked, CleanFiles, LabelSwitch, ErrorFound;
  15. public List<FileInformation> OldList;
  16. public Queue<FileInformation> DownloadList = new Queue<FileInformation>();
  17. public List<Download> ActiveDownloads = new List<Download>();
  18. private Stopwatch _stopwatch = Stopwatch.StartNew();
  19. public Thread _workThread;
  20. private bool dragging = false;
  21. private Point dragCursorPoint;
  22. private Point dragFormPoint;
  23. private Config ConfigForm = new Config();
  24. private bool Restart = false;
  25. public AMain()
  26. {
  27. InitializeComponent();
  28. BackColor = Color.FromArgb(1, 0, 0);
  29. TransparencyKey = Color.FromArgb(1, 0, 0);
  30. }
  31. public static void SaveError(string ex)
  32. {
  33. try
  34. {
  35. if (Settings.RemainingErrorLogs-- > 0)
  36. {
  37. File.AppendAllText(@".\Error.txt",
  38. string.Format("[{0}] {1}{2}", DateTime.Now, ex, Environment.NewLine));
  39. }
  40. }
  41. catch
  42. {
  43. }
  44. }
  45. public void Start()
  46. {
  47. try
  48. {
  49. GetOldFileList();
  50. if (OldList.Count == 0)
  51. {
  52. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.PatchErr));
  53. Completed = true;
  54. return;
  55. }
  56. _fileCount = OldList.Count;
  57. for (int i = 0; i < OldList.Count; i++)
  58. CheckFile(OldList[i]);
  59. Checked = true;
  60. _fileCount = 0;
  61. _currentCount = 0;
  62. _fileCount = DownloadList.Count;
  63. ServicePointManager.DefaultConnectionLimit = Settings.P_Concurrency;
  64. _stopwatch = Stopwatch.StartNew();
  65. for (var i = 0; i < Settings.P_Concurrency; i++)
  66. BeginDownload();
  67. }
  68. catch (EndOfStreamException ex)
  69. {
  70. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.EndStreamOldVersion));
  71. Completed = true;
  72. SaveError(ex.ToString());
  73. }
  74. catch (Exception ex)
  75. {
  76. MessageBox.Show(ex.ToString(), "Error");
  77. Completed = true;
  78. SaveError(ex.ToString());
  79. }
  80. _stopwatch.Stop();
  81. }
  82. private void BeginDownload()
  83. {
  84. if (DownloadList.Count == 0)
  85. {
  86. Completed = true;
  87. CleanUp();
  88. return;
  89. }
  90. var download = new Download();
  91. download.Info = DownloadList.Dequeue();
  92. DownloadFile(download);
  93. }
  94. private void CleanUp()
  95. {
  96. if (!CleanFiles) return;
  97. string[] fileNames = Directory.GetFiles(@".\", "*.*", SearchOption.AllDirectories);
  98. string fileName;
  99. for (int i = 0; i < fileNames.Length; i++)
  100. {
  101. if (fileNames[i].StartsWith(".\\Screenshots\\")) continue;
  102. fileName = Path.GetFileName(fileNames[i]);
  103. if (fileName == "Mir2Config.ini" || fileName == System.AppDomain.CurrentDomain.FriendlyName) continue;
  104. try
  105. {
  106. if (!NeedFile(fileNames[i]))
  107. File.Delete(fileNames[i]);
  108. }
  109. catch { }
  110. }
  111. }
  112. public bool NeedFile(string fileName)
  113. {
  114. for (int i = 0; i < OldList.Count; i++)
  115. {
  116. if (fileName.EndsWith(OldList[i].FileName))
  117. return true;
  118. }
  119. return false;
  120. }
  121. private void GetOldFileList()
  122. {
  123. OldList = new List<FileInformation>();
  124. byte[] data = Download(Settings.P_PatchFileName);
  125. if (data != null)
  126. {
  127. using MemoryStream stream = new MemoryStream(data);
  128. using BinaryReader reader = new BinaryReader(stream);
  129. if (reader.ReadByte() == 60)
  130. {
  131. //assume we got a html page back with an error code so it's not a patchlist
  132. return;
  133. }
  134. reader.BaseStream.Seek(0,SeekOrigin.Begin);
  135. int count = reader.ReadInt32();
  136. for (int i = 0; i < count; i++)
  137. {
  138. OldList.Add(new FileInformation(reader));
  139. }
  140. }
  141. }
  142. public void ParseOld(BinaryReader reader)
  143. {
  144. int count = reader.ReadInt32();
  145. for (int i = 0; i < count; i++)
  146. OldList.Add(new FileInformation(reader));
  147. }
  148. public void CheckFile(FileInformation old)
  149. {
  150. FileInformation info = GetFileInformation(Settings.P_Client + old.FileName);
  151. _currentCount++;
  152. if (info == null || old.Length != info.Length || old.Creation != info.Creation)
  153. {
  154. DownloadList.Enqueue(old);
  155. _totalBytes += old.Length;
  156. }
  157. }
  158. private int errorcount = 0;
  159. public void DownloadFile(Download dl)
  160. {
  161. var info = dl.Info;
  162. string fileName = info.FileName.Replace(@"\", "/");
  163. if (fileName != "PList.gz" && (info.Compressed != info.Length || info.Compressed == 0))
  164. {
  165. fileName += ".gz";
  166. }
  167. try
  168. {
  169. HttpClientHandler httpClientHandler = new() { AllowAutoRedirect = true };
  170. ProgressMessageHandler progressMessageHandler = new(httpClientHandler);
  171. progressMessageHandler.HttpReceiveProgress += (_, args) =>
  172. {
  173. dl.CurrentBytes = args.BytesTransferred;
  174. };
  175. using (HttpClient client = new(progressMessageHandler))
  176. {
  177. client.DefaultRequestHeaders.Accept.Clear();
  178. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  179. client.DefaultRequestHeaders.AcceptCharset.Clear();
  180. client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
  181. if (Settings.P_NeedLogin)
  182. {
  183. string authInfo = Settings.P_Login + ":" + Settings.P_Password;
  184. authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
  185. client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);
  186. }
  187. ActiveDownloads.Add(dl);
  188. var task = Task.Run(() => client.GetAsync(new Uri($"{Settings.P_Host}{fileName}"), HttpCompletionOption.ResponseHeadersRead));
  189. var response = task.Result;
  190. var task2 = Task.Run(() => response.Content.ReadAsByteArrayAsync());
  191. byte[] data = task2.Result;
  192. _currentCount++;
  193. _completedBytes += dl.CurrentBytes;
  194. dl.CurrentBytes = 0;
  195. dl.Completed = true;
  196. if (info.Compressed > 0 && info.Compressed != info.Length)
  197. {
  198. data = Functions.DecompressBytes(data);
  199. }
  200. var fileNameOut = Settings.P_Client + info.FileName;
  201. var dirName = Path.GetDirectoryName(fileNameOut);
  202. if (!Directory.Exists(dirName))
  203. Directory.CreateDirectory(dirName);
  204. //first remove the original file if needed
  205. string[] specialfiles = { ".dll", ".exe", ".pdb" };
  206. if (File.Exists(fileNameOut) && ( specialfiles.Contains( Path.GetExtension(fileNameOut).ToLower() )))
  207. {
  208. string oldFilename = Path.Combine(Path.GetDirectoryName(fileNameOut), ("Old__" + Path.GetFileName(fileNameOut)));
  209. try
  210. {
  211. //if there's another previous backup: delete it first
  212. if (File.Exists(oldFilename))
  213. {
  214. File.Delete(oldFilename);
  215. }
  216. File.Move(fileNameOut, oldFilename);
  217. }
  218. catch (UnauthorizedAccessException ex)
  219. {
  220. SaveError(ex.ToString());
  221. errorcount++;
  222. if (errorcount == 5)
  223. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
  224. if (errorcount < 5)
  225. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + fileNameOut);
  226. }
  227. catch (Exception ex)
  228. {
  229. SaveError(ex.ToString());
  230. errorcount++;
  231. if (errorcount == 5)
  232. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
  233. if (errorcount < 5)
  234. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + fileNameOut);
  235. }
  236. finally
  237. {
  238. //Might cause an infinite loop if it can never gain access
  239. Restart = true;
  240. }
  241. }
  242. File.WriteAllBytes(fileNameOut, data);
  243. File.SetLastWriteTime(fileNameOut, info.Creation);
  244. }
  245. }
  246. catch (HttpRequestException e)
  247. {
  248. File.AppendAllText(@".\Error.txt",
  249. $"[{DateTime.Now}] {info.FileName} could not be downloaded. ({e.Message}) {Environment.NewLine}");
  250. ErrorFound = true;
  251. }
  252. catch (Exception ex)
  253. {
  254. SaveError(ex.ToString());
  255. errorcount++;
  256. if (errorcount == 5)
  257. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
  258. if (errorcount < 5)
  259. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + dl.Info.FileName);
  260. }
  261. finally
  262. {
  263. if (ErrorFound)
  264. {
  265. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.FileDownload_Failure), fileName));
  266. }
  267. }
  268. BeginDownload();
  269. }
  270. public byte[] Download(string fileName)
  271. {
  272. using (HttpClient client = new())
  273. {
  274. client.DefaultRequestHeaders.Accept.Clear();
  275. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  276. client.DefaultRequestHeaders.AcceptCharset.Clear();
  277. client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
  278. if (Settings.P_NeedLogin)
  279. {
  280. string authInfo = Settings.P_Login + ":" + Settings.P_Password;
  281. authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
  282. client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);
  283. }
  284. string uriString = Settings.P_Host + Path.ChangeExtension(fileName, ".gz");
  285. if (Uri.IsWellFormedUriString(uriString, UriKind.Absolute))
  286. {
  287. var task = Task.Run(() => client.GetAsync(new Uri(uriString), HttpCompletionOption.ResponseHeadersRead));
  288. var response = task.Result;
  289. using Stream sm = response.Content.ReadAsStream();
  290. using MemoryStream ms = new();
  291. sm.CopyTo(ms);
  292. byte[] data = ms.ToArray();
  293. return data;
  294. }
  295. else
  296. {
  297. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.LauncherHostSettingFormatError), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.BadHostFormat));
  298. return null;
  299. }
  300. }
  301. }
  302. public FileInformation GetFileInformation(string fileName)
  303. {
  304. if (!File.Exists(fileName)) return null;
  305. FileInfo info = new FileInfo(fileName);
  306. return new FileInformation
  307. {
  308. FileName = fileName.Remove(0, Settings.P_Client.Length),
  309. Length = (int)info.Length,
  310. Creation = info.LastWriteTime
  311. };
  312. }
  313. private void AMain_Load(object sender, EventArgs e)
  314. {
  315. var envir = CoreWebView2Environment.CreateAsync(null, Settings.ResourcePath).Result;
  316. Main_browser.EnsureCoreWebView2Async(envir);
  317. if (Settings.P_BrowserAddress != "")
  318. {
  319. if (Uri.IsWellFormedUriString(Settings.P_BrowserAddress, UriKind.Absolute))
  320. {
  321. Main_browser.NavigationCompleted += Main_browser_NavigationCompleted;
  322. Main_browser.Source = new Uri(Settings.P_BrowserAddress);
  323. }
  324. else
  325. {
  326. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.LauncherBrowserFormatError), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.BadBrowserFormat));
  327. }
  328. }
  329. RepairOldFiles();
  330. Launch_pb.Enabled = false;
  331. ProgressCurrent_pb.Width = 5;
  332. TotalProg_pb.Width = 5;
  333. Version_label.Text = string.Format("Build: {0}.{1}.{2}", Globals.ProductCodename, Settings.UseTestConfig ? "Debug" : "Release", Application.ProductVersion);
  334. if (Settings.P_ServerName != String.Empty)
  335. {
  336. Name_label.Visible = true;
  337. Name_label.Text = Settings.P_ServerName;
  338. }
  339. _workThread = new Thread(Start) { IsBackground = true };
  340. _workThread.Start();
  341. }
  342. private void Main_browser_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
  343. {
  344. if (Main_browser.Source.AbsolutePath != "blank") Main_browser.Visible = true;
  345. }
  346. private void Launch_pb_Click(object sender, EventArgs e)
  347. {
  348. Launch();
  349. }
  350. private void Launch()
  351. {
  352. if (ConfigForm.Visible) ConfigForm.Visible = false;
  353. Program.Launch = true;
  354. Close();
  355. }
  356. private void Close_pb_Click(object sender, EventArgs e)
  357. {
  358. if (ConfigForm.Visible) ConfigForm.Visible = false;
  359. Close();
  360. }
  361. private void Movement_panel_MouseClick(object sender, MouseEventArgs e)
  362. {
  363. if (ConfigForm.Visible) ConfigForm.Visible = false;
  364. dragging = true;
  365. dragCursorPoint = Cursor.Position;
  366. dragFormPoint = this.Location;
  367. }
  368. private void Movement_panel_MouseUp(object sender, MouseEventArgs e)
  369. {
  370. dragging = false;
  371. }
  372. private void Movement_panel_MouseMove(object sender, MouseEventArgs e)
  373. {
  374. if (dragging)
  375. {
  376. Point dif = Point.Subtract(Cursor.Position, new Size(dragCursorPoint));
  377. this.Location = Point.Add(dragFormPoint, new Size(dif));
  378. }
  379. }
  380. private void Launch_pb_MouseEnter(object sender, EventArgs e)
  381. {
  382. Launch_pb.Image = Client.Resources.Images.Launch_Hover;
  383. }
  384. private void Launch_pb_MouseLeave(object sender, EventArgs e)
  385. {
  386. Launch_pb.Image = Client.Resources.Images.Launch_Base1;
  387. }
  388. private void Close_pb_MouseEnter(object sender, EventArgs e)
  389. {
  390. Close_pb.Image = Client.Resources.Images.Cross_Hover;
  391. }
  392. private void Close_pb_MouseLeave(object sender, EventArgs e)
  393. {
  394. Close_pb.Image = Client.Resources.Images.Cross_Base;
  395. }
  396. private void Launch_pb_MouseDown(object sender, MouseEventArgs e)
  397. {
  398. Launch_pb.Image = Client.Resources.Images.Launch_Pressed;
  399. }
  400. private void Launch_pb_MouseUp(object sender, MouseEventArgs e)
  401. {
  402. Launch_pb.Image = Client.Resources.Images.Launch_Base1;
  403. }
  404. private void Close_pb_MouseDown(object sender, MouseEventArgs e)
  405. {
  406. Close_pb.Image = Client.Resources.Images.Cross_Pressed;
  407. }
  408. private void Close_pb_MouseUp(object sender, MouseEventArgs e)
  409. {
  410. Close_pb.Image = Client.Resources.Images.Cross_Base;
  411. }
  412. private void ProgressCurrent_pb_SizeChanged(object sender, EventArgs e)
  413. {
  414. ProgEnd_pb.Location = new Point((ProgressCurrent_pb.Location.X + ProgressCurrent_pb.Width), ProgressCurrent_pb.Location.Y);
  415. if (ProgressCurrent_pb.Width == 0) ProgEnd_pb.Visible = false;
  416. else ProgEnd_pb.Visible = true;
  417. }
  418. private void Config_pb_MouseDown(object sender, MouseEventArgs e)
  419. {
  420. Config_pb.Image = Client.Resources.Images.Config_Pressed;
  421. }
  422. private void Config_pb_MouseEnter(object sender, EventArgs e)
  423. {
  424. Config_pb.Image = Client.Resources.Images.Config_Hover;
  425. }
  426. private void Config_pb_MouseLeave(object sender, EventArgs e)
  427. {
  428. Config_pb.Image = Client.Resources.Images.Config_Base;
  429. }
  430. private void Config_pb_MouseUp(object sender, MouseEventArgs e)
  431. {
  432. Config_pb.Image = Client.Resources.Images.Config_Base;
  433. }
  434. private void Config_pb_Click(object sender, EventArgs e)
  435. {
  436. if (ConfigForm.Visible) ConfigForm.Hide();
  437. else ConfigForm.Show(Program.PForm);
  438. ConfigForm.Location = new Point(Location.X + Config_pb.Location.X - 183, Location.Y + 36);
  439. }
  440. private void TotalProg_pb_SizeChanged(object sender, EventArgs e)
  441. {
  442. ProgTotalEnd_pb.Location = new Point((TotalProg_pb.Location.X + TotalProg_pb.Width), TotalProg_pb.Location.Y);
  443. if (TotalProg_pb.Width == 0) ProgTotalEnd_pb.Visible = false;
  444. else ProgTotalEnd_pb.Visible = true;
  445. }
  446. private void InterfaceTimer_Tick(object sender, EventArgs e)
  447. {
  448. try
  449. {
  450. if (Completed && ActiveDownloads.Count == 0)
  451. {
  452. ActionLabel.Text = "";
  453. CurrentFile_label.Text = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.UpToDate);
  454. SpeedLabel.Text = "";
  455. ProgressCurrent_pb.Width = 550;
  456. TotalProg_pb.Width = 550;
  457. CurrentFile_label.Visible = true;
  458. CurrentPercent_label.Visible = true;
  459. TotalPercent_label.Visible = true;
  460. CurrentPercent_label.Text = "100%";
  461. TotalPercent_label.Text = "100%";
  462. InterfaceTimer.Enabled = false;
  463. Launch_pb.Enabled = true;
  464. if (ErrorFound) MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.FilesDownloadFailed), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.DownloadFailed));
  465. ErrorFound = false;
  466. if (CleanFiles)
  467. {
  468. CleanFiles = false;
  469. MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.YourFilesCleanedUp), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.CleanFiles));
  470. }
  471. if (Restart)
  472. {
  473. Program.Restart = true;
  474. Close();
  475. }
  476. if (Settings.P_AutoStart)
  477. {
  478. Launch();
  479. }
  480. return;
  481. }
  482. var currentBytes = 0L;
  483. FileInformation currentFile = null;
  484. // Remove completed downloads..
  485. for (var i = ActiveDownloads.Count - 1; i >= 0; i--)
  486. {
  487. var dl = ActiveDownloads[i];
  488. if (dl.Completed)
  489. {
  490. ActiveDownloads.RemoveAt(i);
  491. continue;
  492. }
  493. }
  494. for (var i = ActiveDownloads.Count - 1; i >= 0; i--)
  495. {
  496. var dl = ActiveDownloads[i];
  497. if (!dl.Completed)
  498. currentBytes += dl.CurrentBytes;
  499. }
  500. if (Settings.P_Concurrency == 1)
  501. {
  502. // Note: Just mimic old behaviour for now until a better UI is done.
  503. if (ActiveDownloads.Count > 0)
  504. currentFile = ActiveDownloads[0].Info;
  505. }
  506. ActionLabel.Visible = true;
  507. SpeedLabel.Visible = true;
  508. CurrentFile_label.Visible = true;
  509. CurrentPercent_label.Visible = true;
  510. TotalPercent_label.Visible = true;
  511. if (LabelSwitch) ActionLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.FilesRemaining), _fileCount - _currentCount);
  512. else ActionLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.MBRemaining), ((_totalBytes) - (_completedBytes + currentBytes)) / 1024 / 1024);
  513. if (Settings.P_Concurrency > 1)
  514. {
  515. CurrentFile_label.Text = string.Format("<Concurrent> {0}", ActiveDownloads.Count);
  516. SpeedLabel.Text = ToSize(currentBytes / _stopwatch.Elapsed.TotalSeconds);
  517. }
  518. else
  519. {
  520. if (currentFile != null)
  521. {
  522. CurrentFile_label.Text = string.Format("{0}", currentFile.FileName);
  523. SpeedLabel.Text = ToSize(currentBytes / _stopwatch.Elapsed.TotalSeconds);
  524. CurrentPercent_label.Text = ((int)(100 * currentBytes / currentFile.Length)).ToString() + "%";
  525. ProgressCurrent_pb.Width = (int)(5.5 * (100 * currentBytes / currentFile.Length));
  526. }
  527. }
  528. if (!(_completedBytes is 0 && currentBytes is 0 && _totalBytes is 0))
  529. {
  530. TotalProg_pb.Width = (int)(5.5 * (100 * (_completedBytes + currentBytes) / _totalBytes));
  531. TotalPercent_label.Text = ((int)(100 * (_completedBytes + currentBytes) / _totalBytes)).ToString() + "%";
  532. }
  533. }
  534. catch
  535. {
  536. //to-do
  537. }
  538. }
  539. private void AMain_Click(object sender, EventArgs e)
  540. {
  541. if (ConfigForm.Visible) ConfigForm.Visible = false;
  542. }
  543. private void ActionLabel_Click(object sender, EventArgs e)
  544. {
  545. LabelSwitch = !LabelSwitch;
  546. }
  547. private void Credit_label_Click(object sender, EventArgs e)
  548. {
  549. if (Credit_label.Text == "Powered by Crystal M2") Credit_label.Text = "Designed by Breezer";
  550. else Credit_label.Text = "Powered by Crystal M2";
  551. }
  552. private void AMain_FormClosed(object sender, FormClosedEventArgs e)
  553. {
  554. MoveOldFilesToCurrent();
  555. Launch_pb?.Dispose();
  556. Close_pb?.Dispose();
  557. }
  558. private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
  559. private string ToSize(double number, int precision = 2)
  560. {
  561. // unit's number of bytes
  562. const double unit = 1024;
  563. // suffix counter
  564. int i = 0;
  565. // as long as we're bigger than a unit, keep going
  566. while (number > unit)
  567. {
  568. number /= unit;
  569. i++;
  570. }
  571. // apply precision and current suffix
  572. return Math.Round(number, precision) + suffixes[i];
  573. }
  574. private void RepairOldFiles()
  575. {
  576. var files = Directory.GetFiles(Settings.P_Client, "*", SearchOption.AllDirectories).Where(x => Path.GetFileName(x).StartsWith("Old__"));
  577. foreach (var oldFilename in files)
  578. {
  579. if (!File.Exists(oldFilename.Replace("Old__", "")))
  580. {
  581. File.Move(oldFilename, oldFilename.Replace("Old__", ""));
  582. }
  583. else
  584. {
  585. File.Delete(oldFilename);
  586. }
  587. }
  588. }
  589. private void MoveOldFilesToCurrent()
  590. {
  591. var files = Directory.GetFiles(Settings.P_Client, "*", SearchOption.AllDirectories).Where(x => Path.GetFileName(x).StartsWith("Old__"));
  592. foreach (var oldFilename in files)
  593. {
  594. string originalFilename = Path.Combine(Path.GetDirectoryName(oldFilename), (Path.GetFileName(oldFilename).Replace("Old__", "")));
  595. if (!File.Exists(originalFilename) && File.Exists(oldFilename))
  596. File.Move(oldFilename, originalFilename);
  597. }
  598. }
  599. }
  600. }