mirror of
https://github.com/JuniorDark/RustyHearts-Launcher.git
synced 2026-05-07 13:31:45 -04:00
1099 lines
36 KiB
C#
1099 lines
36 KiB
C#
using Microsoft.WindowsAPICodePack.Taskbar;
|
|
using Newtonsoft.Json;
|
|
using RHLauncher.RHLauncher.Helper;
|
|
using RHLauncher.RHLauncher.Http;
|
|
using RHLauncher.RHLauncher.i8n;
|
|
using System.Diagnostics;
|
|
using static RHLauncher.RHLauncher.Http.ClientDownloader;
|
|
using static RHLauncher.RHLauncher.Http.UpdateDownloader;
|
|
|
|
/*
|
|
Rusty Hearts Launcher - Windows Forms Implementation in C#
|
|
Author: JuniorDark
|
|
GitHub Repository: https://github.com/JuniorDark/RustyHearts-Launcher
|
|
This code serves as a starting point for creating your own launcher.
|
|
However, it requires further development to improve functionality and
|
|
ensure stability. Please check the GitHub repository for updates.
|
|
*/
|
|
|
|
namespace RHLauncher
|
|
{
|
|
public partial class LauncherForm : Form
|
|
{
|
|
private RegistryHandler registryHandler = new();
|
|
private string? installDirectory;
|
|
private string? tempInstallDirectory;
|
|
private static readonly string DefaultIniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.ini");
|
|
private readonly IniFile _iniFile = new(DefaultIniFilePath);
|
|
private readonly string _windyCode;
|
|
private readonly string _password;
|
|
|
|
public LauncherForm(string windyCode, string password)
|
|
{
|
|
InitializeComponent();
|
|
_windyCode = windyCode;
|
|
_password = password;
|
|
installDirectory = registryHandler.GetInstallDirectory();
|
|
tempInstallDirectory = registryHandler.GetTempInstallDirectory();
|
|
|
|
notifyIcon.Text = LocalizedStrings.RustyHearts;
|
|
Text = LocalizedStrings.LauncherFormTitle;
|
|
LabelNews.Text = LocalizedStrings.LabelNews;
|
|
ChangeInstallLocationButton.Text = LocalizedStrings.InstallLocation;
|
|
UninstallButton.Text = LocalizedStrings.Uninstall;
|
|
OpenSettingsButton.Text = LocalizedStrings.GameSettings;
|
|
CheckUpdateButton.Text = LocalizedStrings.CheckUpdate;
|
|
OpenInstallDirButton.Text = LocalizedStrings.OpenInstallDir;
|
|
ManageButton.Text = LocalizedStrings.Manage;
|
|
ChangePwdButton.Text = LocalizedStrings.ChangePassword;
|
|
LogoutButton.Text = LocalizedStrings.Logout;
|
|
LabelInstalled.Text = LocalizedStrings.AlreadyInstalled;
|
|
LabelLocate.Text = LocalizedStrings.LocateGame;
|
|
}
|
|
|
|
#region Form Events
|
|
private async void LauncherForm_Load(object sender, EventArgs e)
|
|
{
|
|
NameLabel.Text = LocalizedStrings.Welcome + ", " + _windyCode;
|
|
ChangeCharPictureBox();
|
|
getUpdatePanel.Visible = false;
|
|
|
|
await LoadInstall();
|
|
await WebView2Async();
|
|
}
|
|
|
|
private void LauncherForm_Resize(object sender, EventArgs e)
|
|
{
|
|
if (WindowState == FormWindowState.Minimized)
|
|
{
|
|
notifyIcon.Visible = true;
|
|
}
|
|
}
|
|
private void LauncherForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (e.CloseReason == CloseReason.UserClosing)
|
|
{
|
|
Application.Exit();
|
|
}
|
|
}
|
|
|
|
private void LauncherForm_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
notifyIcon.Icon = null;
|
|
notifyIcon?.Dispose();
|
|
}
|
|
#endregion
|
|
|
|
#region Install Methods
|
|
private async Task Install()
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(tempInstallDirectory))
|
|
{
|
|
using FolderBrowserDialog installFbd = new()
|
|
{
|
|
Description = LocalizedStrings.SelectInstallLocation,
|
|
RootFolder = Environment.SpecialFolder.MyComputer,
|
|
ShowNewFolderButton = true
|
|
};
|
|
|
|
if (installFbd.ShowDialog() == DialogResult.OK)
|
|
{
|
|
tempInstallDirectory = installFbd.SelectedPath;
|
|
if (!string.IsNullOrEmpty(tempInstallDirectory))
|
|
{
|
|
registryHandler.SaveTempInstallDirectory(tempInstallDirectory);
|
|
await DownloadClient();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await DownloadClient();
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async Task LoadInstall()
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
SetLocateLabels(true);
|
|
LaunchOptionsButton.Enabled = false;
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Click += InstallButton_Click;
|
|
}
|
|
else
|
|
{
|
|
DirectoryInfo directoryInfo = new(installDirectory);
|
|
if (Directory.Exists(installDirectory))
|
|
{
|
|
SetLocateLabels(false);
|
|
ServiceFileHandler updater = new("Config.ini", installDirectory);
|
|
updater.UpdateService();
|
|
|
|
await CheckForUpdates();
|
|
}
|
|
else
|
|
{
|
|
registryHandler.ClearInstallDirectory();
|
|
tempInstallDirectory = null;
|
|
registryHandler.ClearTempInstallDirectory();
|
|
LaunchButton.Enabled = true;
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Click -= LaunchGameButton_Click;
|
|
LaunchButton.Click += InstallButton_Click;
|
|
LabelInstalled.Visible = true;
|
|
LabelLocate.Visible = true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async Task LocateInstall()
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
OpenFileDialog ofd = new()
|
|
{
|
|
InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
|
|
Filter = "RustyHearts.exe|RustyHearts.exe",
|
|
Title = LocalizedStrings.SelectExe,
|
|
};
|
|
if (ofd.ShowDialog() == DialogResult.OK)
|
|
{
|
|
installDirectory = Path.GetDirectoryName(ofd.FileName);
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
SetInstallDirectory(installDirectory);
|
|
await CheckForUpdates();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void SetInstallDirectory(string directory)
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(directory))
|
|
{
|
|
SetLocateLabels(false);
|
|
installDirectory = directory;
|
|
registryHandler.SaveInstallDirectory(directory);
|
|
tempInstallDirectory = null;
|
|
registryHandler.ClearTempInstallDirectory();
|
|
LaunchButton.Click -= InstallButton_Click;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void SetLocateLabels(bool state)
|
|
{
|
|
LabelInstalled.Visible = state;
|
|
LabelLocate.Visible = state;
|
|
}
|
|
#endregion
|
|
|
|
#region Update Methods
|
|
private async Task CheckForUpdates()
|
|
{
|
|
try
|
|
{
|
|
LaunchButton.Enabled = false;
|
|
LaunchButton.Text = LocalizedStrings.Checking;
|
|
LaunchOptionsButton.Enabled = false;
|
|
|
|
bool updateAvailable = false;
|
|
switch (await CheckForUpdatesAsync())
|
|
{
|
|
case UpdateState.UpdateAvailable:
|
|
updateAvailable = true;
|
|
break;
|
|
case UpdateState.NoUpdateAvailable:
|
|
case UpdateState.Error:
|
|
updateAvailable = false;
|
|
break;
|
|
}
|
|
|
|
SetLaunchButtonHandlers(updateAvailable);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
finally
|
|
{
|
|
LaunchButton.Enabled = true;
|
|
LaunchOptionsButton.Enabled = true;
|
|
AccOptionsButton.Enabled = true;
|
|
}
|
|
}
|
|
|
|
private void SetLaunchButtonHandlers(bool updateAvailable)
|
|
{
|
|
LaunchButton.Click -= InstallButton_Click;
|
|
LaunchButton.Click -= InstallUpdateButton_Click;
|
|
LaunchButton.Click -= LaunchGameButton_Click;
|
|
|
|
if (updateAvailable)
|
|
{
|
|
LaunchButton.Text = LocalizedStrings.Update;
|
|
LaunchButton.Click += InstallUpdateButton_Click;
|
|
}
|
|
else
|
|
{
|
|
LaunchButton.Text = LocalizedStrings.Launch;
|
|
LaunchButton.Click += LaunchGameButton_Click;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Download Methods
|
|
private readonly SemaphoreSlim _semaphore = new(1);
|
|
|
|
public async Task DownloadClient()
|
|
{
|
|
HidePanels();
|
|
SetLocateLabels(false);
|
|
LaunchButton.Text = LocalizedStrings.Downloading;
|
|
LaunchButton.Enabled = false;
|
|
LaunchOptionsButton.Enabled = false;
|
|
|
|
await _semaphore.WaitAsync();
|
|
_cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
try
|
|
{
|
|
Progress<ProgressReport> progress = new(ReportProgress);
|
|
ProgressThrottler progressThrottler = new(progress, 100);
|
|
|
|
if (!string.IsNullOrEmpty(tempInstallDirectory))
|
|
{
|
|
DownloadClientResult result = await DownloadClientAsync(tempInstallDirectory, progressThrottler, _cancellationTokenSource.Token);
|
|
if (result.Status == DownloadClientResultStatus.Success)
|
|
{
|
|
if (result.InstallDirectoryPath != null)
|
|
{
|
|
SetInstallDirectory(result.InstallDirectoryPath);
|
|
await CheckForUpdates();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLocateLabels(true);
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Enabled = true;
|
|
LaunchOptionsButton.Enabled = false;
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (OperationCanceledException ex)
|
|
{
|
|
Logger.WriteLog($"Download canceled: {ex.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
finally
|
|
{
|
|
_semaphore.Release();
|
|
}
|
|
}
|
|
|
|
public async Task InstallUpdateAsync()
|
|
{
|
|
await _semaphore.WaitAsync();
|
|
_cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
try
|
|
{
|
|
Progress<ProgressReport> progress = new(ReportProgress);
|
|
ProgressThrottler progressThrottler = new(progress, 100);
|
|
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
await DownloadUpdatesAsync(installDirectory, progressThrottler, _cancellationTokenSource.Token);
|
|
if (!_cancellationTokenSource.Token.IsCancellationRequested)
|
|
{
|
|
await Task.Delay(1000);
|
|
await PatchUpdatesAsync(installDirectory);
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (OperationCanceledException ex)
|
|
{
|
|
Logger.WriteLog($"Update installation canceled: {ex.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
await CheckForUpdates();
|
|
}
|
|
finally
|
|
{
|
|
_semaphore.Release();
|
|
await CheckForUpdates();
|
|
}
|
|
}
|
|
|
|
public async Task PatchUpdatesAsync(string installDir)
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(installDir))
|
|
{
|
|
string mpatcherPath = Path.Combine(installDir, "MPatcher.exe");
|
|
|
|
if (!File.Exists(mpatcherPath))
|
|
{
|
|
MsgBoxForm.Show(LocalizedStrings.MPatcher, LocalizedStrings.Error);
|
|
Logger.WriteLog(LocalizedStrings.MPatcher);
|
|
return;
|
|
}
|
|
|
|
ProcessStartInfo startInfo = new()
|
|
{
|
|
FileName = mpatcherPath,
|
|
WorkingDirectory = installDirectory
|
|
};
|
|
|
|
Process? process = Process.Start(startInfo);
|
|
|
|
if (process != null)
|
|
{
|
|
await process.WaitForExitAsync();
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private const long ScaleFactor = 100000;
|
|
private void ReportProgress(ProgressReport progressReport)
|
|
{
|
|
if (InvokeRequired)
|
|
{
|
|
Invoke(new Action<ProgressReport>(ReportProgress), progressReport);
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
getUpdatePanel.Visible = progressReport.Panel;
|
|
StopButton.Visible = progressReport.CancellButton;
|
|
FileNameLabel.Visible = progressReport.ShowFileNameLabel;
|
|
SpeedLabel.Visible = progressReport.ShowSpeedLabel;
|
|
TimeLabel.Visible = progressReport.ShowTimeLabel;
|
|
FileSizeLabel.Visible = progressReport.ShowFileSizeLabel;
|
|
FileCountLabel.Visible = progressReport.ShowFileCountLabel;
|
|
DownloadingLabel.Text = progressReport.Label;
|
|
PercentLabel.Text = $"{progressReport.PercentComplete}%";
|
|
if (progressReport.IsCheckingFilelist)
|
|
{
|
|
progressBar.Maximum = (int)progressReport.Total;
|
|
progressBar.Value = (int)Math.Min(progressReport.Current, progressReport.Total);
|
|
}
|
|
else
|
|
{
|
|
long scaledMaxValue = progressReport.Total / ScaleFactor;
|
|
long scaledCurrentValue = progressReport.Current / ScaleFactor;
|
|
|
|
scaledMaxValue = Math.Min(scaledMaxValue, int.MaxValue);
|
|
scaledCurrentValue = Math.Min(scaledCurrentValue, scaledMaxValue);
|
|
|
|
progressBar.Maximum = (int)scaledMaxValue;
|
|
progressBar.Value = (int)scaledCurrentValue;
|
|
}
|
|
|
|
if (TaskbarManager.IsPlatformSupported)
|
|
{
|
|
TaskbarManager.Instance.SetProgressValue(progressReport.PercentComplete, 100);
|
|
}
|
|
|
|
FileNameLabel.Text = progressReport.FileName;
|
|
SpeedLabel.Text = DownloadHelper.FormatDownloadSpeed(progressReport.TotalSpeed);
|
|
TimeSpan t = TimeSpan.FromSeconds(progressReport.TimeLeft);
|
|
TimeLabel.Text = $"{t.Hours:00}:{t.Minutes:00}:{t.Seconds:00}";
|
|
FileSizeLabel.Text = $"({DownloadHelper.FormatFileSize(progressReport.Current)} / {DownloadHelper.FormatFileSize(progressReport.Total)})";
|
|
FileCountLabel.Text = $"({progressReport.NumFiles}/{progressReport.TotalNumFiles})";
|
|
LaunchButton.Text = progressReport.Button;
|
|
|
|
if (!string.IsNullOrEmpty(progressReport.FileName))
|
|
{
|
|
FileNameLabel.Refresh();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
|
|
}
|
|
|
|
private static async Task<bool> CheckServerStatusAsync()
|
|
{
|
|
try
|
|
{
|
|
using HttpClient client = new();
|
|
using HttpResponseMessage response = await client.GetAsync(Configuration.Default.GateStatusUrl);
|
|
response.EnsureSuccessStatusCode();
|
|
string json = await response.Content.ReadAsStringAsync();
|
|
|
|
var result = JsonConvert.DeserializeObject<ServerStatusResponse>(json);
|
|
|
|
if (result != null && !string.IsNullOrEmpty(result.Status))
|
|
{
|
|
return (result.Status == "online");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Button Click Events
|
|
|
|
private async void InstallUpdateButton_Click(object? sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
LaunchButton.Text = LocalizedStrings.Updating;
|
|
LaunchButton.Enabled = false;
|
|
LaunchOptionsButton.Enabled = false;
|
|
await InstallUpdateAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async void LaunchGameButton_Click(object? sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
await Launch();
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private CancellationTokenSource? _cancellationTokenSource;
|
|
private void StopButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_cancellationTokenSource?.Cancel();
|
|
getUpdatePanel.Visible = false;
|
|
LaunchButton.Text = LocalizedStrings.Cancelling;
|
|
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async void LbLocate_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
await LocateInstall();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
|
|
}
|
|
|
|
private void CharPictureBox_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
ChangeCharPictureBox();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void OnMouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
HidePanels();
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
FormUtils.MoveForm(Handle);
|
|
}
|
|
}
|
|
|
|
private void CloseButton_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void MinimizeButton_Click(object sender, EventArgs e)
|
|
{
|
|
WindowState = FormWindowState.Minimized;
|
|
}
|
|
|
|
private void LogoutButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Logout();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async void UpdateCheckButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
await CheckForUpdates();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async void InstallButton_Click(object? sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
await Install();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private async void ChangeInstallLocationButton_Click(object? sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
OpenFileDialog ofd = new()
|
|
{
|
|
InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
|
|
Filter = "RustyHearts.exe|RustyHearts.exe",
|
|
Title = "Select RustyHearts.exe"
|
|
};
|
|
if (ofd.ShowDialog() == DialogResult.OK)
|
|
{
|
|
installDirectory = Path.GetDirectoryName(ofd.FileName);
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
registryHandler.SaveInstallDirectory(installDirectory);
|
|
await CheckForUpdates();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
|
|
}
|
|
|
|
private void ManageButton_Click(object sender, EventArgs e)
|
|
{
|
|
InstallPanel.Visible = !InstallPanel.Visible;
|
|
}
|
|
|
|
private void OpenInstallDirButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
Process.Start("explorer.exe", installDirectory);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void OpenSettingsButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
string rustyHeartsConfigPath = Path.Combine(installDirectory, "rustyheartsconfig.exe");
|
|
if (File.Exists(rustyHeartsConfigPath))
|
|
{
|
|
ProcessStartInfo startInfo = new()
|
|
{
|
|
FileName = rustyHeartsConfigPath,
|
|
WorkingDirectory = installDirectory
|
|
|
|
};
|
|
Process.Start(startInfo);
|
|
}
|
|
else
|
|
{
|
|
MsgBoxForm.Show(LocalizedStrings.rustyheartsconfig, LocalizedStrings.Error);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void UninstallButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Uninstall();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
|
|
}
|
|
|
|
private void ChangePwdButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
ChangePwdForm changePwd = new(true);
|
|
changePwd.FormClosing += ChangePwd_FormClosing;
|
|
changePwd.ShowDialog();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void ChangePwd_FormClosing(object? sender, FormClosingEventArgs e)
|
|
{
|
|
if (sender is ChangePwdForm changePwd)
|
|
{
|
|
changePwd.Dispose();
|
|
}
|
|
}
|
|
|
|
private void LaunchOptionsButton_Click(object sender, EventArgs e)
|
|
{
|
|
LaunchPanel.Visible = !LaunchPanel.Visible;
|
|
if (InstallPanel.Visible)
|
|
{
|
|
InstallPanel.Visible = false;
|
|
}
|
|
}
|
|
|
|
private void SettingsButton_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
ConfigForm configForm = new();
|
|
configForm.ShowDialog();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Button Events
|
|
|
|
private void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
// Restore the form and hide the NotifyIcon when clicked
|
|
Show();
|
|
WindowState = FormWindowState.Normal;
|
|
notifyIcon.Visible = false;
|
|
}
|
|
}
|
|
|
|
private void AccOptionsButton_Click(object sender, EventArgs e)
|
|
{
|
|
AccPanel.Visible = !AccPanel.Visible;
|
|
}
|
|
|
|
private void Button_MouseHover(object sender, EventArgs e)
|
|
{
|
|
if (sender is Button button)
|
|
{
|
|
button.ImageIndex = 1;
|
|
}
|
|
}
|
|
|
|
private void Button_MouseLeave(object sender, EventArgs e)
|
|
{
|
|
if (sender is Button button)
|
|
{
|
|
button.ImageIndex = 0;
|
|
}
|
|
}
|
|
|
|
private void Button_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
if (sender is Button button)
|
|
{
|
|
button.ImageIndex = 2;
|
|
}
|
|
}
|
|
|
|
private void LabelLocate_MouseHover(object sender, EventArgs e)
|
|
{
|
|
LabelLocate.ForeColor = Color.Gold;
|
|
}
|
|
|
|
private void LabelLocate_MouseLeave(object sender, EventArgs e)
|
|
{
|
|
LabelLocate.ForeColor = Color.Goldenrod;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
private async Task Launch()
|
|
{
|
|
try
|
|
{
|
|
HidePanels();
|
|
LaunchButton.Text = LocalizedStrings.Launching;
|
|
LaunchButton.Enabled = false;
|
|
LaunchOptionsButton.Enabled = false;
|
|
AccOptionsButton.Enabled = false;
|
|
|
|
// Check if RustyHearts.exe is already running
|
|
if (Process.GetProcessesByName("RustyHearts").Length > 0)
|
|
{
|
|
MsgBoxForm.Show(LocalizedStrings.AlreadyExecute, LocalizedStrings.Error);
|
|
await CheckForUpdates();
|
|
return;
|
|
}
|
|
|
|
// Check if server is online
|
|
bool serverOnline = await CheckServerStatusAsync();
|
|
if (!serverOnline)
|
|
{
|
|
MsgBoxForm.Show(LocalizedStrings.ServerOffline, LocalizedStrings.Error);
|
|
await CheckForUpdates();
|
|
return;
|
|
}
|
|
|
|
LaunchButton.Text = LocalizedStrings.Running;
|
|
LaunchButton.Enabled = false;
|
|
LaunchOptionsButton.Enabled = false;
|
|
AccOptionsButton.Enabled = false;
|
|
|
|
string service = _iniFile.ReadValue("Info", "Service");
|
|
string arguments = string.Empty;
|
|
|
|
switch (service.ToLower())
|
|
{
|
|
case "usa":
|
|
case "usa_beta":
|
|
arguments = "server=" + Configuration.Default.GateXMLUrl;
|
|
break;
|
|
case "jpn":
|
|
case "jpn_beta":
|
|
arguments = $"-serverurl{Configuration.Default.GateInfoUrl}";
|
|
break;
|
|
case "chn":
|
|
case "chn_beta":
|
|
arguments = $"-serverurl{Configuration.Default.GateInfoUrl} id={_windyCode} password={_password}";
|
|
break;
|
|
default:
|
|
// handle unsupported service
|
|
MsgBoxForm.Show(LocalizedStrings.UnsupportedService, LocalizedStrings.Error);
|
|
await CheckForUpdates();
|
|
return;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
ProcessStartInfo startInfo = new()
|
|
{
|
|
FileName = Path.Combine(installDirectory, "RustyHearts.exe"),
|
|
Arguments = arguments,
|
|
WorkingDirectory = installDirectory
|
|
};
|
|
|
|
Process? process = Process.Start(startInfo);
|
|
|
|
if (process != null)
|
|
{
|
|
WindowState = FormWindowState.Minimized;
|
|
|
|
if (WindowState == FormWindowState.Minimized)
|
|
{
|
|
Hide();
|
|
notifyIcon.Visible = true;
|
|
}
|
|
|
|
await process.WaitForExitAsync();
|
|
|
|
Show();
|
|
WindowState = FormWindowState.Normal;
|
|
notifyIcon.Visible = false;
|
|
|
|
await CheckForUpdates();
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
}
|
|
|
|
private void Uninstall()
|
|
{
|
|
HidePanels();
|
|
|
|
if (!string.IsNullOrEmpty(installDirectory))
|
|
{
|
|
DialogResult result = MsgBoxForm.ShowYN(LocalizedStrings.ConfirmUninstallText, LocalizedStrings.ConfirmUninstall);
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
try
|
|
{
|
|
LaunchButton.Enabled = false;
|
|
LaunchOptionsButton.Enabled = false;
|
|
LaunchButton.Text = LocalizedStrings.Uninstalling;
|
|
|
|
DirectoryInfo directoryInfo = new(installDirectory);
|
|
if (Directory.Exists(installDirectory))
|
|
{
|
|
foreach (FileInfo file in directoryInfo.GetFiles())
|
|
{
|
|
if (!file.Name.Equals("launcher.exe", StringComparison.CurrentCultureIgnoreCase) && !file.Name.Equals("config.ini", StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
file.Delete();
|
|
}
|
|
}
|
|
|
|
foreach (DirectoryInfo dir in directoryInfo.GetDirectories())
|
|
{
|
|
if (!dir.Name.Equals("Launcher.exe.WebView2", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
dir.Delete(true);
|
|
}
|
|
}
|
|
|
|
registryHandler.ClearInstallDirectory();
|
|
LaunchButton.Enabled = true;
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Click -= InstallButton_Click;
|
|
LaunchButton.Click -= InstallUpdateButton_Click;
|
|
LaunchButton.Click -= LaunchGameButton_Click;
|
|
LaunchButton.Click += InstallButton_Click;
|
|
LabelInstalled.Visible = true;
|
|
LabelLocate.Visible = true;
|
|
MsgBoxForm.Show(LocalizedStrings.UninstallText, LocalizedStrings.Uninstall);
|
|
|
|
}
|
|
else
|
|
{
|
|
registryHandler.ClearInstallDirectory();
|
|
LaunchButton.Enabled = true;
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Click -= InstallButton_Click;
|
|
LaunchButton.Click -= InstallUpdateButton_Click;
|
|
LaunchButton.Click -= LaunchGameButton_Click;
|
|
LaunchButton.Click += InstallButton_Click;
|
|
LabelInstalled.Visible = true;
|
|
LabelLocate.Visible = true;
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleException(ex);
|
|
}
|
|
finally
|
|
{
|
|
registryHandler.ClearInstallDirectory();
|
|
LaunchButton.Enabled = true;
|
|
LaunchButton.Text = LocalizedStrings.Install;
|
|
LaunchButton.Click -= InstallButton_Click;
|
|
LaunchButton.Click -= InstallUpdateButton_Click;
|
|
LaunchButton.Click -= LaunchGameButton_Click;
|
|
LaunchButton.Click += InstallButton_Click;
|
|
LabelInstalled.Visible = true;
|
|
LabelLocate.Visible = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Logout()
|
|
{
|
|
HidePanels();
|
|
DialogResult result = MsgBoxForm.ShowYN(LocalizedStrings.LogoutText, LocalizedStrings.Confirmation);
|
|
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
registryHandler = new RegistryHandler();
|
|
registryHandler.SaveValues(_windyCode, "", false, false);
|
|
|
|
LoginForm? loginForm = Application.OpenForms.OfType<LoginForm>().FirstOrDefault();
|
|
if (loginForm != null)
|
|
{
|
|
Invoke((MethodInvoker)(() => Close()));
|
|
Task.Delay(500).ContinueWith(_ =>
|
|
{
|
|
Application.Restart();
|
|
});
|
|
}
|
|
else
|
|
{
|
|
LoginForm newLoginForm = new();
|
|
newLoginForm.Show();
|
|
Invoke((MethodInvoker)(() => Close()));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private async Task WebView2Async()
|
|
{
|
|
await webView2.EnsureCoreWebView2Async();
|
|
webView2.Source = new Uri(Configuration.Default.LauncherNewsUrl);
|
|
webView2.CoreWebView2.NavigationStarting += (sender, args) =>
|
|
{
|
|
// Check if the URL being navigated to is an external link
|
|
if (!args.Uri.ToString().StartsWith(Configuration.Default.LauncherNewsUrl))
|
|
{
|
|
// Cancel the navigation
|
|
args.Cancel = true;
|
|
|
|
// Launch the URL in the user's default browser
|
|
Process.Start(new ProcessStartInfo(args.Uri) { UseShellExecute = true });
|
|
}
|
|
};
|
|
}
|
|
|
|
private async void ChangeCharPictureBox()
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
Random rnd = new();
|
|
int index = rnd.Next(images.Length);
|
|
Invoke(new Action(() =>
|
|
{
|
|
CharPictureBox.Image = images[index];
|
|
}));
|
|
});
|
|
}
|
|
|
|
private readonly Image[] images = LoadImages();
|
|
|
|
private static Image[] LoadImages()
|
|
{
|
|
return
|
|
[
|
|
Properties.Resources.character_select_cut_angela,
|
|
Properties.Resources.character_select_cut_edgar,
|
|
Properties.Resources.character_select_cut_frantz,
|
|
Properties.Resources.character_select_cut_ian,
|
|
Properties.Resources.character_select_cut_leila,
|
|
Properties.Resources.character_select_cut_meilinchen,
|
|
Properties.Resources.character_select_cut_natasha,
|
|
Properties.Resources.character_select_cut_roselle,
|
|
Properties.Resources.character_select_cut_tude
|
|
];
|
|
}
|
|
|
|
private static void HidePanel(Panel panel)
|
|
{
|
|
if (panel.Visible)
|
|
{
|
|
panel.Visible = false;
|
|
}
|
|
}
|
|
|
|
private void HidePanels()
|
|
{
|
|
HidePanel(AccPanel);
|
|
HidePanel(LaunchPanel);
|
|
HidePanel(InstallPanel);
|
|
}
|
|
|
|
private static void HandleException(Exception ex)
|
|
{
|
|
string errorMessage = ex.Message;
|
|
string errorLog = ex.Message + ex.StackTrace;
|
|
Exception newEx = new(errorMessage, ex);
|
|
Exception newLogEx = new(errorLog, ex);
|
|
ExceptionHandler.HandleException(newEx, newLogEx);
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|