mirror of
https://github.com/JuniorDark/RustyHearts-Launcher.git
synced 2026-05-07 13:31:45 -04:00
Compare commits
No commits in common. "master" and "1.2.0" have entirely different histories.
20 changed files with 305 additions and 595 deletions
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
|
|
@ -6,24 +6,19 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: '9.0.x'
|
dotnet-version: '7.0.x'
|
||||||
|
- name: Build
|
||||||
# Build with --self-contained false
|
run: dotnet publish --configuration Release --self-contained false --runtime win-x64 /p:PublishSingleFile=true
|
||||||
- name: Build Rusty Hearts Launcher (No Self-Contained)
|
- name: Zip output file
|
||||||
run: dotnet publish ./RHLauncher.sln --configuration Release --self-contained false --runtime win-x64 /p:PublishSingleFile=true /p:PublishDir=./publish/RustyHearts-Launcher_framework-dependent
|
run: Compress-Archive -Path ./bin/Release/net7.0-windows7.0/win-x64/publish/Launcher.exe -DestinationPath Launcher.zip
|
||||||
|
|
||||||
- name: Zip output files (No Self-Contained)
|
|
||||||
run: Compress-Archive -Path "./publish/RustyHearts-Launcher_framework-dependent" -DestinationPath RustyHearts-Launcher.zip
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: Launcher
|
name: Launcher
|
||||||
path: RustyHearts-Launcher.zip
|
path: Launcher.zip
|
||||||
|
|
|
||||||
58
.github/workflows/release.yml
vendored
58
.github/workflows/release.yml
vendored
|
|
@ -3,50 +3,42 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: '9.0.x'
|
dotnet-version: '7.0.x'
|
||||||
|
- name: Get version from .csproj file
|
||||||
# Build with --self-contained false
|
|
||||||
- name: Build Rusty Hearts Launcher (No Self-Contained)
|
|
||||||
run: dotnet publish ./RHLauncher.sln --configuration Release --self-contained false --runtime win-x64 /p:PublishSingleFile=true /p:PublishDir=./publish/RustyHearts-Launcher_framework-dependent
|
|
||||||
|
|
||||||
- name: Zip output files (No Self-Contained)
|
|
||||||
run: Compress-Archive -Path "./publish/RustyHearts-Launcher_framework-dependent" -DestinationPath RustyHearts-Launcher-Framework-Dependent.zip
|
|
||||||
|
|
||||||
# Build with --self-contained true
|
|
||||||
- name: Build Rusty Hearts Launcher (Self-Contained)
|
|
||||||
run: dotnet publish ./RHLauncher.sln --configuration Release --self-contained true --runtime win-x64 /p:PublishSingleFile=false /p:PublishDir=./publish/RustyHearts-Launcher_self-contained
|
|
||||||
|
|
||||||
- name: Zip output files (Self-Contained)
|
|
||||||
run: Compress-Archive -Path "./publish/RustyHearts-Launcher_self-contained" -DestinationPath RustyHearts-Launcher-SelfContained.zip
|
|
||||||
|
|
||||||
- name: Get version from compiled assembly
|
|
||||||
id: version
|
id: version
|
||||||
run: |
|
|
||||||
$version = (Get-Command "./publish/RustyHearts-Launcher_self-contained/Launcher.dll").FileVersionInfo.FileVersion
|
|
||||||
echo "::set-output name=version::$version"
|
|
||||||
|
|
||||||
# Create Release and Upload Assets using softprops/action-gh-release
|
run: |
|
||||||
- name: Create GitHub Release and Upload Assets
|
echo "::set-output name=version::$(grep -m1 -o '<FileVersion>[^<]*' RHLauncher.csproj | sed 's/<FileVersion>//')"
|
||||||
uses: softprops/action-gh-release@v2
|
- name: Build
|
||||||
|
run: dotnet publish --configuration Release --self-contained false --runtime win-x64 /p:PublishSingleFile=true
|
||||||
|
- name: Zip output file
|
||||||
|
run: Compress-Archive -Path ./bin/Release/net7.0-windows7.0/win-x64/publish/Launcher.exe -DestinationPath Launcher.zip
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
with:
|
with:
|
||||||
tag_name: v${{ steps.version.outputs.version }}
|
tag_name: ${{ steps.version.outputs.version }}
|
||||||
body: Automated pre-release created by GitHub Actions.
|
release_name: v${{ steps.version.outputs.version }}
|
||||||
draft: true
|
body: Automated release created by GitHub Actions.
|
||||||
prerelease: true
|
draft: false
|
||||||
files: |
|
prerelease: false
|
||||||
./RustyHearts-Launcher-Framework-Dependent.zip
|
env:
|
||||||
./RustyHearts-Launcher-SelfContained.zip
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Upload Release Asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./Launcher.zip
|
||||||
|
asset_name: Launcher.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
54
README.md
54
README.md
|
|
@ -23,8 +23,10 @@ Rusty Hearts Launcher is a custom launcher for the Rusty Hearts game client. It
|
||||||
* [Prerequisites for Building Locally/Development](#prerequisites-for-building-locallydevelopment)
|
* [Prerequisites for Building Locally/Development](#prerequisites-for-building-locallydevelopment)
|
||||||
* [System Requirements for Ready-to-use build](#system-requirements-for-ready-to-use-build)
|
* [System Requirements for Ready-to-use build](#system-requirements-for-ready-to-use-build)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
* [Building](#building)
|
* [Contributing](#contributing)
|
||||||
|
* [FAQ](#faq)
|
||||||
* [Credits](#credits)
|
* [Credits](#credits)
|
||||||
|
* [Support](#support)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Game Download: The launcher can download and install the client.
|
* Game Download: The launcher can download and install the client.
|
||||||
|
|
@ -42,9 +44,8 @@ In order for the launcher to work it need to be conected to the api. To change t
|
||||||
The default URL for the api can be changed on IniFile.cs
|
The default URL for the api can be changed on IniFile.cs
|
||||||
|
|
||||||
### Client region
|
### Client region
|
||||||
The client region can be set on Config.ini or in the Config menu
|
The client region can be set on Service on Config.ini
|
||||||
|
|
||||||
* **Jpn** (SEGA) - Full api support
|
|
||||||
* **usa** (PWE) - Full api support
|
* **usa** (PWE) - Full api support
|
||||||
* **chn** (Xunlei) - Only launcher support
|
* **chn** (Xunlei) - Only launcher support
|
||||||
|
|
||||||
|
|
@ -72,37 +73,36 @@ If you want to add a new language create a LocalizedStrings.<language>.resx with
|
||||||
|
|
||||||
If you want to change the text on the buttons/images used in the launcher you can use the Photoshop .psd files included in the PSD Resources.rar
|
If you want to change the text on the buttons/images used in the launcher you can use the Photoshop .psd files included in the PSD Resources.rar
|
||||||
|
|
||||||
## Prerequisites for Development
|
## Prerequisites for Building Locally/Development
|
||||||
* Visual Studio 2022 (Any Edition - 17.12 or later)
|
The launcher is built in .NET 7 and as such, the packages listed below are required to create a local and development build of the launcher. Furthermore, it uses many submodules and packages outside of this, which will automatically be loaded when the user sets up a local environment of the application.
|
||||||
* Windows 10 SDK or Windows 11 SDK via Visual Studio Installer
|
* Visual Studio 2022 (Any Edition - 17.4 or later)
|
||||||
* .NET Core 9 SDK (9.0.100 or later)
|
* Windows 10 SDK (10.0.19043.0) or Windows 11 SDK (10.0.22000.0) via Visual Studio Installer
|
||||||
|
* .NET: [.NET Core 7 SDK (7.0.100 or later)](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
|
||||||
|
|
||||||
## Building
|
## System Requirements for Ready-to-use build
|
||||||
|
* OS: Windows 10 1809 Update (build 17763) or later / Windows 11 (Any builds)
|
||||||
If you wish to build the project yourself, follow these steps:
|
* Architecture: x64/AMD64
|
||||||
|
|
||||||
### Step 1
|
|
||||||
|
|
||||||
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0).
|
|
||||||
Make sure your SDK version is higher or equal to the required version specified.
|
|
||||||
|
|
||||||
### Step 2
|
|
||||||
|
|
||||||
Either use `git clone https://github.com/JuniorDark/RustyHearts-Launcher` on the command line to clone the repository or use Code --> Download zip button to get the files.
|
|
||||||
|
|
||||||
### Step 3
|
|
||||||
|
|
||||||
To build Rusty Hearts Launcher, open a command prompt inside the project directory.
|
|
||||||
You can quickly access it on Windows by holding shift in File Explorer, then right clicking and selecting `Open command window here`.
|
|
||||||
Then type the following command: `dotnet build -c Release`.
|
|
||||||
|
|
||||||
The built files will be found in the newly created `bin` build directory.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This project is licensed under the terms found in [`LICENSE-0BSD`](LICENSE).
|
This project is licensed under the terms found in [`LICENSE-0BSD`](LICENSE).
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Contributions from the community are welcome! If you encounter a bug or have a feature request, please submit an issue on GitHub. If you would like to contribute code, please fork the repository and submit a pull request.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
* Q: How do I report a bug?
|
||||||
|
* A: Please submit an issue on GitHub with a detailed description of the bug and steps to reproduce it.
|
||||||
|
* Q: How do I request a new feature?
|
||||||
|
* A: Please submit an issue on GitHub with a detailed description of the feature and why it would be useful.
|
||||||
|
* Q: How do I contribute code?
|
||||||
|
* A: Please fork the repository, make your changes, and submit a pull request.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
The following third-party libraries, tools, and resources are used in this project:
|
The following third-party libraries, tools, and resources are used in this project:
|
||||||
|
* [DotNetZip](https://www.nuget.org/packages/DotNetZip)
|
||||||
* [Microsoft.Web.WebView2](https://www.nuget.org/packages/Microsoft.Web.WebView2)
|
* [Microsoft.Web.WebView2](https://www.nuget.org/packages/Microsoft.Web.WebView2)
|
||||||
* [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json)
|
* [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json)
|
||||||
* [WindowsAPICodePack](https://www.nuget.org/packages/WindowsAPICodePack)
|
* [WindowsAPICodePack](https://www.nuget.org/packages/WindowsAPICodePack)
|
||||||
|
|
||||||
|
## Support
|
||||||
|
If you need help with the launcher, please submit an issue on GitHub.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Newtonsoft.Json;
|
using RHLauncher.RHLauncher.Helper;
|
||||||
using RHLauncher.RHLauncher.Helper;
|
|
||||||
using RHLauncher.RHLauncher.i8n;
|
using RHLauncher.RHLauncher.i8n;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
|
@ -9,10 +8,10 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
private RegistryHandler registryHandler = new();
|
private RegistryHandler registryHandler = new();
|
||||||
|
|
||||||
private readonly string SendPasswordCodeUrl = Configuration.Default.SendPasswordCodeUrl;
|
public string SendPasswordCodeUrl = Configuration.Default.SendPasswordCodeUrl;
|
||||||
private readonly string VerifyCodeUrl = Configuration.Default.VerifyCodeUrl;
|
public string VerifyCodeUrl = Configuration.Default.VerifyCodeUrl;
|
||||||
private readonly string ChangePasswordUrl = Configuration.Default.ChangePasswordUrl;
|
public string ChangePasswordUrl = Configuration.Default.ChangePasswordUrl;
|
||||||
private readonly string Lang = Configuration.Default.Lang;
|
public string Lang = Configuration.Default.Lang;
|
||||||
private List<Button>? buttons;
|
private List<Button>? buttons;
|
||||||
private List<ImageList>? imageLists;
|
private List<ImageList>? imageLists;
|
||||||
private Dictionary<string, List<ImageList>>? languageImageLists;
|
private Dictionary<string, List<ImageList>>? languageImageLists;
|
||||||
|
|
@ -55,8 +54,8 @@ namespace RHLauncher
|
||||||
private void LoadLocalizedStrings()
|
private void LoadLocalizedStrings()
|
||||||
{
|
{
|
||||||
// Initialize buttons and image lists
|
// Initialize buttons and image lists
|
||||||
buttons = [ContinueButtonS1, SendEmailButton, OkButtonS2];
|
buttons = new List<Button> { ContinueButtonS1, SendEmailButton, OkButtonS2 };
|
||||||
imageLists = [imageListContinueBtn, imageListSendEmailBtn, imageListOKBtn];
|
imageLists = new List<ImageList> { imageListContinueBtn, imageListSendEmailBtn, imageListOKBtn };
|
||||||
|
|
||||||
// Initialize language-specific image lists
|
// Initialize language-specific image lists
|
||||||
languageImageLists = new Dictionary<string, List<ImageList>>
|
languageImageLists = new Dictionary<string, List<ImageList>>
|
||||||
|
|
@ -92,12 +91,12 @@ namespace RHLauncher
|
||||||
private async Task<string> SendEmailRequestAsync()
|
private async Task<string> SendEmailRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(SendPasswordCodeUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(SendPasswordCodeUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
|
|
||||||
]));
|
}));
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,23 +104,14 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
Invoke((MethodInvoker)(() =>
|
Invoke((MethodInvoker)(() =>
|
||||||
{
|
{
|
||||||
try
|
switch (response)
|
||||||
{
|
|
||||||
HttpResponse? httpResponse = JsonConvert.DeserializeObject<HttpResponse>(response);
|
|
||||||
|
|
||||||
if (httpResponse == null)
|
|
||||||
{
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + $": {LocalizedStrings.HttpResponseNull}", LocalizedStrings.Error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (httpResponse.Result)
|
|
||||||
{
|
{
|
||||||
case "EmailSent":
|
case "EmailSent":
|
||||||
SendEmailButton.Enabled = false;
|
SendEmailButton.Enabled = false;
|
||||||
resendTimer.Start();
|
resendTimer.Start();
|
||||||
break;
|
break;
|
||||||
case "ValidVerificationCode":
|
case "ValidVerificationCode":
|
||||||
|
// Hide the firs panel and show the second panel
|
||||||
Stage1Panel.Visible = false;
|
Stage1Panel.Visible = false;
|
||||||
Stage2Panel.Visible = true;
|
Stage2Panel.Visible = true;
|
||||||
EmailLabelS2.Text = EmailTextBox.Text;
|
EmailLabelS2.Text = EmailTextBox.Text;
|
||||||
|
|
@ -139,26 +129,21 @@ namespace RHLauncher
|
||||||
EmailDescLabel.Text = LocalizedStrings.AccountNotFound;
|
EmailDescLabel.Text = LocalizedStrings.AccountNotFound;
|
||||||
EmailDescLabel.ForeColor = Color.Red;
|
EmailDescLabel.ForeColor = Color.Red;
|
||||||
EmailPictureBox.Image = imageListTips.Images[0];
|
EmailPictureBox.Image = imageListTips.Images[0];
|
||||||
break;
|
return;
|
||||||
case "InvalidVerificationCode":
|
case "InvalidVerificationCode":
|
||||||
CodeDescLabel.Text = LocalizedStrings.InvalidVerificationCode;
|
CodeDescLabel.Text = LocalizedStrings.InvalidVerificationCode;
|
||||||
CodeDescLabel.ForeColor = Color.Red;
|
CodeDescLabel.ForeColor = Color.Red;
|
||||||
CodePictureBox.Image = imageListTips.Images[0];
|
CodePictureBox.Image = imageListTips.Images[0];
|
||||||
break;
|
return;
|
||||||
case "ExpiredVerificationCode":
|
case "ExpiredVerificationCode":
|
||||||
CodeDescLabel.Text = LocalizedStrings.ExpiredVerificationCode;
|
CodeDescLabel.Text = LocalizedStrings.ExpiredVerificationCode;
|
||||||
CodeDescLabel.ForeColor = Color.Red;
|
CodeDescLabel.ForeColor = Color.Red;
|
||||||
CodePictureBox.Image = imageListTips.Images[0];
|
CodePictureBox.Image = imageListTips.Images[0];
|
||||||
break;
|
return;
|
||||||
default:
|
default:
|
||||||
MsgBoxForm.Show($"{LocalizedStrings.Error}: " + httpResponse.Message, LocalizedStrings.Error);
|
MsgBoxForm.Show("Error:" + response, LocalizedStrings.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (JsonException)
|
|
||||||
{
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + $": {LocalizedStrings.HttpResponseParseError}", LocalizedStrings.Error);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,28 +167,28 @@ namespace RHLauncher
|
||||||
private async Task<string> VerifyCodeSendRequestAsync()
|
private async Task<string> VerifyCodeSendRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(VerifyCodeUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(VerifyCodeUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
new KeyValuePair<string, string>("verificationCode", CodeTextBox.Text),
|
new KeyValuePair<string, string>("verification_code", CodeTextBox.Text),
|
||||||
new KeyValuePair<string, string>("verificationCodeType", "Password"),
|
new KeyValuePair<string, string>("verification_code_type", "Password"),
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
]));
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ChangePasswordSendRequestAsync()
|
private async Task<string> ChangePasswordSendRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(ChangePasswordUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(ChangePasswordUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
new KeyValuePair<string, string>("password", PasswordTextBox.Text),
|
new KeyValuePair<string, string>("password", PasswordTextBox.Text),
|
||||||
new KeyValuePair<string, string>("verificationCode", CodeTextBox.Text),
|
new KeyValuePair<string, string>("verification_code", CodeTextBox.Text),
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
]));
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,7 +325,7 @@ namespace RHLauncher
|
||||||
string password = PasswordTextBox.Text;
|
string password = PasswordTextBox.Text;
|
||||||
|
|
||||||
// Check for minimum length and maximum length
|
// Check for minimum length and maximum length
|
||||||
if (password.Length < 8 || password.Length > 16)
|
if (password.Length < 6 || password.Length > 16)
|
||||||
{
|
{
|
||||||
PwdDescLabel.Text = LocalizedStrings.PwdDescLabelSize;
|
PwdDescLabel.Text = LocalizedStrings.PwdDescLabelSize;
|
||||||
PwdDescLabel.ForeColor = Color.Red;
|
PwdDescLabel.ForeColor = Color.Red;
|
||||||
|
|
|
||||||
40
RHLauncher.Forms/ConfigForm.Designer.cs
generated
40
RHLauncher.Forms/ConfigForm.Designer.cs
generated
|
|
@ -40,8 +40,6 @@
|
||||||
OkButton = new Button();
|
OkButton = new Button();
|
||||||
VersionLabel = new Label();
|
VersionLabel = new Label();
|
||||||
toolTip = new ToolTip(components);
|
toolTip = new ToolTip(components);
|
||||||
ServiceLabel = new Label();
|
|
||||||
cbLauncherService = new ComboBox();
|
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// CloseButton
|
// CloseButton
|
||||||
|
|
@ -90,7 +88,7 @@
|
||||||
TitleLabel.AutoEllipsis = true;
|
TitleLabel.AutoEllipsis = true;
|
||||||
TitleLabel.AutoSize = true;
|
TitleLabel.AutoSize = true;
|
||||||
TitleLabel.BackColor = Color.Transparent;
|
TitleLabel.BackColor = Color.Transparent;
|
||||||
TitleLabel.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
TitleLabel.Font = new Font("Segoe UI", 11F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
TitleLabel.ForeColor = Color.White;
|
TitleLabel.ForeColor = Color.White;
|
||||||
TitleLabel.ImageAlign = ContentAlignment.TopRight;
|
TitleLabel.ImageAlign = ContentAlignment.TopRight;
|
||||||
TitleLabel.ImeMode = ImeMode.NoControl;
|
TitleLabel.ImeMode = ImeMode.NoControl;
|
||||||
|
|
@ -127,7 +125,7 @@
|
||||||
LanguageLabel.AutoEllipsis = true;
|
LanguageLabel.AutoEllipsis = true;
|
||||||
LanguageLabel.AutoSize = true;
|
LanguageLabel.AutoSize = true;
|
||||||
LanguageLabel.BackColor = Color.Transparent;
|
LanguageLabel.BackColor = Color.Transparent;
|
||||||
LanguageLabel.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
LanguageLabel.Font = new Font("Segoe UI", 11F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
LanguageLabel.ForeColor = Color.White;
|
LanguageLabel.ForeColor = Color.White;
|
||||||
LanguageLabel.ImageAlign = ContentAlignment.TopRight;
|
LanguageLabel.ImageAlign = ContentAlignment.TopRight;
|
||||||
LanguageLabel.ImeMode = ImeMode.NoControl;
|
LanguageLabel.ImeMode = ImeMode.NoControl;
|
||||||
|
|
@ -163,7 +161,7 @@
|
||||||
VersionLabel.AutoSize = true;
|
VersionLabel.AutoSize = true;
|
||||||
VersionLabel.BackColor = Color.Transparent;
|
VersionLabel.BackColor = Color.Transparent;
|
||||||
VersionLabel.Cursor = Cursors.Hand;
|
VersionLabel.Cursor = Cursors.Hand;
|
||||||
VersionLabel.Font = new Font("Segoe UI", 10F, FontStyle.Bold);
|
VersionLabel.Font = new Font("Segoe UI", 10F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
VersionLabel.ForeColor = Color.White;
|
VersionLabel.ForeColor = Color.White;
|
||||||
VersionLabel.Location = new Point(5, 248);
|
VersionLabel.Location = new Point(5, 248);
|
||||||
VersionLabel.Name = "VersionLabel";
|
VersionLabel.Name = "VersionLabel";
|
||||||
|
|
@ -173,34 +171,6 @@
|
||||||
toolTip.SetToolTip(VersionLabel, "Click to open github repository");
|
toolTip.SetToolTip(VersionLabel, "Click to open github repository");
|
||||||
VersionLabel.Click += VersionLabel_Click;
|
VersionLabel.Click += VersionLabel_Click;
|
||||||
//
|
//
|
||||||
// ServiceLabel
|
|
||||||
//
|
|
||||||
ServiceLabel.Anchor = AnchorStyles.None;
|
|
||||||
ServiceLabel.AutoEllipsis = true;
|
|
||||||
ServiceLabel.AutoSize = true;
|
|
||||||
ServiceLabel.BackColor = Color.Transparent;
|
|
||||||
ServiceLabel.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
|
||||||
ServiceLabel.ForeColor = Color.White;
|
|
||||||
ServiceLabel.ImageAlign = ContentAlignment.TopRight;
|
|
||||||
ServiceLabel.ImeMode = ImeMode.NoControl;
|
|
||||||
ServiceLabel.Location = new Point(294, 119);
|
|
||||||
ServiceLabel.Name = "ServiceLabel";
|
|
||||||
ServiceLabel.Size = new Size(59, 20);
|
|
||||||
ServiceLabel.TabIndex = 18;
|
|
||||||
ServiceLabel.Text = "Service";
|
|
||||||
ServiceLabel.TextAlign = ContentAlignment.MiddleCenter;
|
|
||||||
//
|
|
||||||
// cbLauncherService
|
|
||||||
//
|
|
||||||
cbLauncherService.DropDownStyle = ComboBoxStyle.DropDownList;
|
|
||||||
cbLauncherService.FormattingEnabled = true;
|
|
||||||
cbLauncherService.Items.AddRange(new object[] { "JPN", "USA", "CHN", "JPN_BETA", "USA_BETA", "CHN_BETA" });
|
|
||||||
cbLauncherService.Location = new Point(254, 142);
|
|
||||||
cbLauncherService.Name = "cbLauncherService";
|
|
||||||
cbLauncherService.Size = new Size(145, 23);
|
|
||||||
cbLauncherService.TabIndex = 17;
|
|
||||||
cbLauncherService.SelectedIndexChanged += CbLauncherService_SelectedIndexChanged;
|
|
||||||
//
|
|
||||||
// ConfigForm
|
// ConfigForm
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
|
@ -208,8 +178,6 @@
|
||||||
BackColor = Color.Magenta;
|
BackColor = Color.Magenta;
|
||||||
BackgroundImage = (Image)resources.GetObject("$this.BackgroundImage");
|
BackgroundImage = (Image)resources.GetObject("$this.BackgroundImage");
|
||||||
ClientSize = new Size(646, 272);
|
ClientSize = new Size(646, 272);
|
||||||
Controls.Add(ServiceLabel);
|
|
||||||
Controls.Add(cbLauncherService);
|
|
||||||
Controls.Add(VersionLabel);
|
Controls.Add(VersionLabel);
|
||||||
Controls.Add(OkButton);
|
Controls.Add(OkButton);
|
||||||
Controls.Add(LanguageLabel);
|
Controls.Add(LanguageLabel);
|
||||||
|
|
@ -242,7 +210,5 @@
|
||||||
private Button OkButton;
|
private Button OkButton;
|
||||||
private Label VersionLabel;
|
private Label VersionLabel;
|
||||||
private ToolTip toolTip;
|
private ToolTip toolTip;
|
||||||
private Label ServiceLabel;
|
|
||||||
private ComboBox cbLauncherService;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,36 +1,27 @@
|
||||||
using RHLauncher.RHLauncher.i8n;
|
using RHLauncher.RHLauncher.i8n;
|
||||||
using RHLauncher.RHLauncher.Helper;
|
using RHLauncher.RHLauncher.Helper;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace RHLauncher
|
namespace RHLauncher
|
||||||
{
|
{
|
||||||
public partial class ConfigForm : Form
|
public partial class ConfigForm : Form
|
||||||
{
|
{
|
||||||
private readonly RegistryHandler registryHandler = new();
|
public string Url = "https://github.com/JuniorDark/RustyHearts-Launcher";
|
||||||
private readonly string? installDirectory;
|
|
||||||
|
|
||||||
private readonly string Url = "https://github.com/JuniorDark/RustyHearts-Launcher";
|
|
||||||
|
|
||||||
private bool languageChanged = false;
|
private bool languageChanged = false;
|
||||||
readonly string currentLanguageCode = Configuration.Default.Lang;
|
readonly string currentLanguageCode = Configuration.Default.Lang;
|
||||||
|
|
||||||
private bool serviceChanged = false;
|
|
||||||
readonly string currentService = Configuration.Default.Service;
|
|
||||||
|
|
||||||
public ConfigForm()
|
public ConfigForm()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
installDirectory = registryHandler.GetInstallDirectory();
|
|
||||||
string currentVersion = GetLauncherVersion.GetVersion();
|
string currentVersion = GetLauncherVersion.GetVersion();
|
||||||
cbLauncherLanguage.SelectedItem = GetLanguageName(currentLanguageCode);
|
cbLauncherLanguage.SelectedItem = GetLanguageName(currentLanguageCode);
|
||||||
cbLauncherService.SelectedItem = GetServiceName(currentService);
|
|
||||||
|
|
||||||
VersionLabel.Text = $"{LocalizedStrings.Version}: {currentVersion}";
|
VersionLabel.Text = $"{LocalizedStrings.Version}: {currentVersion}";
|
||||||
Text = LocalizedStrings.ConfigFormTitle;
|
Text = LocalizedStrings.ConfigFormTitle;
|
||||||
TitleLabel.Text = LocalizedStrings.Settings;
|
TitleLabel.Text = LocalizedStrings.Settings;
|
||||||
LanguageLabel.Text = LocalizedStrings.LauncherLanguage;
|
LanguageLabel.Text = LocalizedStrings.LauncherLanguage;
|
||||||
ServiceLabel.Text = LocalizedStrings.Service;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +61,7 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
"English" => "en",
|
"English" => "en",
|
||||||
"한국어" => "ko",
|
"한국어" => "ko",
|
||||||
_ => "en",
|
_ => "en", // default to English if not found
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,109 +71,17 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
"en" => "English",
|
"en" => "English",
|
||||||
"ko" => "한국어",
|
"ko" => "한국어",
|
||||||
_ => "English",
|
_ => "English", // default to English if not found
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Service Methods
|
|
||||||
|
|
||||||
private void CbLauncherService_SelectedIndexChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (cbLauncherService.SelectedItem is string selectedItem)
|
|
||||||
{
|
|
||||||
string selectedServiceCode = GetServiceCode(selectedItem);
|
|
||||||
if (selectedServiceCode != currentService)
|
|
||||||
{
|
|
||||||
serviceChanged = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serviceChanged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetServiceCode(string? service)
|
|
||||||
{
|
|
||||||
return service switch
|
|
||||||
{
|
|
||||||
"USA" => "usa",
|
|
||||||
"JPN" => "jpn",
|
|
||||||
"CHN" => "chn",
|
|
||||||
"USA_BETA" => "usa_beta",
|
|
||||||
"JPN_BETA" => "jpn_beta",
|
|
||||||
"CHN_BETA" => "chn_beta",
|
|
||||||
_ => "jpn",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetServiceName(string service)
|
|
||||||
{
|
|
||||||
return service switch
|
|
||||||
{
|
|
||||||
"usa" => "USA",
|
|
||||||
"jpn" => "JPN",
|
|
||||||
"chn" => "CHN",
|
|
||||||
"usa_beta" => "USA_BETA",
|
|
||||||
"jpn_beta" => "JPN_BETA",
|
|
||||||
"chn_beta" => "CHN_BETA",
|
|
||||||
_ => "JPN",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateServiceDatFile(string serviceCode)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(installDirectory))
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Compute MD5 hash
|
|
||||||
byte[] inputBytes = Encoding.UTF8.GetBytes(serviceCode);
|
|
||||||
byte[] hashBytes = System.Security.Cryptography.MD5.HashData(inputBytes);
|
|
||||||
|
|
||||||
StringBuilder sb = new();
|
|
||||||
foreach (byte b in hashBytes)
|
|
||||||
{
|
|
||||||
sb.Append(b.ToString("x2")); // Lowercase hex
|
|
||||||
}
|
|
||||||
string hashString = sb.ToString();
|
|
||||||
|
|
||||||
string fileContent = $"{hashString}\r\n\r\nSTAIRWAY GAMES";
|
|
||||||
|
|
||||||
// Write to Service.dat
|
|
||||||
string filePath = Path.Combine(installDirectory, "Service.dat");
|
|
||||||
File.WriteAllText(filePath, fileContent);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"Failed to update Service.dat: {ex.Message}", LocalizedStrings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Button Click Events
|
#region Button Click Events
|
||||||
private void OkButton_Click(object sender, EventArgs e)
|
private void OkButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
if (languageChanged)
|
||||||
{
|
{
|
||||||
if (languageChanged || serviceChanged)
|
string? selectedLanguage = cbLauncherLanguage.SelectedItem.ToString();
|
||||||
{
|
|
||||||
string? selectedService = cbLauncherService.SelectedItem?.ToString();
|
|
||||||
string serviceCode = GetServiceCode(selectedService);
|
|
||||||
if (serviceCode != null)
|
|
||||||
{
|
|
||||||
// Update the service in the INI file
|
|
||||||
Configuration.Default.Service = serviceCode;
|
|
||||||
Configuration.Default.iniFile.WriteValue("Info", "Service", serviceCode);
|
|
||||||
|
|
||||||
UpdateServiceDatFile(serviceCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
string? selectedLanguage = cbLauncherLanguage.SelectedItem?.ToString();
|
|
||||||
string languageCode = GetLanguageCode(selectedLanguage);
|
string languageCode = GetLanguageCode(selectedLanguage);
|
||||||
|
|
||||||
if (languageCode != null)
|
if (languageCode != null)
|
||||||
|
|
@ -202,19 +101,11 @@ namespace RHLauncher
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"{LocalizedStrings.Error}: {ex.Message}", LocalizedStrings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VersionLabel_Click(object sender, EventArgs e)
|
private void VersionLabel_Click(object sender, EventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA+jYAAAJNU0Z0AUkBTAIBAQMB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA+jYAAAJNU0Z0AUkBTAIBAQMB
|
||||||
AAHwAQEB8AEBARkBAAEZAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABZAMAARkDAAEBAQABIAUAARAB
|
AAHQAQEB0AEBARkBAAEZAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABZAMAARkDAAEBAQABIAUAARAB
|
||||||
JxIAARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
JxIAARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
||||||
AAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
AAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
||||||
AAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
AAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUCAAH/ARUC
|
||||||
|
|
@ -370,7 +370,7 @@
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAkGEBAAJNU0Z0AUkBTAIBAQMB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAkGEBAAJNU0Z0AUkBTAIBAQMB
|
||||||
AAHgAQIB4AECAWcBAAElAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABnAEBAgABJQMAAQEBAAEgBQAB
|
AAHAAQIBwAECAWcBAAElAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABnAEBAgABJQMAAQEBAAEgBQAB
|
||||||
MAHuEgABJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
MAHuEgABJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
||||||
/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScB
|
/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScB
|
||||||
BwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
BwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
||||||
|
|
@ -1889,7 +1889,7 @@
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAZGYBAAJNU0Z0AUkBTAIBAQMB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAZGYBAAJNU0Z0AUkBTAIBAQMB
|
||||||
AAHoAQIB6AECAWcBAAElAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABnAEBAgABJQMAAQEBAAEgBQAB
|
AAHIAQIByAECAWcBAAElAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABnAEBAgABJQMAAQEBAAEgBQAB
|
||||||
MAHuEgABJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
MAHuEgABJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
||||||
/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScB
|
/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScB
|
||||||
BwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
BwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB/wEnAQcBAAH/AScBBwEAAf8BJwEHAQAB
|
||||||
|
|
@ -3427,7 +3427,7 @@
|
||||||
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAAoYAAAEQCAIAAACiPyLtAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
|
iVBORw0KGgoAAAANSUhEUgAAAoYAAAEQCAIAAACiPyLtAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
|
||||||
DgAACw4BQL7hQQAAJ5dJREFUeF7t3d2zXOV5pnFVZTCCJJXAluJ4QmypW1Bjhw8JBoT4sqfmOJkgnNRk
|
EgAACxIB0t1+/AAAJ5dJREFUeF7t3d2zXOV5pnFVZTCCJJXAluJ4QmypW1Bjhw8JBoT4sqfmOJkgnNRk
|
||||||
bDAIpypnwY4NqTmfkyR/9KzevbV399a1Xt0XYffqg7vqKpX2T0sLzp5aq99Hfe1nH//77Tc++9Frn916
|
bDAIpypnwY4NqTmfkyR/9KzevbV399a1Xt0XYffqg7vqKpX2T0sLzp5aq99Hfe1nH//77Tc++9Frn916
|
||||||
7dOXfvKLv/zJP7w09eN/mH7zl3/1f3746qbpNxv/8b5P+NjP8NTPcHCTCQ95k0v/28Ob7P0Xv91NJjzk
|
7dOXfvKLv/zJP7w09eN/mH7zl3/1f3746qbpNxv/8b5P+NjP8NTPcHCTCQ95k0v/28Ob7P0Xv91NJjzk
|
||||||
TSakm5zht73J3sW7N7n0v33VN5nwP3eTMwxvMuEhb3Lpf3t4k73/4re7yYSHvMmEdJMz/LY32bt49yaX
|
TSakm5zht73J3sW7N7n0v33VN5nwP3eTMwxvMuEhb3Lpf3t4k73/4re7yYSHvMmEdJMz/LY32bt49yaX
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ namespace RHLauncher
|
||||||
public partial class LauncherForm : Form
|
public partial class LauncherForm : Form
|
||||||
{
|
{
|
||||||
private RegistryHandler registryHandler = new();
|
private RegistryHandler registryHandler = new();
|
||||||
private string? installDirectory;
|
public string? installDirectory;
|
||||||
private string? tempInstallDirectory;
|
public string? tempInstallDirectory;
|
||||||
private static readonly string DefaultIniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.ini");
|
private static readonly string DefaultIniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.ini");
|
||||||
private readonly IniFile _iniFile = new(DefaultIniFilePath);
|
private readonly IniFile _iniFile = new(DefaultIniFilePath);
|
||||||
private readonly string _windyCode;
|
private readonly string _windyCode;
|
||||||
|
|
@ -487,6 +487,10 @@ namespace RHLauncher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ServerStatusResponse
|
||||||
|
{
|
||||||
|
public string? Status { get; set; }
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Button Click Events
|
#region Button Click Events
|
||||||
|
|
@ -662,6 +666,10 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
Process.Start("explorer.exe", installDirectory);
|
Process.Start("explorer.exe", installDirectory);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -853,15 +861,9 @@ namespace RHLauncher
|
||||||
switch (service.ToLower())
|
switch (service.ToLower())
|
||||||
{
|
{
|
||||||
case "usa":
|
case "usa":
|
||||||
case "usa_beta":
|
|
||||||
arguments = "server=" + Configuration.Default.GateXMLUrl;
|
arguments = "server=" + Configuration.Default.GateXMLUrl;
|
||||||
break;
|
break;
|
||||||
case "jpn":
|
|
||||||
case "jpn_beta":
|
|
||||||
arguments = $"-serverurl{Configuration.Default.GateInfoUrl}";
|
|
||||||
break;
|
|
||||||
case "chn":
|
case "chn":
|
||||||
case "chn_beta":
|
|
||||||
arguments = $"-serverurl{Configuration.Default.GateInfoUrl} id={_windyCode} password={_password}";
|
arguments = $"-serverurl{Configuration.Default.GateInfoUrl} id={_windyCode} password={_password}";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -929,7 +931,7 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
foreach (FileInfo file in directoryInfo.GetFiles())
|
foreach (FileInfo file in directoryInfo.GetFiles())
|
||||||
{
|
{
|
||||||
if (!file.Name.Equals("launcher.exe", StringComparison.CurrentCultureIgnoreCase) && !file.Name.Equals("config.ini", StringComparison.CurrentCultureIgnoreCase))
|
if (file.Name.ToLower() != "launcher.exe" && file.Name.ToLower() != "config.ini")
|
||||||
{
|
{
|
||||||
file.Delete();
|
file.Delete();
|
||||||
}
|
}
|
||||||
|
|
@ -1054,8 +1056,8 @@ namespace RHLauncher
|
||||||
|
|
||||||
private static Image[] LoadImages()
|
private static Image[] LoadImages()
|
||||||
{
|
{
|
||||||
return
|
return new Image[]
|
||||||
[
|
{
|
||||||
Properties.Resources.character_select_cut_angela,
|
Properties.Resources.character_select_cut_angela,
|
||||||
Properties.Resources.character_select_cut_edgar,
|
Properties.Resources.character_select_cut_edgar,
|
||||||
Properties.Resources.character_select_cut_frantz,
|
Properties.Resources.character_select_cut_frantz,
|
||||||
|
|
@ -1065,7 +1067,7 @@ namespace RHLauncher
|
||||||
Properties.Resources.character_select_cut_natasha,
|
Properties.Resources.character_select_cut_natasha,
|
||||||
Properties.Resources.character_select_cut_roselle,
|
Properties.Resources.character_select_cut_roselle,
|
||||||
Properties.Resources.character_select_cut_tude
|
Properties.Resources.character_select_cut_tude
|
||||||
];
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HidePanel(Panel panel)
|
private static void HidePanel(Panel panel)
|
||||||
|
|
@ -1091,7 +1093,6 @@ namespace RHLauncher
|
||||||
Exception newLogEx = new(errorLog, ex);
|
Exception newLogEx = new(errorLog, ex);
|
||||||
ExceptionHandler.HandleException(newEx, newLogEx);
|
ExceptionHandler.HandleException(newEx, newLogEx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
private RegistryHandler registryHandler = new();
|
private RegistryHandler registryHandler = new();
|
||||||
|
|
||||||
private string windyCode = string.Empty;
|
public string windyCode = string.Empty;
|
||||||
private string password = string.Empty;
|
public string password = string.Empty;
|
||||||
private readonly string LoginUrl = Configuration.Default.LoginUrl;
|
public string LoginUrl = Configuration.Default.LoginUrl;
|
||||||
private readonly string Lang = Configuration.Default.Lang;
|
public string Lang = Configuration.Default.Lang;
|
||||||
private List<Button>? buttons;
|
private List<Button>? buttons;
|
||||||
private List<ImageList>? imageLists;
|
private List<ImageList>? imageLists;
|
||||||
private Dictionary<string, List<ImageList>>? languageImageLists;
|
private Dictionary<string, List<ImageList>>? languageImageLists;
|
||||||
|
|
@ -42,8 +42,8 @@ namespace RHLauncher
|
||||||
private void LoadLocalizedStrings()
|
private void LoadLocalizedStrings()
|
||||||
{
|
{
|
||||||
// Initialize buttons and image lists
|
// Initialize buttons and image lists
|
||||||
buttons = [LoginButton, RegisterButton];
|
buttons = new List<Button> { LoginButton, RegisterButton };
|
||||||
imageLists = [imageListLogin, imageListRegister];
|
imageLists = new List<ImageList> { imageListLogin, imageListRegister };
|
||||||
|
|
||||||
// Initialize language-specific image lists
|
// Initialize language-specific image lists
|
||||||
languageImageLists = new Dictionary<string, List<ImageList>>
|
languageImageLists = new Dictionary<string, List<ImageList>>
|
||||||
|
|
@ -171,12 +171,12 @@ namespace RHLauncher
|
||||||
private async Task<string> SendLoginRequestAsync()
|
private async Task<string> SendLoginRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(LoginUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(LoginUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("account", UsernameTextBox.Text),
|
new KeyValuePair<string, string>("account", UsernameTextBox.Text),
|
||||||
new KeyValuePair<string, string>("password", PasswordTextBox.Text)
|
new KeyValuePair<string, string>("password", PasswordTextBox.Text)
|
||||||
]));
|
}));
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,63 +184,52 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var loginResponse = JsonConvert.DeserializeObject<LoginResponse>(response);
|
Dictionary<string, string>? loginResponse = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
|
||||||
|
|
||||||
if (loginResponse == null)
|
if (loginResponse != null)
|
||||||
{
|
{
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + $": {LocalizedStrings.HttpResponseNull}", LocalizedStrings.Error);
|
if (loginResponse.TryGetValue("Result", out var result))
|
||||||
return;
|
{
|
||||||
}
|
switch (result)
|
||||||
|
|
||||||
switch (loginResponse.Result)
|
|
||||||
{
|
{
|
||||||
case "LoginSuccess":
|
case "LoginSuccess":
|
||||||
if (!string.IsNullOrEmpty(loginResponse.WindyCode) && !string.IsNullOrEmpty(loginResponse.Token))
|
windyCode = loginResponse["WindyCode"];
|
||||||
{
|
password = loginResponse["Token"];
|
||||||
windyCode = loginResponse.WindyCode;
|
|
||||||
password = loginResponse.Token;
|
|
||||||
progressBarLogin.Visible = false;
|
progressBarLogin.Visible = false;
|
||||||
Hide();
|
Hide();
|
||||||
notifyIcon.Visible = false;
|
notifyIcon.Visible = false;
|
||||||
LauncherForm launcherForm = new(windyCode, password);
|
LauncherForm launcherForm = new(windyCode, password);
|
||||||
launcherForm.ShowDialog();
|
launcherForm.ShowDialog();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + " Missing token or windyCode.", LocalizedStrings.Error);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "InvalidCredentials":
|
case "InvalidCredentials":
|
||||||
|
MsgBoxForm.Show(LocalizedStrings.LoginInvalidCredentials, LocalizedStrings.LoginInfoTitle);
|
||||||
|
break;
|
||||||
|
case "InvalidUsernameFormat":
|
||||||
|
MsgBoxForm.Show(LocalizedStrings.LoginInvalidUsernameFormat, LocalizedStrings.LoginInfoTitle);
|
||||||
|
break;
|
||||||
case "AccountNotFound":
|
case "AccountNotFound":
|
||||||
MsgBoxForm.Show(LocalizedStrings.LoginInvalidCredentials, LocalizedStrings.LoginInfoTitle);
|
MsgBoxForm.Show(LocalizedStrings.LoginInvalidCredentials, LocalizedStrings.LoginInfoTitle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Locked":
|
case "Locked":
|
||||||
MsgBoxForm.Show(LocalizedStrings.LoginLocked, LocalizedStrings.LoginInfoTitle);
|
MsgBoxForm.Show(LocalizedStrings.LoginLocked, LocalizedStrings.LoginInfoTitle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "TooManyAttempts":
|
case "TooManyAttempts":
|
||||||
MsgBoxForm.Show(LocalizedStrings.LoginTooManyAttempts, LocalizedStrings.LoginInfoTitle);
|
MsgBoxForm.Show(LocalizedStrings.LoginTooManyAttempts, LocalizedStrings.LoginInfoTitle);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
case "InvalidRequest":
|
MsgBoxForm.Show(LocalizedStrings.Error + result, LocalizedStrings.Error);
|
||||||
case "ServerError":
|
break;
|
||||||
if (!string.IsNullOrEmpty(loginResponse.Message))
|
}
|
||||||
{
|
|
||||||
MsgBoxForm.Show(loginResponse.Message, LocalizedStrings.Error);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + ": " + loginResponse.Result, LocalizedStrings.Error);
|
MsgBoxForm.Show(LocalizedStrings.Error + "Response does not contain a Result field.", LocalizedStrings.Error);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + ": " + loginResponse.Result, LocalizedStrings.Error);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MsgBoxForm.Show(LocalizedStrings.Error + "Failed to deserialize the response.", LocalizedStrings.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
using RHLauncher.RHLauncher.i8n;
|
using RHLauncher.RHLauncher.i8n;
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace RHLauncher
|
namespace RHLauncher
|
||||||
{
|
{
|
||||||
public partial class MsgBoxForm : Form
|
public partial class MsgBoxForm : Form
|
||||||
{
|
{
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
||||||
public new DialogResult DialogResult { get; private set; }
|
public new DialogResult DialogResult { get; private set; }
|
||||||
|
|
||||||
public MsgBoxForm()
|
public MsgBoxForm()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Newtonsoft.Json;
|
using RHLauncher.RHLauncher.Helper;
|
||||||
using RHLauncher.RHLauncher.Helper;
|
|
||||||
using RHLauncher.RHLauncher.i8n;
|
using RHLauncher.RHLauncher.i8n;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
@ -8,11 +7,11 @@ namespace RHLauncher
|
||||||
{
|
{
|
||||||
public partial class RegisterForm : Form
|
public partial class RegisterForm : Form
|
||||||
{
|
{
|
||||||
private readonly string SendCodeUrl = Configuration.Default.SendCodeUrl;
|
public string SendCodeUrl = Configuration.Default.SendCodeUrl;
|
||||||
private readonly string AgreementUrl = Configuration.Default.AgreementUrl;
|
public string AgreementUrl = Configuration.Default.AgreementUrl;
|
||||||
private readonly string VerifyCodeUrl = Configuration.Default.VerifyCodeUrl;
|
public string VerifyCodeUrl = Configuration.Default.VerifyCodeUrl;
|
||||||
private readonly string RegisterUrl = Configuration.Default.RegisterUrl;
|
public string RegisterUrl = Configuration.Default.RegisterUrl;
|
||||||
private readonly string Lang = Configuration.Default.Lang;
|
public string Lang = Configuration.Default.Lang;
|
||||||
private List<Button>? buttons;
|
private List<Button>? buttons;
|
||||||
private List<ImageList>? imageLists;
|
private List<ImageList>? imageLists;
|
||||||
private Dictionary<string, List<ImageList>>? languageImageLists;
|
private Dictionary<string, List<ImageList>>? languageImageLists;
|
||||||
|
|
@ -56,8 +55,8 @@ namespace RHLauncher
|
||||||
private void LoadLocalizedStrings()
|
private void LoadLocalizedStrings()
|
||||||
{
|
{
|
||||||
// Initialize buttons and image lists
|
// Initialize buttons and image lists
|
||||||
buttons = [ContinueButtonS1, SendEmailButton, ContinueButtonS2];
|
buttons = new List<Button> { ContinueButtonS1, SendEmailButton, ContinueButtonS2 };
|
||||||
imageLists = [imageListContinueBtn, imageListSendEmailBtn, imageListContinueBtn];
|
imageLists = new List<ImageList> { imageListContinueBtn, imageListSendEmailBtn, imageListContinueBtn };
|
||||||
|
|
||||||
// Initialize language-specific image lists
|
// Initialize language-specific image lists
|
||||||
languageImageLists = new Dictionary<string, List<ImageList>>
|
languageImageLists = new Dictionary<string, List<ImageList>>
|
||||||
|
|
@ -89,26 +88,18 @@ namespace RHLauncher
|
||||||
private async Task<string> SendEmailRequestAsync()
|
private async Task<string> SendEmailRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(SendCodeUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(SendCodeUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
|
|
||||||
]));
|
}));
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleSendEmailResponse(string response)
|
private void HandleSendEmailResponse(string response)
|
||||||
{
|
{
|
||||||
HttpResponse? httpResponse = JsonConvert.DeserializeObject<HttpResponse>(response);
|
switch (response)
|
||||||
|
|
||||||
if (httpResponse == null)
|
|
||||||
{
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + $": {LocalizedStrings.HttpResponseNull}", LocalizedStrings.Error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (httpResponse.Result)
|
|
||||||
{
|
{
|
||||||
case "EmailSent":
|
case "EmailSent":
|
||||||
SendEmailButton.Enabled = false;
|
SendEmailButton.Enabled = false;
|
||||||
|
|
@ -116,7 +107,6 @@ namespace RHLauncher
|
||||||
break;
|
break;
|
||||||
case "AccountExists":
|
case "AccountExists":
|
||||||
MsgBoxForm.Show(LocalizedStrings.AccountEmailExists, LocalizedStrings.Info);
|
MsgBoxForm.Show(LocalizedStrings.AccountEmailExists, LocalizedStrings.Info);
|
||||||
ResetSendEmailButton();
|
|
||||||
break;
|
break;
|
||||||
case "ValidVerificationCode":
|
case "ValidVerificationCode":
|
||||||
// Hide the first panel and show the second panel
|
// Hide the first panel and show the second panel
|
||||||
|
|
@ -150,66 +140,52 @@ namespace RHLauncher
|
||||||
|
|
||||||
// If the timer has finished counting down, stop the timer and enable the ResendEmailButton
|
// If the timer has finished counting down, stop the timer and enable the ResendEmailButton
|
||||||
if (secondsLeft == 0)
|
if (secondsLeft == 0)
|
||||||
{
|
|
||||||
ResetSendEmailButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetSendEmailButton()
|
|
||||||
{
|
{
|
||||||
resendTimer.Stop();
|
resendTimer.Stop();
|
||||||
SendEmailButton.Enabled = true;
|
SendEmailButton.Enabled = true;
|
||||||
TimerLabel.Text = "";
|
TimerLabel.Text = "";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<string> VerifyCodeSendRequestAsync()
|
private async Task<string> VerifyCodeSendRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(VerifyCodeUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(VerifyCodeUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
new KeyValuePair<string, string>("verificationCode", CodeTextBox.Text),
|
new KeyValuePair<string, string>("verification_code", CodeTextBox.Text),
|
||||||
new KeyValuePair<string, string>("verificationCodeType", "Account"),
|
new KeyValuePair<string, string>("verification_code_type", "Account"),
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
]));
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> SendRequestAsync()
|
private async Task<string> SendRequestAsync()
|
||||||
{
|
{
|
||||||
using HttpClient client = new();
|
using HttpClient client = new();
|
||||||
using HttpResponseMessage response = await client.PostAsync(RegisterUrl, new FormUrlEncodedContent(
|
using HttpResponseMessage response = await client.PostAsync(RegisterUrl, new FormUrlEncodedContent(new[]
|
||||||
[
|
{
|
||||||
new KeyValuePair<string, string>("username", UsernameTextBox.Text),
|
new KeyValuePair<string, string>("windyCode", UsernameTextBox.Text),
|
||||||
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
new KeyValuePair<string, string>("email", EmailTextBox.Text),
|
||||||
new KeyValuePair<string, string>("password", PasswordTextBox.Text),
|
new KeyValuePair<string, string>("password", PasswordTextBox.Text)
|
||||||
new KeyValuePair<string, string>("verificationCode", CodeTextBox.Text)
|
}));
|
||||||
]));
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleResponse(string response)
|
private void HandleResponse(string response)
|
||||||
{
|
{
|
||||||
HttpResponse? accounResponse = JsonConvert.DeserializeObject<HttpResponse>(response);
|
switch (response)
|
||||||
|
|
||||||
if (accounResponse == null)
|
|
||||||
{
|
{
|
||||||
MsgBoxForm.Show(LocalizedStrings.Error + $": {LocalizedStrings.HttpResponseNull}", LocalizedStrings.Error);
|
case "Success":
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (accounResponse.Result)
|
|
||||||
{
|
|
||||||
case "AccountCreated":
|
|
||||||
MsgBoxForm.Show(LocalizedStrings.AccountCreateSuccess, LocalizedStrings.RegisterWindow);
|
MsgBoxForm.Show(LocalizedStrings.AccountCreateSuccess, LocalizedStrings.RegisterWindow);
|
||||||
Close();
|
Close();
|
||||||
break;
|
break;
|
||||||
case "EmailExists":
|
case "AccountExists":
|
||||||
MsgBoxForm.Show(LocalizedStrings.AccountEmailExists, LocalizedStrings.Info);
|
MsgBoxForm.Show(LocalizedStrings.AccountExists, LocalizedStrings.Info);
|
||||||
break;
|
break;
|
||||||
case "UsernameExists":
|
case "WindyCodeExists":
|
||||||
MsgBoxForm.Show(LocalizedStrings.WindyCodeExists, LocalizedStrings.Error);
|
MsgBoxForm.Show(LocalizedStrings.WindyCodeExists, LocalizedStrings.Error);
|
||||||
break;
|
break;
|
||||||
case "InvalidUserNameFormat":
|
case "InvalidUserNameFormat":
|
||||||
|
|
@ -219,7 +195,7 @@ namespace RHLauncher
|
||||||
MsgBoxForm.Show(LocalizedStrings.InvalidEmailFormat, LocalizedStrings.Error);
|
MsgBoxForm.Show(LocalizedStrings.InvalidEmailFormat, LocalizedStrings.Error);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MsgBoxForm.Show($"{LocalizedStrings.Error}: " + accounResponse.Message, LocalizedStrings.Error);
|
MsgBoxForm.Show($"{LocalizedStrings.Error}: {response}", LocalizedStrings.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,7 +375,7 @@ namespace RHLauncher
|
||||||
string password = PasswordTextBox.Text;
|
string password = PasswordTextBox.Text;
|
||||||
|
|
||||||
// Check for minimum length and maximum length
|
// Check for minimum length and maximum length
|
||||||
if (password.Length < 8 || password.Length > 16)
|
if (password.Length < 6 || password.Length > 16)
|
||||||
{
|
{
|
||||||
PwdDescLabel.Text = LocalizedStrings.PwdDescLabelSize;
|
PwdDescLabel.Text = LocalizedStrings.PwdDescLabelSize;
|
||||||
PwdDescLabel.ForeColor = Color.Red;
|
PwdDescLabel.ForeColor = Color.Red;
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,20 @@ public class Configuration
|
||||||
|
|
||||||
public Configuration()
|
public Configuration()
|
||||||
{
|
{
|
||||||
string apiUrl = iniFile.ReadValue("Info", "ServerURL");
|
string apiUrl = iniFile.ReadValue("Info", "LoginURL");
|
||||||
|
|
||||||
//Client endpoints
|
//Client endpoints
|
||||||
GateXMLUrl = $"{apiUrl}/launcher/GetGatewayAction";
|
GateXMLUrl = $"{apiUrl}/serverApi/gateway";
|
||||||
GateInfoUrl = $"{apiUrl}/launcher/GetGatewayAction/info";
|
GateInfoUrl = $"{apiUrl}/serverApi/gateway/info";
|
||||||
GateStatusUrl = $"{apiUrl}/launcher/GetGatewayAction/status";
|
GateStatusUrl = $"{apiUrl}/serverApi/gateway/status";
|
||||||
|
|
||||||
//Launcher endpoints
|
//Launcher endpoints
|
||||||
LoginUrl = $"{apiUrl}/launcher/LoginAction";
|
LoginUrl = $"{apiUrl}/accountApi/login";
|
||||||
RegisterUrl = $"{apiUrl}/launcher/SignupAction";
|
RegisterUrl = $"{apiUrl}/accountApi/register";
|
||||||
SendCodeUrl = $"{apiUrl}/launcher/SendVerificationEmailAction";
|
SendCodeUrl = $"{apiUrl}/accountApi/sendVerificationEmail";
|
||||||
VerifyCodeUrl = $"{apiUrl}/launcher/VerifyCodeAction";
|
VerifyCodeUrl = $"{apiUrl}/accountApi/codeVerification";
|
||||||
SendPasswordCodeUrl = $"{apiUrl}/launcher/SendPasswordResetEmailAction";
|
SendPasswordCodeUrl = $"{apiUrl}/accountApi/sendPasswordResetEmail";
|
||||||
ChangePasswordUrl = $"{apiUrl}/launcher/ResetPasswordAction";
|
ChangePasswordUrl = $"{apiUrl}/accountApi/changePassword";
|
||||||
LauncherNewsUrl = $"{apiUrl}/launcher/news";
|
LauncherNewsUrl = $"{apiUrl}/launcher/news";
|
||||||
AgreementUrl = $"{apiUrl}/launcher/agreement";
|
AgreementUrl = $"{apiUrl}/launcher/agreement";
|
||||||
|
|
||||||
|
|
@ -36,12 +36,12 @@ public class Configuration
|
||||||
DownloadUpdateFileUrl = $"{apiUrl}/launcher/patch";
|
DownloadUpdateFileUrl = $"{apiUrl}/launcher/patch";
|
||||||
|
|
||||||
//Launcher update endpoints
|
//Launcher update endpoints
|
||||||
GetLauncherVersion = $"{apiUrl}/launcherAction/getLauncherVersion";
|
GetLauncherVersion = $"{apiUrl}/launcherApi/launcherUpdater/getLauncherVersion";
|
||||||
UpdateLauncherVersion = $"{apiUrl}/launcherAction/updateLauncherVersion";
|
UpdateLauncherVersion = $"{apiUrl}/launcherApi/launcherUpdater/updateLauncherVersion";
|
||||||
|
|
||||||
//Launcher settings
|
//Launcher settings
|
||||||
Lang = iniFile.ReadValue("Launcher", "Lang");
|
string lang = iniFile.ReadValue("Launcher", "Lang");
|
||||||
Service = iniFile.ReadValue("Info", "Service");
|
Lang = lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GateXMLUrl { get; set; }
|
public string GateXMLUrl { get; set; }
|
||||||
|
|
@ -62,6 +62,5 @@ public class Configuration
|
||||||
public string ClientPartsListUrl { get; set; }
|
public string ClientPartsListUrl { get; set; }
|
||||||
public string DownloadClientPartUrl { get; set; }
|
public string DownloadClientPartUrl { get; set; }
|
||||||
public string Lang { get; set; }
|
public string Lang { get; set; }
|
||||||
public string Service { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace RHLauncher.RHLauncher.Helper;
|
|
||||||
|
|
||||||
public class HttpResponse
|
|
||||||
{
|
|
||||||
[JsonProperty("success")]
|
|
||||||
public string? Success { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("result")]
|
|
||||||
public string? Result { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("message")]
|
|
||||||
public string? Message { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LoginResponse
|
|
||||||
{
|
|
||||||
[JsonProperty("result")]
|
|
||||||
public string? Result { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("token")]
|
|
||||||
public string? Token { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("windyCode")]
|
|
||||||
public string? WindyCode { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("message")]
|
|
||||||
public string? Message { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ServerStatusResponse
|
|
||||||
{
|
|
||||||
[JsonProperty("status")]
|
|
||||||
public string? Status { get; set; }
|
|
||||||
}
|
|
||||||
|
|
@ -21,9 +21,9 @@ namespace RHLauncher.RHLauncher.Helper
|
||||||
if (!File.Exists(_iniFilePath))
|
if (!File.Exists(_iniFilePath))
|
||||||
{
|
{
|
||||||
//Default api url
|
//Default api url
|
||||||
WritePrivateProfileString("Info", "ServerURL", "http://127.0.0.1", _iniFilePath);
|
WritePrivateProfileString("Info", "LoginURL", "http://localhost:3000", _iniFilePath);
|
||||||
//Default client service
|
//Default client service
|
||||||
WritePrivateProfileString("Info", "Service", "jpn", _iniFilePath);
|
WritePrivateProfileString("Info", "Service", "usa", _iniFilePath);
|
||||||
//Default launcher language
|
//Default launcher language
|
||||||
WritePrivateProfileString("Launcher", "Lang", "en", _iniFilePath);
|
WritePrivateProfileString("Launcher", "Lang", "en", _iniFilePath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using RHLauncher.RHLauncher.Helper;
|
using Ionic.Zip;
|
||||||
|
using RHLauncher.RHLauncher.Helper;
|
||||||
using RHLauncher.RHLauncher.i8n;
|
using RHLauncher.RHLauncher.i8n;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace RHLauncher.RHLauncher.Http
|
namespace RHLauncher.RHLauncher.Http
|
||||||
|
|
@ -51,10 +51,10 @@ namespace RHLauncher.RHLauncher.Http
|
||||||
Directory.CreateDirectory(downloadDir);
|
Directory.CreateDirectory(downloadDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> filesToBeDownloaded = [];
|
List<string> filesToBeDownloaded = new();
|
||||||
long totalBytesToDownload = 0L;
|
long totalBytesToDownload = 0L;
|
||||||
|
|
||||||
List<string> lines = [.. filelistText.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries)];
|
List<string> lines = filelistText.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
int totalLines = lines.Count;
|
int totalLines = lines.Count;
|
||||||
int checkedFiles = 0;
|
int checkedFiles = 0;
|
||||||
|
|
||||||
|
|
@ -146,17 +146,14 @@ namespace RHLauncher.RHLauncher.Http
|
||||||
|
|
||||||
private static async Task<string> UnzipFilesAsync(string sourceDirectory, string destinationDirectory, IProgress<ProgressReport> progress, CancellationToken cancellationToken)
|
private static async Task<string> UnzipFilesAsync(string sourceDirectory, string destinationDirectory, IProgress<ProgressReport> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
string[] fileEntries = [.. Directory.GetFiles(sourceDirectory, "*.zip.*").OrderBy(f => f)];
|
string[] fileEntries = Directory.GetFiles(sourceDirectory, "*.zip.*").OrderBy(f => f).ToArray();
|
||||||
string rhExeDirectoryPath = "";
|
string rhExeDirectoryPath = "";
|
||||||
|
|
||||||
// Calculate total uncompressed size of all files in all zip archives
|
// Calculate total uncompressed size of all files in all zip archives
|
||||||
long totalUncompressedSize = fileEntries.Sum(file =>
|
long totalUncompressedSize = fileEntries.Sum(file =>
|
||||||
{
|
{
|
||||||
using FileStream fs = new(file, FileMode.Open, FileAccess.Read);
|
using ZipFile zip = ZipFile.Read(file);
|
||||||
using ZipArchive zip = new(fs, ZipArchiveMode.Read);
|
return zip.Entries.Sum(entry => entry.UncompressedSize);
|
||||||
|
|
||||||
static long entryLength(ZipArchiveEntry entry) => entry.Length;
|
|
||||||
return zip.Entries.Sum(entryLength);
|
|
||||||
});
|
});
|
||||||
long totalExtracted = 0;
|
long totalExtracted = 0;
|
||||||
|
|
||||||
|
|
@ -166,27 +163,26 @@ namespace RHLauncher.RHLauncher.Http
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
using FileStream fs = new(file, FileMode.Open, FileAccess.Read);
|
using ZipFile zip = ZipFile.Read(file);
|
||||||
using ZipArchive zip = new(fs, ZipArchiveMode.Read);
|
foreach (var entry in zip)
|
||||||
foreach (var entry in zip.Entries)
|
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
string destinationPath = Path.Combine(destinationDirectory, entry.FullName);
|
string destinationPath = Path.Combine(destinationDirectory, entry.FileName);
|
||||||
string? directoryPath = Path.GetDirectoryName(destinationPath);
|
string? directoryPath = Path.GetDirectoryName(destinationPath);
|
||||||
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
|
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(directoryPath);
|
Directory.CreateDirectory(directoryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.ExtractToFile(destinationPath, overwrite: true);
|
entry.Extract(destinationDirectory, ExtractExistingFileAction.OverwriteSilently);
|
||||||
totalExtracted += entry.Length;
|
totalExtracted += entry.UncompressedSize;
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
ProgressReporter.ReportUnzipProgress(progress, totalExtracted, totalUncompressedSize, cancellationToken);
|
ProgressReporter.ReportUnzipProgress(progress, totalExtracted, totalUncompressedSize, cancellationToken);
|
||||||
|
|
||||||
// Check if the current entry is "rustyhearts.exe" and store its directory path
|
// Check if the current entry is "rustyhearts.exe" and store its directory path
|
||||||
if (entry.FullName.EndsWith("rustyhearts.exe", StringComparison.OrdinalIgnoreCase))
|
if (entry.FileName.EndsWith("rustyhearts.exe", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
rhExeDirectoryPath = Path.GetDirectoryName(destinationPath) ?? "";
|
rhExeDirectoryPath = Path.GetDirectoryName(destinationPath) ?? "";
|
||||||
}
|
}
|
||||||
|
|
@ -221,5 +217,7 @@ namespace RHLauncher.RHLauncher.Http
|
||||||
throw new FileNotFoundException($"{LocalizedStrings.ClientFolderExeErrorMessage}");
|
throw new FileNotFoundException($"{LocalizedStrings.ClientFolderExeErrorMessage}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System.IO.Compression;
|
using Ionic.Zlib;
|
||||||
using RHLauncher.RHLauncher.Helper;
|
using RHLauncher.RHLauncher.Helper;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace RHLauncher.RHLauncher.PCK
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using MemoryStream compressedStream = new(compressedBytes);
|
using MemoryStream compressedStream = new(compressedBytes);
|
||||||
using ZLibStream deflateStream = new(compressedStream, CompressionMode.Decompress);
|
using ZlibStream deflateStream = new(compressedStream, CompressionMode.Decompress);
|
||||||
using MemoryStream decompressedStream = new();
|
using MemoryStream decompressedStream = new();
|
||||||
deflateStream.CopyTo(decompressedStream);
|
deflateStream.CopyTo(decompressedStream);
|
||||||
decompressedStream.Seek(0, SeekOrigin.Begin);
|
decompressedStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net9.0-windows</TargetFramework>
|
<TargetFramework>net7.0-windows7.0</TargetFramework>
|
||||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
<AssemblyName>Launcher</AssemblyName>
|
<AssemblyName>Launcher</AssemblyName>
|
||||||
<Description>Rusty Hearts Launcher</Description>
|
<Description>Rusty Hearts Launcher</Description>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<AssemblyVersion>1.4.0</AssemblyVersion>
|
<AssemblyVersion>1.2.0</AssemblyVersion>
|
||||||
<FileVersion>1.4.0</FileVersion>
|
<FileVersion>1.2.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|
@ -36,9 +36,10 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
|
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
||||||
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="WindowsAPICodePack" Version="8.0.6" />
|
<PackageReference Include="WindowsAPICodePack" Version="7.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
31
RHLauncher.i8n/LocalizedStrings.Designer.cs
generated
31
RHLauncher.i8n/LocalizedStrings.Designer.cs
generated
|
|
@ -438,24 +438,6 @@ namespace RHLauncher.RHLauncher.i8n {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Failed to process server response..
|
|
||||||
/// </summary>
|
|
||||||
public static string HttpResponseNull {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("HttpResponseNull", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Failed to parse server response..
|
|
||||||
/// </summary>
|
|
||||||
public static string HttpResponseParseError {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("HttpResponseParseError", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Info.
|
/// Looks up a localized string similar to Info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -754,7 +736,7 @@ namespace RHLauncher.RHLauncher.i8n {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to 8-16 characters.
|
/// Looks up a localized string similar to 6-16 characters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string NewPasswordDesc {
|
public static string NewPasswordDesc {
|
||||||
get {
|
get {
|
||||||
|
|
@ -844,7 +826,7 @@ namespace RHLauncher.RHLauncher.i8n {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Password must be between 8-16 characters!.
|
/// Looks up a localized string similar to Password must be between 6-16 characters!.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string PwdDescLabelSize {
|
public static string PwdDescLabelSize {
|
||||||
get {
|
get {
|
||||||
|
|
@ -996,15 +978,6 @@ namespace RHLauncher.RHLauncher.i8n {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Service.
|
|
||||||
/// </summary>
|
|
||||||
public static string Service {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("Service", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Could not find Service.dat. Please check if the Install Directory is correct..
|
/// Looks up a localized string similar to Could not find Service.dat. Please check if the Install Directory is correct..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -243,12 +243,6 @@
|
||||||
<data name="GameSettings" xml:space="preserve">
|
<data name="GameSettings" xml:space="preserve">
|
||||||
<value>게임 설정</value>
|
<value>게임 설정</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="HttpResponseNull" xml:space="preserve">
|
|
||||||
<value>서버 응답을 처리하지 못했습니다.</value>
|
|
||||||
</data>
|
|
||||||
<data name="HttpResponseParseError" xml:space="preserve">
|
|
||||||
<value>서버 응답을 구문 분석하는 데 실패했습니다.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Info" xml:space="preserve">
|
<data name="Info" xml:space="preserve">
|
||||||
<value>정보</value>
|
<value>정보</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -349,7 +343,7 @@
|
||||||
<value>새 비밀번호를 입력하세요</value>
|
<value>새 비밀번호를 입력하세요</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NewPasswordDesc" xml:space="preserve">
|
<data name="NewPasswordDesc" xml:space="preserve">
|
||||||
<value>8~16자</value>
|
<value>6~16자</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>아니요</value>
|
<value>아니요</value>
|
||||||
|
|
@ -379,7 +373,7 @@
|
||||||
<value>비밀번호는 비워둘 수 없습니다!</value>
|
<value>비밀번호는 비워둘 수 없습니다!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PwdDescLabelSize" xml:space="preserve">
|
<data name="PwdDescLabelSize" xml:space="preserve">
|
||||||
<value>비밀번호는 8~16자 사이여야 합니다!</value>
|
<value>비밀번호는 6~16자 사이여야 합니다!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PwdStrengthLabelMedium" xml:space="preserve">
|
<data name="PwdStrengthLabelMedium" xml:space="preserve">
|
||||||
<value>매질</value>
|
<value>매질</value>
|
||||||
|
|
@ -429,9 +423,6 @@
|
||||||
<data name="ServerOffline" xml:space="preserve">
|
<data name="ServerOffline" xml:space="preserve">
|
||||||
<value>게임 서버에 연결할 수 없습니다.</value>
|
<value>게임 서버에 연결할 수 없습니다.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Service" xml:space="preserve">
|
|
||||||
<value>서비스</value>
|
|
||||||
</data>
|
|
||||||
<data name="ServiceDatFileMissing" xml:space="preserve">
|
<data name="ServiceDatFileMissing" xml:space="preserve">
|
||||||
<value>Service.dat를 찾을 수 없습니다. 설치 디렉터리가 올바른지 확인하세요.</value>
|
<value>Service.dat를 찾을 수 없습니다. 설치 디렉터리가 올바른지 확인하세요.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -243,12 +243,6 @@
|
||||||
<data name="GameSettings" xml:space="preserve">
|
<data name="GameSettings" xml:space="preserve">
|
||||||
<value>Game Settings</value>
|
<value>Game Settings</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="HttpResponseNull" xml:space="preserve">
|
|
||||||
<value>Failed to process server response.</value>
|
|
||||||
</data>
|
|
||||||
<data name="HttpResponseParseError" xml:space="preserve">
|
|
||||||
<value>Failed to parse server response.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Info" xml:space="preserve">
|
<data name="Info" xml:space="preserve">
|
||||||
<value>Info</value>
|
<value>Info</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -349,7 +343,7 @@
|
||||||
<value>Enter the new password</value>
|
<value>Enter the new password</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NewPasswordDesc" xml:space="preserve">
|
<data name="NewPasswordDesc" xml:space="preserve">
|
||||||
<value>8-16 characters</value>
|
<value>6-16 characters</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="No" xml:space="preserve">
|
<data name="No" xml:space="preserve">
|
||||||
<value>No</value>
|
<value>No</value>
|
||||||
|
|
@ -379,7 +373,7 @@
|
||||||
<value>Password cannot be empty!</value>
|
<value>Password cannot be empty!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PwdDescLabelSize" xml:space="preserve">
|
<data name="PwdDescLabelSize" xml:space="preserve">
|
||||||
<value>Password must be between 8-16 characters!</value>
|
<value>Password must be between 6-16 characters!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PwdStrengthLabelMedium" xml:space="preserve">
|
<data name="PwdStrengthLabelMedium" xml:space="preserve">
|
||||||
<value>Medium</value>
|
<value>Medium</value>
|
||||||
|
|
@ -429,9 +423,6 @@
|
||||||
<data name="ServerOffline" xml:space="preserve">
|
<data name="ServerOffline" xml:space="preserve">
|
||||||
<value>Cannot connect to the game server.</value>
|
<value>Cannot connect to the game server.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Service" xml:space="preserve">
|
|
||||||
<value>Service</value>
|
|
||||||
</data>
|
|
||||||
<data name="ServiceDatFileMissing" xml:space="preserve">
|
<data name="ServiceDatFileMissing" xml:space="preserve">
|
||||||
<value>Could not find Service.dat. Please check if the Install Directory is correct.</value>
|
<value>Could not find Service.dat. Please check if the Install Directory is correct.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue