| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- using System.Diagnostics;
- using System.Net;
- using Client;
- using Microsoft.Web.WebView2.Core;
- using System.Net.Http.Headers;
- using System.Net.Http.Handlers;
- using Client.Utils;
- namespace Launcher
- {
- public partial class AMain : Form
- {
- long _totalBytes, _completedBytes;
- private int _fileCount, _currentCount;
- public bool Completed, Checked, CleanFiles, LabelSwitch, ErrorFound;
- public List<FileInformation> OldList;
- public Queue<FileInformation> DownloadList = new Queue<FileInformation>();
- public List<Download> ActiveDownloads = new List<Download>();
- private Stopwatch _stopwatch = Stopwatch.StartNew();
- public Thread _workThread;
- private bool dragging = false;
- private Point dragCursorPoint;
- private Point dragFormPoint;
- private Config ConfigForm = new Config();
- private bool Restart = false;
- public AMain()
- {
- InitializeComponent();
- BackColor = Color.FromArgb(1, 0, 0);
- TransparencyKey = Color.FromArgb(1, 0, 0);
- }
- public static void SaveError(string ex)
- {
- try
- {
- if (Settings.RemainingErrorLogs-- > 0)
- {
- File.AppendAllText(@".\Error.txt",
- string.Format("[{0}] {1}{2}", DateTime.Now, ex, Environment.NewLine));
- }
- }
- catch
- {
- }
- }
- public void Start()
- {
- try
- {
- GetOldFileList();
- if (OldList.Count == 0)
- {
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.PatchErr));
- Completed = true;
- return;
- }
- _fileCount = OldList.Count;
- for (int i = 0; i < OldList.Count; i++)
- CheckFile(OldList[i]);
- Checked = true;
- _fileCount = 0;
- _currentCount = 0;
- _fileCount = DownloadList.Count;
- ServicePointManager.DefaultConnectionLimit = Settings.P_Concurrency;
- _stopwatch = Stopwatch.StartNew();
- for (var i = 0; i < Settings.P_Concurrency; i++)
- BeginDownload();
- }
- catch (EndOfStreamException ex)
- {
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.EndStreamOldVersion));
- Completed = true;
- SaveError(ex.ToString());
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString(), "Error");
- Completed = true;
- SaveError(ex.ToString());
- }
- _stopwatch.Stop();
- }
- private void BeginDownload()
- {
- if (DownloadList.Count == 0)
- {
- Completed = true;
- CleanUp();
- return;
- }
- var download = new Download();
- download.Info = DownloadList.Dequeue();
- DownloadFile(download);
- }
- private void CleanUp()
- {
- if (!CleanFiles) return;
- string[] fileNames = Directory.GetFiles(@".\", "*.*", SearchOption.AllDirectories);
- string fileName;
- for (int i = 0; i < fileNames.Length; i++)
- {
- if (fileNames[i].StartsWith(".\\Screenshots\\")) continue;
- fileName = Path.GetFileName(fileNames[i]);
- if (fileName == "Mir2Config.ini" || fileName == System.AppDomain.CurrentDomain.FriendlyName) continue;
- try
- {
- if (!NeedFile(fileNames[i]))
- File.Delete(fileNames[i]);
- }
- catch { }
- }
- }
- public bool NeedFile(string fileName)
- {
- for (int i = 0; i < OldList.Count; i++)
- {
- if (fileName.EndsWith(OldList[i].FileName))
- return true;
- }
- return false;
- }
- private void GetOldFileList()
- {
- OldList = new List<FileInformation>();
- byte[] data = Download(Settings.P_PatchFileName);
- if (data != null)
- {
- using MemoryStream stream = new MemoryStream(data);
- using BinaryReader reader = new BinaryReader(stream);
- if (reader.ReadByte() == 60)
- {
- //assume we got a html page back with an error code so it's not a patchlist
- return;
- }
- reader.BaseStream.Seek(0,SeekOrigin.Begin);
- int count = reader.ReadInt32();
- for (int i = 0; i < count; i++)
- {
- OldList.Add(new FileInformation(reader));
- }
- }
- }
- public void ParseOld(BinaryReader reader)
- {
- int count = reader.ReadInt32();
- for (int i = 0; i < count; i++)
- OldList.Add(new FileInformation(reader));
- }
- public void CheckFile(FileInformation old)
- {
- FileInformation info = GetFileInformation(Settings.P_Client + old.FileName);
- _currentCount++;
- if (info == null || old.Length != info.Length || old.Creation != info.Creation)
- {
- DownloadList.Enqueue(old);
- _totalBytes += old.Length;
- }
- }
- private int errorcount = 0;
- public void DownloadFile(Download dl)
- {
- var info = dl.Info;
- string fileName = info.FileName.Replace(@"\", "/");
- if (fileName != "PList.gz" && (info.Compressed != info.Length || info.Compressed == 0))
- {
- fileName += ".gz";
- }
- try
- {
- HttpClientHandler httpClientHandler = new() { AllowAutoRedirect = true };
- ProgressMessageHandler progressMessageHandler = new(httpClientHandler);
- progressMessageHandler.HttpReceiveProgress += (_, args) =>
- {
- dl.CurrentBytes = args.BytesTransferred;
- };
- using (HttpClient client = new(progressMessageHandler))
- {
- client.DefaultRequestHeaders.Accept.Clear();
- client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- client.DefaultRequestHeaders.AcceptCharset.Clear();
- client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
- if (Settings.P_NeedLogin)
- {
- string authInfo = Settings.P_Login + ":" + Settings.P_Password;
- authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);
- }
- ActiveDownloads.Add(dl);
- var task = Task.Run(() => client.GetAsync(new Uri($"{Settings.P_Host}{fileName}"), HttpCompletionOption.ResponseHeadersRead));
- var response = task.Result;
- var task2 = Task.Run(() => response.Content.ReadAsByteArrayAsync());
- byte[] data = task2.Result;
- _currentCount++;
- _completedBytes += dl.CurrentBytes;
- dl.CurrentBytes = 0;
- dl.Completed = true;
- if (info.Compressed > 0 && info.Compressed != info.Length)
- {
- data = Functions.DecompressBytes(data);
- }
- var fileNameOut = Settings.P_Client + info.FileName;
- var dirName = Path.GetDirectoryName(fileNameOut);
- if (!Directory.Exists(dirName))
- Directory.CreateDirectory(dirName);
- //first remove the original file if needed
- string[] specialfiles = { ".dll", ".exe", ".pdb" };
- if (File.Exists(fileNameOut) && ( specialfiles.Contains( Path.GetExtension(fileNameOut).ToLower() )))
- {
- string oldFilename = Path.Combine(Path.GetDirectoryName(fileNameOut), ("Old__" + Path.GetFileName(fileNameOut)));
- try
- {
- //if there's another previous backup: delete it first
- if (File.Exists(oldFilename))
- {
- File.Delete(oldFilename);
- }
- File.Move(fileNameOut, oldFilename);
- }
- catch (UnauthorizedAccessException ex)
- {
- SaveError(ex.ToString());
- errorcount++;
- if (errorcount == 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
- if (errorcount < 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + fileNameOut);
- }
- catch (Exception ex)
- {
- SaveError(ex.ToString());
- errorcount++;
- if (errorcount == 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
- if (errorcount < 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + fileNameOut);
- }
- finally
- {
- //Might cause an infinite loop if it can never gain access
- Restart = true;
- }
- }
- File.WriteAllBytes(fileNameOut, data);
- File.SetLastWriteTime(fileNameOut, info.Creation);
- }
- }
- catch (HttpRequestException e)
- {
- File.AppendAllText(@".\Error.txt",
- $"[{DateTime.Now}] {info.FileName} could not be downloaded. ({e.Message}) {Environment.NewLine}");
- ErrorFound = true;
- }
- catch (Exception ex)
- {
- SaveError(ex.ToString());
- errorcount++;
- if (errorcount == 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TooManyErrors));
- if (errorcount < 5)
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ErrorSavingFile) + dl.Info.FileName);
- }
- finally
- {
- if (ErrorFound)
- {
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.FileDownload_Failure), fileName));
- }
- }
- BeginDownload();
- }
- public byte[] Download(string fileName)
- {
- using (HttpClient client = new())
- {
- client.DefaultRequestHeaders.Accept.Clear();
- client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- client.DefaultRequestHeaders.AcceptCharset.Clear();
- client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
- if (Settings.P_NeedLogin)
- {
- string authInfo = Settings.P_Login + ":" + Settings.P_Password;
- authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);
- }
- string uriString = Settings.P_Host + Path.ChangeExtension(fileName, ".gz");
- if (Uri.IsWellFormedUriString(uriString, UriKind.Absolute))
- {
- var task = Task.Run(() => client.GetAsync(new Uri(uriString), HttpCompletionOption.ResponseHeadersRead));
- var response = task.Result;
- using Stream sm = response.Content.ReadAsStream();
- using MemoryStream ms = new();
- sm.CopyTo(ms);
- byte[] data = ms.ToArray();
- return data;
- }
- else
- {
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.LauncherHostSettingFormatError), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.BadHostFormat));
- return null;
- }
- }
- }
- public FileInformation GetFileInformation(string fileName)
- {
- if (!File.Exists(fileName)) return null;
- FileInfo info = new FileInfo(fileName);
- return new FileInformation
- {
- FileName = fileName.Remove(0, Settings.P_Client.Length),
- Length = (int)info.Length,
- Creation = info.LastWriteTime
- };
- }
- private void AMain_Load(object sender, EventArgs e)
- {
- var envir = CoreWebView2Environment.CreateAsync(null, Settings.ResourcePath).Result;
- Main_browser.EnsureCoreWebView2Async(envir);
- if (Settings.P_BrowserAddress != "")
- {
- if (Uri.IsWellFormedUriString(Settings.P_BrowserAddress, UriKind.Absolute))
- {
- Main_browser.NavigationCompleted += Main_browser_NavigationCompleted;
- Main_browser.Source = new Uri(Settings.P_BrowserAddress);
- }
- else
- {
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.LauncherBrowserFormatError), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.BadBrowserFormat));
- }
- }
- RepairOldFiles();
- Launch_pb.Enabled = false;
- ProgressCurrent_pb.Width = 5;
- TotalProg_pb.Width = 5;
- Version_label.Text = string.Format("Build: {0}.{1}.{2}", Globals.ProductCodename, Settings.UseTestConfig ? "Debug" : "Release", Application.ProductVersion);
- if (Settings.P_ServerName != String.Empty)
- {
- Name_label.Visible = true;
- Name_label.Text = Settings.P_ServerName;
- }
- _workThread = new Thread(Start) { IsBackground = true };
- _workThread.Start();
- }
- private void Main_browser_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
- {
- if (Main_browser.Source.AbsolutePath != "blank") Main_browser.Visible = true;
- }
- private void Launch_pb_Click(object sender, EventArgs e)
- {
- Launch();
- }
- private void Launch()
- {
- if (ConfigForm.Visible) ConfigForm.Visible = false;
- Program.Launch = true;
- Close();
- }
- private void Close_pb_Click(object sender, EventArgs e)
- {
- if (ConfigForm.Visible) ConfigForm.Visible = false;
- Close();
- }
- private void Movement_panel_MouseClick(object sender, MouseEventArgs e)
- {
- if (ConfigForm.Visible) ConfigForm.Visible = false;
- dragging = true;
- dragCursorPoint = Cursor.Position;
- dragFormPoint = this.Location;
- }
- private void Movement_panel_MouseUp(object sender, MouseEventArgs e)
- {
- dragging = false;
- }
- private void Movement_panel_MouseMove(object sender, MouseEventArgs e)
- {
- if (dragging)
- {
- Point dif = Point.Subtract(Cursor.Position, new Size(dragCursorPoint));
- this.Location = Point.Add(dragFormPoint, new Size(dif));
- }
- }
- private void Launch_pb_MouseEnter(object sender, EventArgs e)
- {
- Launch_pb.Image = Client.Resources.Images.Launch_Hover;
- }
- private void Launch_pb_MouseLeave(object sender, EventArgs e)
- {
- Launch_pb.Image = Client.Resources.Images.Launch_Base1;
- }
- private void Close_pb_MouseEnter(object sender, EventArgs e)
- {
- Close_pb.Image = Client.Resources.Images.Cross_Hover;
- }
- private void Close_pb_MouseLeave(object sender, EventArgs e)
- {
- Close_pb.Image = Client.Resources.Images.Cross_Base;
- }
- private void Launch_pb_MouseDown(object sender, MouseEventArgs e)
- {
- Launch_pb.Image = Client.Resources.Images.Launch_Pressed;
- }
- private void Launch_pb_MouseUp(object sender, MouseEventArgs e)
- {
- Launch_pb.Image = Client.Resources.Images.Launch_Base1;
- }
- private void Close_pb_MouseDown(object sender, MouseEventArgs e)
- {
- Close_pb.Image = Client.Resources.Images.Cross_Pressed;
- }
- private void Close_pb_MouseUp(object sender, MouseEventArgs e)
- {
- Close_pb.Image = Client.Resources.Images.Cross_Base;
- }
- private void ProgressCurrent_pb_SizeChanged(object sender, EventArgs e)
- {
- ProgEnd_pb.Location = new Point((ProgressCurrent_pb.Location.X + ProgressCurrent_pb.Width), ProgressCurrent_pb.Location.Y);
- if (ProgressCurrent_pb.Width == 0) ProgEnd_pb.Visible = false;
- else ProgEnd_pb.Visible = true;
- }
- private void Config_pb_MouseDown(object sender, MouseEventArgs e)
- {
- Config_pb.Image = Client.Resources.Images.Config_Pressed;
- }
- private void Config_pb_MouseEnter(object sender, EventArgs e)
- {
- Config_pb.Image = Client.Resources.Images.Config_Hover;
- }
- private void Config_pb_MouseLeave(object sender, EventArgs e)
- {
- Config_pb.Image = Client.Resources.Images.Config_Base;
- }
- private void Config_pb_MouseUp(object sender, MouseEventArgs e)
- {
- Config_pb.Image = Client.Resources.Images.Config_Base;
- }
- private void Config_pb_Click(object sender, EventArgs e)
- {
- if (ConfigForm.Visible) ConfigForm.Hide();
- else ConfigForm.Show(Program.PForm);
- ConfigForm.Location = new Point(Location.X + Config_pb.Location.X - 183, Location.Y + 36);
- }
- private void TotalProg_pb_SizeChanged(object sender, EventArgs e)
- {
- ProgTotalEnd_pb.Location = new Point((TotalProg_pb.Location.X + TotalProg_pb.Width), TotalProg_pb.Location.Y);
- if (TotalProg_pb.Width == 0) ProgTotalEnd_pb.Visible = false;
- else ProgTotalEnd_pb.Visible = true;
- }
- private void InterfaceTimer_Tick(object sender, EventArgs e)
- {
- try
- {
- if (Completed && ActiveDownloads.Count == 0)
- {
- ActionLabel.Text = "";
- CurrentFile_label.Text = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.UpToDate);
- SpeedLabel.Text = "";
- ProgressCurrent_pb.Width = 550;
- TotalProg_pb.Width = 550;
- CurrentFile_label.Visible = true;
- CurrentPercent_label.Visible = true;
- TotalPercent_label.Visible = true;
- CurrentPercent_label.Text = "100%";
- TotalPercent_label.Text = "100%";
- InterfaceTimer.Enabled = false;
- Launch_pb.Enabled = true;
- if (ErrorFound) MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.FilesDownloadFailed), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.DownloadFailed));
- ErrorFound = false;
- if (CleanFiles)
- {
- CleanFiles = false;
- MessageBox.Show(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.YourFilesCleanedUp), GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.CleanFiles));
- }
- if (Restart)
- {
- Program.Restart = true;
- Close();
- }
- if (Settings.P_AutoStart)
- {
- Launch();
- }
- return;
- }
- var currentBytes = 0L;
- FileInformation currentFile = null;
- // Remove completed downloads..
- for (var i = ActiveDownloads.Count - 1; i >= 0; i--)
- {
- var dl = ActiveDownloads[i];
- if (dl.Completed)
- {
- ActiveDownloads.RemoveAt(i);
- continue;
- }
- }
- for (var i = ActiveDownloads.Count - 1; i >= 0; i--)
- {
- var dl = ActiveDownloads[i];
- if (!dl.Completed)
- currentBytes += dl.CurrentBytes;
- }
- if (Settings.P_Concurrency == 1)
- {
- // Note: Just mimic old behaviour for now until a better UI is done.
- if (ActiveDownloads.Count > 0)
- currentFile = ActiveDownloads[0].Info;
- }
- ActionLabel.Visible = true;
- SpeedLabel.Visible = true;
- CurrentFile_label.Visible = true;
- CurrentPercent_label.Visible = true;
- TotalPercent_label.Visible = true;
- if (LabelSwitch) ActionLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.FilesRemaining), _fileCount - _currentCount);
- else ActionLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.MBRemaining), ((_totalBytes) - (_completedBytes + currentBytes)) / 1024 / 1024);
- if (Settings.P_Concurrency > 1)
- {
- CurrentFile_label.Text = string.Format("<Concurrent> {0}", ActiveDownloads.Count);
- SpeedLabel.Text = ToSize(currentBytes / _stopwatch.Elapsed.TotalSeconds);
- }
- else
- {
- if (currentFile != null)
- {
- CurrentFile_label.Text = string.Format("{0}", currentFile.FileName);
- SpeedLabel.Text = ToSize(currentBytes / _stopwatch.Elapsed.TotalSeconds);
- CurrentPercent_label.Text = ((int)(100 * currentBytes / currentFile.Length)).ToString() + "%";
- ProgressCurrent_pb.Width = (int)(5.5 * (100 * currentBytes / currentFile.Length));
- }
- }
- if (!(_completedBytes is 0 && currentBytes is 0 && _totalBytes is 0))
- {
- TotalProg_pb.Width = (int)(5.5 * (100 * (_completedBytes + currentBytes) / _totalBytes));
- TotalPercent_label.Text = ((int)(100 * (_completedBytes + currentBytes) / _totalBytes)).ToString() + "%";
- }
- }
- catch
- {
- //to-do
- }
- }
- private void AMain_Click(object sender, EventArgs e)
- {
- if (ConfigForm.Visible) ConfigForm.Visible = false;
- }
- private void ActionLabel_Click(object sender, EventArgs e)
- {
- LabelSwitch = !LabelSwitch;
- }
- private void Credit_label_Click(object sender, EventArgs e)
- {
- if (Credit_label.Text == "Powered by Crystal M2") Credit_label.Text = "Designed by Breezer";
- else Credit_label.Text = "Powered by Crystal M2";
- }
- private void AMain_FormClosed(object sender, FormClosedEventArgs e)
- {
- MoveOldFilesToCurrent();
- Launch_pb?.Dispose();
- Close_pb?.Dispose();
- }
- private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
- private string ToSize(double number, int precision = 2)
- {
- // unit's number of bytes
- const double unit = 1024;
- // suffix counter
- int i = 0;
- // as long as we're bigger than a unit, keep going
- while (number > unit)
- {
- number /= unit;
- i++;
- }
- // apply precision and current suffix
- return Math.Round(number, precision) + suffixes[i];
- }
- private void RepairOldFiles()
- {
- var files = Directory.GetFiles(Settings.P_Client, "*", SearchOption.AllDirectories).Where(x => Path.GetFileName(x).StartsWith("Old__"));
- foreach (var oldFilename in files)
- {
- if (!File.Exists(oldFilename.Replace("Old__", "")))
- {
- File.Move(oldFilename, oldFilename.Replace("Old__", ""));
- }
- else
- {
- File.Delete(oldFilename);
- }
- }
- }
- private void MoveOldFilesToCurrent()
- {
- var files = Directory.GetFiles(Settings.P_Client, "*", SearchOption.AllDirectories).Where(x => Path.GetFileName(x).StartsWith("Old__"));
- foreach (var oldFilename in files)
- {
- string originalFilename = Path.Combine(Path.GetDirectoryName(oldFilename), (Path.GetFileName(oldFilename).Replace("Old__", "")));
- if (!File.Exists(originalFilename) && File.Exists(oldFilename))
- File.Move(oldFilename, originalFilename);
- }
- }
- }
- }
|