baseline: OpenMU upstream b5a0961 (fresh source)
This commit is contained in:
21
src/ClientLauncher/ClientColorDepth.cs
Normal file
21
src/ClientLauncher/ClientColorDepth.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// <copyright file="ClientColorDepth.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// The available color depths for the mu online client.
|
||||
/// </summary>
|
||||
public enum ClientColorDepth
|
||||
{
|
||||
/// <summary>
|
||||
/// The 16 bit color depth.
|
||||
/// </summary>
|
||||
Bit16 = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The 32 bit color depth.
|
||||
/// </summary>
|
||||
Bit32 = 1,
|
||||
}
|
||||
27
src/ClientLauncher/ClientLanguage.cs
Normal file
27
src/ClientLauncher/ClientLanguage.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
// <copyright file="ClientLanguage.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// The available mu online client languages.
|
||||
/// Only applicable for the global (english) client.
|
||||
/// </summary>
|
||||
public enum ClientLanguage
|
||||
{
|
||||
/// <summary>
|
||||
/// The english language.
|
||||
/// </summary>
|
||||
English = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The portuguese language.
|
||||
/// </summary>
|
||||
Portuguese = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The spanish language.
|
||||
/// </summary>
|
||||
Spanish = 2,
|
||||
}
|
||||
37
src/ClientLauncher/ClientLanguageExtensions.cs
Normal file
37
src/ClientLauncher/ClientLanguageExtensions.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// <copyright file="ClientLanguageExtensions.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// Extensions for <see cref="ClientLanguage"/>.
|
||||
/// </summary>
|
||||
public static class ClientLanguageExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// The language keys used in the registry.
|
||||
/// </summary>
|
||||
private static readonly string[] LanguageKeys = { "Eng", "Por", "Spn" };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string which should be set in the registry for the given <see cref="ClientLanguage"/>.
|
||||
/// </summary>
|
||||
/// <param name="clientLanguage">The client language.</param>
|
||||
/// <returns>The string which should be set in the registry for the given <see cref="ClientLanguage"/>.</returns>
|
||||
public static string? GetString(this ClientLanguage clientLanguage)
|
||||
{
|
||||
var index = (int)clientLanguage;
|
||||
return index < LanguageKeys.Length ? LanguageKeys[index] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ClientLanguage"/> based on the given key, which is set in the registry.
|
||||
/// </summary>
|
||||
/// <param name="languageKey">The language key.</param>
|
||||
/// <returns>The <see cref="ClientLanguage"/> based on the given key, which is set in the registry.</returns>
|
||||
public static ClientLanguage GetLanguage(this string languageKey)
|
||||
{
|
||||
return (ClientLanguage)Array.IndexOf(LanguageKeys, languageKey);
|
||||
}
|
||||
}
|
||||
41
src/ClientLauncher/ClientResolution.cs
Normal file
41
src/ClientLauncher/ClientResolution.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// <copyright file="ClientResolution.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// The available mu online client screen resolutions.
|
||||
/// </summary>
|
||||
public class ClientResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientResolution"/> class.
|
||||
/// </summary>
|
||||
public ClientResolution()
|
||||
{
|
||||
this.Index = 0;
|
||||
this.Caption = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientResolution"/> class.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="caption">The caption.</param>
|
||||
public ClientResolution(int index, string caption)
|
||||
{
|
||||
this.Index = index;
|
||||
this.Caption = caption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index.
|
||||
/// </summary>
|
||||
public int Index { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the caption.
|
||||
/// </summary>
|
||||
public string Caption { get; init; }
|
||||
}
|
||||
94
src/ClientLauncher/ClientSettings.cs
Normal file
94
src/ClientLauncher/ClientSettings.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
// <copyright file="ClientSettings.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Win32;
|
||||
|
||||
/// <summary>
|
||||
/// This class allows to read and write the game client settings in the registry.
|
||||
/// </summary>
|
||||
internal class ClientSettings
|
||||
{
|
||||
private const string DefaultLanguage = "Eng";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client color depth.
|
||||
/// </summary>
|
||||
public ClientColorDepth ClientColorDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is music enabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is music enabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsMusicEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is sound enabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is sound enabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSoundEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the volume level.
|
||||
/// </summary>
|
||||
public int VolumeLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is window mode active.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is window mode active; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsWindowModeActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resolution.
|
||||
/// </summary>
|
||||
public int ResolutionIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language selection.
|
||||
/// </summary>
|
||||
public ClientLanguage LangSelection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings from the windows registry.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public void Load()
|
||||
{
|
||||
using var currentUserKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32);
|
||||
using var key = currentUserKey.CreateSubKey(@"SOFTWARE\WebZen\Mu\Config");
|
||||
this.ClientColorDepth = (ClientColorDepth)(key.GetValue("ColorDepth") ?? 0);
|
||||
this.IsMusicEnabled = (int)(key.GetValue("MusicOnOff") ?? 0) == 1;
|
||||
this.IsSoundEnabled = (int)(key.GetValue("SoundOnOff") ?? 0) == 1;
|
||||
this.VolumeLevel = (int)(key.GetValue("VolumeLevel") ?? 0);
|
||||
this.IsWindowModeActive = (int)(key.GetValue("WindowMode") ?? 0) == 1;
|
||||
this.ResolutionIndex = (int)(key.GetValue("Resolution") ?? 0);
|
||||
this.LangSelection = ((string?)key.GetValue("LangSelection") ?? DefaultLanguage).GetLanguage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the settings at the windows registry.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public void Save()
|
||||
{
|
||||
using var currentUserKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32);
|
||||
using var key = currentUserKey.CreateSubKey(@"SOFTWARE\WebZen\Mu\Config");
|
||||
key.SetValue("ColorDepth", this.ClientColorDepth, RegistryValueKind.DWord);
|
||||
key.SetValue("MusicOnOff", this.IsMusicEnabled, RegistryValueKind.DWord);
|
||||
key.SetValue("SoundOnOff", this.IsSoundEnabled, RegistryValueKind.DWord);
|
||||
key.SetValue("VolumeLevel", this.VolumeLevel, RegistryValueKind.DWord);
|
||||
key.SetValue("WindowMode", this.IsWindowModeActive, RegistryValueKind.DWord);
|
||||
key.SetValue("Resolution", this.ResolutionIndex, RegistryValueKind.DWord);
|
||||
key.SetValue("LangSelection", this.LangSelection.GetString() ?? DefaultLanguage, RegistryValueKind.String);
|
||||
}
|
||||
}
|
||||
248
src/ClientLauncher/ClientSettingsDialog.Designer.cs
generated
Normal file
248
src/ClientLauncher/ClientSettingsDialog.Designer.cs
generated
Normal file
@@ -0,0 +1,248 @@
|
||||
namespace MUnique.OpenMU.ClientLauncher
|
||||
{
|
||||
partial class ClientSettingsDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
windowModeCheckBox = new System.Windows.Forms.CheckBox();
|
||||
musicActiveCheckBox = new System.Windows.Forms.CheckBox();
|
||||
soundActiveCheckBox = new System.Windows.Forms.CheckBox();
|
||||
groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
soundVolumeTrackBar = new System.Windows.Forms.TrackBar();
|
||||
groupBox4 = new System.Windows.Forms.GroupBox();
|
||||
clientLanguageComboBox = new System.Windows.Forms.ComboBox();
|
||||
saveButton = new System.Windows.Forms.Button();
|
||||
closeButton = new System.Windows.Forms.Button();
|
||||
groupBox5 = new System.Windows.Forms.GroupBox();
|
||||
clientResolutionComboBox = new System.Windows.Forms.ComboBox();
|
||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
colorDepthComboBox = new System.Windows.Forms.ComboBox();
|
||||
groupBox3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)soundVolumeTrackBar).BeginInit();
|
||||
groupBox4.SuspendLayout();
|
||||
groupBox5.SuspendLayout();
|
||||
groupBox1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// windowModeCheckBox
|
||||
//
|
||||
windowModeCheckBox.AutoSize = true;
|
||||
windowModeCheckBox.Location = new System.Drawing.Point(22, 286);
|
||||
windowModeCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
windowModeCheckBox.Name = "windowModeCheckBox";
|
||||
windowModeCheckBox.Size = new System.Drawing.Size(104, 19);
|
||||
windowModeCheckBox.TabIndex = 0;
|
||||
windowModeCheckBox.Text = "Window Mode";
|
||||
windowModeCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// musicActiveCheckBox
|
||||
//
|
||||
musicActiveCheckBox.AutoSize = true;
|
||||
musicActiveCheckBox.Location = new System.Drawing.Point(136, 22);
|
||||
musicActiveCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
musicActiveCheckBox.Name = "musicActiveCheckBox";
|
||||
musicActiveCheckBox.Size = new System.Drawing.Size(125, 19);
|
||||
musicActiveCheckBox.TabIndex = 3;
|
||||
musicActiveCheckBox.Text = "Background Music";
|
||||
musicActiveCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// soundActiveCheckBox
|
||||
//
|
||||
soundActiveCheckBox.AutoSize = true;
|
||||
soundActiveCheckBox.Location = new System.Drawing.Point(10, 22);
|
||||
soundActiveCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
soundActiveCheckBox.Name = "soundActiveCheckBox";
|
||||
soundActiveCheckBox.Size = new System.Drawing.Size(98, 19);
|
||||
soundActiveCheckBox.TabIndex = 4;
|
||||
soundActiveCheckBox.Text = "Sound Effects";
|
||||
soundActiveCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
groupBox3.Controls.Add(soundVolumeTrackBar);
|
||||
groupBox3.Controls.Add(musicActiveCheckBox);
|
||||
groupBox3.Controls.Add(soundActiveCheckBox);
|
||||
groupBox3.Location = new System.Drawing.Point(19, 115);
|
||||
groupBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox3.Name = "groupBox3";
|
||||
groupBox3.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox3.Size = new System.Drawing.Size(315, 111);
|
||||
groupBox3.TabIndex = 7;
|
||||
groupBox3.TabStop = false;
|
||||
groupBox3.Text = "Sound";
|
||||
//
|
||||
// soundVolumeTrackBar
|
||||
//
|
||||
soundVolumeTrackBar.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
soundVolumeTrackBar.Location = new System.Drawing.Point(4, 63);
|
||||
soundVolumeTrackBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
soundVolumeTrackBar.Name = "soundVolumeTrackBar";
|
||||
soundVolumeTrackBar.Size = new System.Drawing.Size(307, 45);
|
||||
soundVolumeTrackBar.TabIndex = 5;
|
||||
//
|
||||
// groupBox4
|
||||
//
|
||||
groupBox4.Controls.Add(clientLanguageComboBox);
|
||||
groupBox4.Location = new System.Drawing.Point(19, 233);
|
||||
groupBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox4.Name = "groupBox4";
|
||||
groupBox4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox4.Size = new System.Drawing.Size(315, 46);
|
||||
groupBox4.TabIndex = 8;
|
||||
groupBox4.TabStop = false;
|
||||
groupBox4.Text = "Language";
|
||||
//
|
||||
// clientLanguageComboBox
|
||||
//
|
||||
clientLanguageComboBox.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
clientLanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
clientLanguageComboBox.FormattingEnabled = true;
|
||||
clientLanguageComboBox.Items.AddRange(new object[] { "English", "Portuguese", "Spanish" });
|
||||
clientLanguageComboBox.Location = new System.Drawing.Point(4, 20);
|
||||
clientLanguageComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
clientLanguageComboBox.Name = "clientLanguageComboBox";
|
||||
clientLanguageComboBox.Size = new System.Drawing.Size(307, 23);
|
||||
clientLanguageComboBox.TabIndex = 0;
|
||||
//
|
||||
// saveButton
|
||||
//
|
||||
saveButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
saveButton.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
saveButton.Location = new System.Drawing.Point(153, 321);
|
||||
saveButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
saveButton.Name = "saveButton";
|
||||
saveButton.Size = new System.Drawing.Size(88, 27);
|
||||
saveButton.TabIndex = 9;
|
||||
saveButton.Text = "OK";
|
||||
saveButton.UseVisualStyleBackColor = true;
|
||||
saveButton.Click += SaveButtonClick;
|
||||
//
|
||||
// closeButton
|
||||
//
|
||||
closeButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
closeButton.Location = new System.Drawing.Point(247, 321);
|
||||
closeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
closeButton.Name = "closeButton";
|
||||
closeButton.Size = new System.Drawing.Size(88, 27);
|
||||
closeButton.TabIndex = 10;
|
||||
closeButton.Text = "Cancel";
|
||||
closeButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox5
|
||||
//
|
||||
groupBox5.Controls.Add(clientResolutionComboBox);
|
||||
groupBox5.Location = new System.Drawing.Point(19, 13);
|
||||
groupBox5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox5.Name = "groupBox5";
|
||||
groupBox5.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox5.Size = new System.Drawing.Size(315, 45);
|
||||
groupBox5.TabIndex = 11;
|
||||
groupBox5.TabStop = false;
|
||||
groupBox5.Text = "Screen Resolution";
|
||||
//
|
||||
// clientResolutionComboBox
|
||||
//
|
||||
clientResolutionComboBox.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
clientResolutionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
clientResolutionComboBox.FormattingEnabled = true;
|
||||
clientResolutionComboBox.Location = new System.Drawing.Point(4, 19);
|
||||
clientResolutionComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
clientResolutionComboBox.Name = "clientResolutionComboBox";
|
||||
clientResolutionComboBox.Size = new System.Drawing.Size(307, 23);
|
||||
clientResolutionComboBox.TabIndex = 1;
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
groupBox1.Controls.Add(colorDepthComboBox);
|
||||
groupBox1.Location = new System.Drawing.Point(19, 65);
|
||||
groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox1.Name = "groupBox1";
|
||||
groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
groupBox1.Size = new System.Drawing.Size(316, 44);
|
||||
groupBox1.TabIndex = 12;
|
||||
groupBox1.TabStop = false;
|
||||
groupBox1.Text = "Color Depth";
|
||||
//
|
||||
// colorDepthComboBox
|
||||
//
|
||||
colorDepthComboBox.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
colorDepthComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
colorDepthComboBox.FormattingEnabled = true;
|
||||
colorDepthComboBox.Items.AddRange(new object[] { "Min Color (16 bit)", "Max Color (32 bit)" });
|
||||
colorDepthComboBox.Location = new System.Drawing.Point(4, 18);
|
||||
colorDepthComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
colorDepthComboBox.Name = "colorDepthComboBox";
|
||||
colorDepthComboBox.Size = new System.Drawing.Size(308, 23);
|
||||
colorDepthComboBox.TabIndex = 2;
|
||||
//
|
||||
// ClientSettingsDialog
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
CancelButton = closeButton;
|
||||
ClientSize = new System.Drawing.Size(349, 361);
|
||||
Controls.Add(groupBox1);
|
||||
Controls.Add(groupBox5);
|
||||
Controls.Add(closeButton);
|
||||
Controls.Add(saveButton);
|
||||
Controls.Add(groupBox4);
|
||||
Controls.Add(groupBox3);
|
||||
Controls.Add(windowModeCheckBox);
|
||||
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
Name = "ClientSettingsDialog";
|
||||
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
Text = "Change Client Settings";
|
||||
groupBox3.ResumeLayout(false);
|
||||
groupBox3.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)soundVolumeTrackBar).EndInit();
|
||||
groupBox4.ResumeLayout(false);
|
||||
groupBox5.ResumeLayout(false);
|
||||
groupBox1.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.CheckBox windowModeCheckBox;
|
||||
private System.Windows.Forms.CheckBox musicActiveCheckBox;
|
||||
private System.Windows.Forms.CheckBox soundActiveCheckBox;
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.GroupBox groupBox4;
|
||||
private System.Windows.Forms.ComboBox clientLanguageComboBox;
|
||||
private System.Windows.Forms.Button saveButton;
|
||||
private System.Windows.Forms.TrackBar soundVolumeTrackBar;
|
||||
private System.Windows.Forms.Button closeButton;
|
||||
private System.Windows.Forms.GroupBox groupBox5;
|
||||
private System.Windows.Forms.ComboBox clientResolutionComboBox;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.ComboBox colorDepthComboBox;
|
||||
}
|
||||
}
|
||||
|
||||
83
src/ClientLauncher/ClientSettingsDialog.cs
Normal file
83
src/ClientLauncher/ClientSettingsDialog.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
// <copyright file="ClientSettingsDialog.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Windows.Forms;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="ClientSettingsDialog"/>.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal partial class ClientSettingsDialog : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientSettingsDialog"/> class.
|
||||
/// </summary>
|
||||
public ClientSettingsDialog()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.clientResolutionComboBox.DisplayMember = nameof(ClientResolution.Caption);
|
||||
this.clientResolutionComboBox.ValueMember = nameof(ClientResolution.Index);
|
||||
this.clientResolutionComboBox.DataSource = LauncherSettings.DefaultResolutions;
|
||||
this.Icon = Icon.FromHandle(Properties.Resources.Settings_16x.GetHicon());
|
||||
var config = new ClientSettings();
|
||||
config.Load();
|
||||
this.ReadConfig(config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the available client resolutions.
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public BindingList<ClientResolution>? Resolutions
|
||||
{
|
||||
get => this.clientResolutionComboBox.DataSource as BindingList<ClientResolution>;
|
||||
set
|
||||
{
|
||||
if (value?.Count > 0)
|
||||
{
|
||||
var index = this.clientResolutionComboBox.SelectedIndex;
|
||||
this.clientResolutionComboBox.DataSource = value;
|
||||
if (value?.Count > index)
|
||||
{
|
||||
this.clientResolutionComboBox.SelectedIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
var config = new ClientSettings();
|
||||
|
||||
this.SetConfig(config);
|
||||
config.Save();
|
||||
}
|
||||
|
||||
private void ReadConfig(ClientSettings clientSettings)
|
||||
{
|
||||
this.colorDepthComboBox.SelectedIndex = clientSettings.ClientColorDepth == 0 ? 0 : 1;
|
||||
this.musicActiveCheckBox.Checked = clientSettings.IsMusicEnabled;
|
||||
this.soundActiveCheckBox.Checked = clientSettings.IsSoundEnabled;
|
||||
this.soundVolumeTrackBar.Value = clientSettings.VolumeLevel;
|
||||
this.windowModeCheckBox.Checked = clientSettings.IsWindowModeActive;
|
||||
this.clientResolutionComboBox.SelectedIndex = clientSettings.ResolutionIndex;
|
||||
this.clientLanguageComboBox.SelectedIndex = (int)clientSettings.LangSelection;
|
||||
}
|
||||
|
||||
private void SetConfig(ClientSettings clientSettings)
|
||||
{
|
||||
clientSettings.ClientColorDepth = (ClientColorDepth)this.colorDepthComboBox.SelectedIndex;
|
||||
clientSettings.IsMusicEnabled = this.musicActiveCheckBox.Checked;
|
||||
clientSettings.IsSoundEnabled = this.soundActiveCheckBox.Checked;
|
||||
clientSettings.VolumeLevel = this.soundVolumeTrackBar.Value;
|
||||
clientSettings.IsWindowModeActive = this.windowModeCheckBox.Checked;
|
||||
clientSettings.ResolutionIndex = this.clientResolutionComboBox.SelectedIndex;
|
||||
clientSettings.LangSelection = (ClientLanguage)this.clientLanguageComboBox.SelectedIndex;
|
||||
}
|
||||
}
|
||||
120
src/ClientLauncher/ClientSettingsDialog.resx
Normal file
120
src/ClientLauncher/ClientSettingsDialog.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
142
src/ClientLauncher/HostConfigurationDialog.Designer.cs
generated
Normal file
142
src/ClientLauncher/HostConfigurationDialog.Designer.cs
generated
Normal file
@@ -0,0 +1,142 @@
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
partial class HostConfigurationDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
_serverPortControl = new System.Windows.Forms.NumericUpDown();
|
||||
_serverAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
_descriptionTextBox = new System.Windows.Forms.TextBox();
|
||||
button1 = new System.Windows.Forms.Button();
|
||||
_cancelButton = new System.Windows.Forms.Button();
|
||||
((System.ComponentModel.ISupportInitialize)_serverPortControl).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// _serverPortControl
|
||||
//
|
||||
_serverPortControl.Location = new System.Drawing.Point(273, 36);
|
||||
_serverPortControl.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
_serverPortControl.Maximum = new decimal(new int[] { 65535, 0, 0, 0 });
|
||||
_serverPortControl.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||
_serverPortControl.Name = "_serverPortControl";
|
||||
_serverPortControl.Size = new System.Drawing.Size(68, 23);
|
||||
_serverPortControl.TabIndex = 10;
|
||||
_serverPortControl.Value = new decimal(new int[] { 44405, 0, 0, 0 });
|
||||
//
|
||||
// _serverAddressTextBox
|
||||
//
|
||||
_serverAddressTextBox.Location = new System.Drawing.Point(113, 35);
|
||||
_serverAddressTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
_serverAddressTextBox.Name = "_serverAddressTextBox";
|
||||
_serverAddressTextBox.Size = new System.Drawing.Size(152, 23);
|
||||
_serverAddressTextBox.TabIndex = 9;
|
||||
_serverAddressTextBox.Text = "127.127.127.127";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(13, 38);
|
||||
label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(89, 15);
|
||||
label2.TabIndex = 8;
|
||||
label2.Text = "Server-Address:";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new System.Drawing.Point(13, 9);
|
||||
label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(70, 15);
|
||||
label1.TabIndex = 11;
|
||||
label1.Text = "Description:";
|
||||
//
|
||||
// _descriptionTextBox
|
||||
//
|
||||
_descriptionTextBox.Location = new System.Drawing.Point(113, 6);
|
||||
_descriptionTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
_descriptionTextBox.Name = "_descriptionTextBox";
|
||||
_descriptionTextBox.PlaceholderText = "<Enter a description here>";
|
||||
_descriptionTextBox.Size = new System.Drawing.Size(228, 23);
|
||||
_descriptionTextBox.TabIndex = 12;
|
||||
//
|
||||
// button1
|
||||
//
|
||||
button1.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
button1.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
button1.Location = new System.Drawing.Point(194, 83);
|
||||
button1.Name = "button1";
|
||||
button1.Size = new System.Drawing.Size(75, 23);
|
||||
button1.TabIndex = 13;
|
||||
button1.Text = "OK";
|
||||
button1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// _cancelButton
|
||||
//
|
||||
_cancelButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
|
||||
_cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
_cancelButton.Location = new System.Drawing.Point(113, 83);
|
||||
_cancelButton.Name = "_cancelButton";
|
||||
_cancelButton.Size = new System.Drawing.Size(75, 23);
|
||||
_cancelButton.TabIndex = 14;
|
||||
_cancelButton.Text = "Cancel";
|
||||
_cancelButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HostConfiguration
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(362, 118);
|
||||
Controls.Add(_cancelButton);
|
||||
Controls.Add(button1);
|
||||
Controls.Add(_descriptionTextBox);
|
||||
Controls.Add(label1);
|
||||
Controls.Add(_serverPortControl);
|
||||
Controls.Add(_serverAddressTextBox);
|
||||
Controls.Add(label2);
|
||||
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
MinimizeBox = false;
|
||||
Name = "HostConfiguration";
|
||||
Text = "Configure Connection";
|
||||
((System.ComponentModel.ISupportInitialize)_serverPortControl).EndInit();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.NumericUpDown _serverPortControl;
|
||||
private System.Windows.Forms.TextBox _serverAddressTextBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox _descriptionTextBox;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Button _cancelButton;
|
||||
}
|
||||
46
src/ClientLauncher/HostConfigurationDialog.cs
Normal file
46
src/ClientLauncher/HostConfigurationDialog.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="HostConfigurationDialog.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
/// <summary>
|
||||
/// Dialog for connection settings of a server.
|
||||
/// </summary>
|
||||
public partial class HostConfigurationDialog : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HostConfigurationDialog"/> class.
|
||||
/// </summary>
|
||||
public HostConfigurationDialog()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the settings.
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public ServerHostSettings Settings
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ServerHostSettings
|
||||
{
|
||||
Description = this._descriptionTextBox.Text,
|
||||
Address = this._serverAddressTextBox.Text,
|
||||
Port = (int)this._serverPortControl.Value,
|
||||
};
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this._descriptionTextBox.Text = value.Description;
|
||||
this._serverAddressTextBox.Text = value.Address;
|
||||
this._serverPortControl.Value = value.Port;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
src/ClientLauncher/HostConfigurationDialog.resx
Normal file
120
src/ClientLauncher/HostConfigurationDialog.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
31
src/ClientLauncher/ILauncher.cs
Normal file
31
src/ClientLauncher/ILauncher.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="ILauncher.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// The interface of a launcher.
|
||||
/// </summary>
|
||||
internal interface ILauncher
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the host ip.
|
||||
/// </summary>
|
||||
string? HostAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the host port.
|
||||
/// </summary>
|
||||
int HostPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the main executable path.
|
||||
/// </summary>
|
||||
string? MainExePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Launches the MU Online client with the specified settings.
|
||||
/// </summary>
|
||||
void LaunchClient();
|
||||
}
|
||||
183
src/ClientLauncher/Launcher.cs
Normal file
183
src/ClientLauncher/Launcher.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
// <copyright file="Launcher.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
|
||||
/// <summary>
|
||||
/// The default launcher, which writes
|
||||
/// * host and port into the registry (official way until season 6 at the global server)
|
||||
/// * adds parameters /u and /p (works in some other versions of the game client)
|
||||
/// before starting the main.exe.
|
||||
/// </summary>
|
||||
public class Launcher : ILauncher
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the host ip.
|
||||
/// </summary>
|
||||
public string? HostAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the host port.
|
||||
/// </summary>
|
||||
public int HostPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the main executable path.
|
||||
/// </summary>
|
||||
public string? MainExePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Launches Mu with the set configuration.
|
||||
/// </summary>
|
||||
public void LaunchClient()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(this.HostAddress))
|
||||
{
|
||||
MessageBox.Show("Host address is not set.", "Error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(this.MainExePath))
|
||||
{
|
||||
MessageBox.Show("The path to the main.exe is not set.", "Error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.ResolveHost() is not { } ipAddress)
|
||||
{
|
||||
MessageBox.Show($"Address '{this.HostAddress} could not be resolved to an IPv4 address.", "Error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
using var localMachineKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
|
||||
using var key = localMachineKey.CreateSubKey(@"SOFTWARE\WebZen\Mu\Connection");
|
||||
key.SetValue("Key", Environment.TickCount, RegistryValueKind.DWord);
|
||||
key.SetValue("ParameterA", this.HostEncode(ipAddress), RegistryValueKind.String);
|
||||
key.SetValue("ParameterB", this.PortEncode(ipAddress), RegistryValueKind.DWord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MessageBox.Show(
|
||||
"IP and Port couldn't be set, because the operating system is not windows. Try to launch the game client anyway?",
|
||||
string.Empty,
|
||||
MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var info = new DirectoryInfo(this.MainExePath!);
|
||||
var startInfo = new ProcessStartInfo(this.MainExePath, ["connect", $"/u{ipAddress}", $"/p{this.HostPort}"])
|
||||
{
|
||||
WorkingDirectory = info.Parent!.FullName,
|
||||
UseShellExecute = true,
|
||||
Verb = "open",
|
||||
};
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
startInfo.LoadUserProfile = true;
|
||||
}
|
||||
|
||||
Process.Start(startInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes the Port, so that the main.exe can read it.
|
||||
/// </summary>
|
||||
/// <returns>Encoded port value which will be put into ParameterB.</returns>
|
||||
private int PortEncode(string ipAddress)
|
||||
{
|
||||
var port = this.HostPort;
|
||||
switch (ipAddress.Length % 4)
|
||||
{
|
||||
case 0:
|
||||
port += 12 - (((port / 4) % 4) * 8);
|
||||
return port;
|
||||
|
||||
case 1:
|
||||
port += 7 - ((port % 8) * 2);
|
||||
return port;
|
||||
|
||||
case 2:
|
||||
port += 3 - ((port % 4) * 2);
|
||||
return port;
|
||||
|
||||
case 3:
|
||||
port += (0x13 - ((port % 4) * 2)) - (((port / 0x10) % 2) * 0x20);
|
||||
return port;
|
||||
default:
|
||||
// we'll hopefully never run into this one
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
private string? ResolveHost()
|
||||
{
|
||||
if (IPAddress.TryParse(this.HostAddress, out _))
|
||||
{
|
||||
return this.HostAddress;
|
||||
}
|
||||
|
||||
var entry = Dns.GetHostEntry(this.HostAddress!);
|
||||
if (entry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork) is { } ipAddress)
|
||||
{
|
||||
var address = ipAddress.ToString();
|
||||
|
||||
// The game client blocks connections to 127.0.0.1 (probably to prevent cheating).
|
||||
return address == "127.0.0.1" ? "127.127.127.127" : address;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes the IP Address of the server, so that the main.exe can read it.
|
||||
/// </summary>
|
||||
/// <returns>Encoded string value of the ip address which to put into ParameterA.</returns>
|
||||
private string HostEncode(string ipAddress)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
var counter = 0;
|
||||
foreach (var ch in ipAddress)
|
||||
{
|
||||
var encodedCharacter = '\0';
|
||||
counter++;
|
||||
switch (counter)
|
||||
{
|
||||
case 1:
|
||||
encodedCharacter = (char)(ch + '\f');
|
||||
break;
|
||||
|
||||
case 2:
|
||||
encodedCharacter = (char)(ch + '\a');
|
||||
break;
|
||||
|
||||
case 3:
|
||||
encodedCharacter = (char)(ch + '\x0003');
|
||||
break;
|
||||
|
||||
case 4:
|
||||
encodedCharacter = (char)(ch + '\x0013');
|
||||
counter = 0;
|
||||
break;
|
||||
default:
|
||||
// we should not run into this case, since it's always 1 to 4.
|
||||
break;
|
||||
}
|
||||
|
||||
result.Append(encodedCharacter);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
44
src/ClientLauncher/LauncherSettings.cs
Normal file
44
src/ClientLauncher/LauncherSettings.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
// <copyright file="LauncherSettings.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
/// <summary>
|
||||
/// Settings of the launcher.
|
||||
/// </summary>
|
||||
public class LauncherSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the default resolutions, which are based on the open source MuMain.
|
||||
/// </summary>
|
||||
public static ClientResolution[] DefaultResolutions =>
|
||||
[
|
||||
new(0, "640x480"),
|
||||
new(1, "800x600"),
|
||||
new(2, "1024x768"),
|
||||
new(3, "1280x1024"),
|
||||
new(4, "1600x1200"),
|
||||
new(5, "1864x1400"),
|
||||
new(6, "1600x900"),
|
||||
new(7, "1600x1280"),
|
||||
new(8, "1680x1050"),
|
||||
new(9, "1920x1080"),
|
||||
new(10, "2560x1440"),
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the main executable path.
|
||||
/// </summary>
|
||||
public string? MainExePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configured hosts.
|
||||
/// </summary>
|
||||
public List<ServerHostSettings> Hosts { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resolutions.
|
||||
/// </summary>
|
||||
public List<ClientResolution> AvailableResolutions { get; set; } = [];
|
||||
}
|
||||
69
src/ClientLauncher/MUnique.OpenMU.ClientLauncher.csproj
Normal file
69
src/ClientLauncher/MUnique.OpenMU.ClientLauncher.csproj
Normal file
@@ -0,0 +1,69 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net10.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<Nullable>enable</Nullable>
|
||||
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DocumentationFile>bin\Debug\MUnique.OpenMU.ClientLauncher.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DocumentationFile>bin\Release\MUnique.OpenMU.ClientLauncher.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Rocket_16x.ico" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>MUnique.OpenMU.ClientLauncher.exe.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>Rocket_16x.ico</ApplicationIcon>
|
||||
<StartupObject>MUnique.OpenMU.ClientLauncher.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="MUnique.OpenMU.ClientLauncher.exe.manifest">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Compile Update="MainForm.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="ClientSettingsDialog.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
<Compile Update="MainForm.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="ClientSettingsDialog.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>ClientSettingsDialog.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="ClientSettingsDialog.resx">
|
||||
<DependentUpon>ClientSettingsDialog.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||
Remove this element if your application requires this virtualization for backwards
|
||||
compatibility.
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on and is
|
||||
is designed to work with. Uncomment the appropriate elements and Windows will
|
||||
automatically selected the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
|
||||
</assembly>
|
||||
207
src/ClientLauncher/MainForm.Designer.cs
generated
Normal file
207
src/ClientLauncher/MainForm.Designer.cs
generated
Normal file
@@ -0,0 +1,207 @@
|
||||
namespace MUnique.OpenMU.ClientLauncher
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
_launchButton = new System.Windows.Forms.Button();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
openFileDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
MainExePathTextBox = new System.Windows.Forms.TextBox();
|
||||
SearchMainExeButton = new System.Windows.Forms.Button();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
configurationDialogButton = new System.Windows.Forms.Button();
|
||||
_editHostButton = new System.Windows.Forms.Button();
|
||||
_addHostButton = new System.Windows.Forms.Button();
|
||||
_serversComboBox = new System.Windows.Forms.ComboBox();
|
||||
_removeHostButton = new System.Windows.Forms.Button();
|
||||
SuspendLayout();
|
||||
//
|
||||
// _launchButton
|
||||
//
|
||||
_launchButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
_launchButton.Location = new System.Drawing.Point(505, 45);
|
||||
_launchButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
_launchButton.Name = "_launchButton";
|
||||
_launchButton.Size = new System.Drawing.Size(147, 27);
|
||||
_launchButton.TabIndex = 0;
|
||||
_launchButton.Text = "Launch Client";
|
||||
_launchButton.UseVisualStyleBackColor = true;
|
||||
_launchButton.Click += LaunchClick;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new System.Drawing.Point(14, 17);
|
||||
label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(85, 15);
|
||||
label1.TabIndex = 1;
|
||||
label1.Text = "main.exe Path:";
|
||||
//
|
||||
// openFileDialog
|
||||
//
|
||||
openFileDialog.FileName = "main.exe";
|
||||
openFileDialog.Filter = "Executeables|*.exe";
|
||||
//
|
||||
// MainExePathTextBox
|
||||
//
|
||||
MainExePathTextBox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
MainExePathTextBox.Location = new System.Drawing.Point(107, 14);
|
||||
MainExePathTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
MainExePathTextBox.Name = "MainExePathTextBox";
|
||||
MainExePathTextBox.Size = new System.Drawing.Size(467, 23);
|
||||
MainExePathTextBox.TabIndex = 2;
|
||||
MainExePathTextBox.Text = "main.exe";
|
||||
//
|
||||
// SearchMainExeButton
|
||||
//
|
||||
SearchMainExeButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
SearchMainExeButton.Location = new System.Drawing.Point(582, 12);
|
||||
SearchMainExeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
SearchMainExeButton.Name = "SearchMainExeButton";
|
||||
SearchMainExeButton.Size = new System.Drawing.Size(35, 27);
|
||||
SearchMainExeButton.TabIndex = 3;
|
||||
SearchMainExeButton.Text = "...";
|
||||
SearchMainExeButton.UseVisualStyleBackColor = true;
|
||||
SearchMainExeButton.Click += SearchMainExeButtonClick;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(57, 54);
|
||||
label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(42, 15);
|
||||
label2.TabIndex = 4;
|
||||
label2.Text = "Server:";
|
||||
//
|
||||
// configurationDialogButton
|
||||
//
|
||||
configurationDialogButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
configurationDialogButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
configurationDialogButton.Image = Properties.Resources.Settings_16x;
|
||||
configurationDialogButton.Location = new System.Drawing.Point(625, 12);
|
||||
configurationDialogButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
configurationDialogButton.Name = "configurationDialogButton";
|
||||
configurationDialogButton.Size = new System.Drawing.Size(27, 27);
|
||||
configurationDialogButton.TabIndex = 4;
|
||||
configurationDialogButton.UseVisualStyleBackColor = true;
|
||||
configurationDialogButton.Click += ConfigurationDialogButtonClick;
|
||||
//
|
||||
// _editHostButton
|
||||
//
|
||||
_editHostButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
_editHostButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
_editHostButton.Image = Properties.Resources.Edit_16x;
|
||||
_editHostButton.Location = new System.Drawing.Point(446, 47);
|
||||
_editHostButton.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||
_editHostButton.Name = "_editHostButton";
|
||||
_editHostButton.Size = new System.Drawing.Size(23, 23);
|
||||
_editHostButton.TabIndex = 7;
|
||||
_editHostButton.UseVisualStyleBackColor = true;
|
||||
_editHostButton.Click += OnEditHostButtonClick;
|
||||
//
|
||||
// _addHostButton
|
||||
//
|
||||
_addHostButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
_addHostButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
_addHostButton.Image = Properties.Resources.Add_16x;
|
||||
_addHostButton.Location = new System.Drawing.Point(419, 47);
|
||||
_addHostButton.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||
_addHostButton.Name = "_addHostButton";
|
||||
_addHostButton.Size = new System.Drawing.Size(23, 23);
|
||||
_addHostButton.TabIndex = 6;
|
||||
_addHostButton.UseVisualStyleBackColor = true;
|
||||
_addHostButton.Click += OnAddHostButtonClick;
|
||||
//
|
||||
// _serversComboBox
|
||||
//
|
||||
_serversComboBox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
_serversComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
_serversComboBox.FormattingEnabled = true;
|
||||
_serversComboBox.Location = new System.Drawing.Point(107, 48);
|
||||
_serversComboBox.Name = "_serversComboBox";
|
||||
_serversComboBox.Size = new System.Drawing.Size(307, 23);
|
||||
_serversComboBox.TabIndex = 5;
|
||||
_serversComboBox.SelectedValueChanged += OnServersComboBoxSelectedIndexChanged;
|
||||
//
|
||||
// _removeHostButton
|
||||
//
|
||||
_removeHostButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
_removeHostButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
_removeHostButton.Image = Properties.Resources.Remove_16x;
|
||||
_removeHostButton.Location = new System.Drawing.Point(473, 46);
|
||||
_removeHostButton.Margin = new System.Windows.Forms.Padding(2, 3, 5, 3);
|
||||
_removeHostButton.Name = "_removeHostButton";
|
||||
_removeHostButton.Size = new System.Drawing.Size(23, 23);
|
||||
_removeHostButton.TabIndex = 8;
|
||||
_removeHostButton.UseVisualStyleBackColor = true;
|
||||
_removeHostButton.Click += OnRemoveHostButtonClick;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(665, 82);
|
||||
Controls.Add(_removeHostButton);
|
||||
Controls.Add(_serversComboBox);
|
||||
Controls.Add(_addHostButton);
|
||||
Controls.Add(_editHostButton);
|
||||
Controls.Add(configurationDialogButton);
|
||||
Controls.Add(label2);
|
||||
Controls.Add(SearchMainExeButton);
|
||||
Controls.Add(MainExePathTextBox);
|
||||
Controls.Add(label1);
|
||||
Controls.Add(_launchButton);
|
||||
Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
MaximizeBox = false;
|
||||
MaximumSize = new System.Drawing.Size(1257, 121);
|
||||
Name = "MainForm";
|
||||
Text = "MU Game Client Launcher";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button _launchButton;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.OpenFileDialog openFileDialog;
|
||||
private System.Windows.Forms.TextBox MainExePathTextBox;
|
||||
private System.Windows.Forms.Button SearchMainExeButton;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Button configurationDialogButton;
|
||||
private System.Windows.Forms.Button _editHostButton;
|
||||
private System.Windows.Forms.Button _addHostButton;
|
||||
private System.Windows.Forms.ComboBox _serversComboBox;
|
||||
private System.Windows.Forms.Button _removeHostButton;
|
||||
}
|
||||
}
|
||||
|
||||
197
src/ClientLauncher/MainForm.cs
Normal file
197
src/ClientLauncher/MainForm.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
// <copyright file="MainForm.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
#pragma warning disable CA1416 // This project is compiled for windows
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// The main form of the launcher.
|
||||
/// </summary>
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private const string ConfigFileName = "launcher.config";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding list for the configured hosts.
|
||||
/// </summary>
|
||||
private BindingList<ServerHostSettings> _hostsBindingList = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainForm"/> class.
|
||||
/// </summary>
|
||||
public MainForm()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.LoadOptions();
|
||||
this.UpdateButtonStates();
|
||||
}
|
||||
|
||||
private BindingList<ServerHostSettings> Hosts
|
||||
{
|
||||
get => this._hostsBindingList;
|
||||
set
|
||||
{
|
||||
this._hostsBindingList = value;
|
||||
this._serversComboBox.DataSource = value;
|
||||
}
|
||||
}
|
||||
|
||||
private BindingList<ClientResolution> Resolutions { get; set; } = new(LauncherSettings.DefaultResolutions);
|
||||
|
||||
/// <summary>
|
||||
/// Launches the MU Online client (main.exe) to connect to the configured address.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
||||
private void LaunchClick(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var selectedHost = (ServerHostSettings)this._serversComboBox.SelectedItem!;
|
||||
var launcher = new Launcher
|
||||
{
|
||||
HostAddress = selectedHost.Address,
|
||||
HostPort = selectedHost.Port,
|
||||
MainExePath = this.MainExePathTextBox.Text,
|
||||
};
|
||||
launcher.LaunchClient();
|
||||
|
||||
this.SaveCurrentOptions();
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
MessageBox.Show("Can't access Windows Registry. To use the launcher, run it as Administrator.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error Starting MU. Path correct?" + Environment.NewLine + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadOptions()
|
||||
{
|
||||
this._serversComboBox.DataSource = this.Hosts;
|
||||
if (!File.Exists(ConfigFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var reader = new XmlSerializer(typeof(LauncherSettings));
|
||||
using var file = new StreamReader(ConfigFileName);
|
||||
if (reader.Deserialize(file) is LauncherSettings launcherSettings)
|
||||
{
|
||||
this.MainExePathTextBox.Text = launcherSettings.MainExePath;
|
||||
this.Hosts = new BindingList<ServerHostSettings>(launcherSettings.Hosts);
|
||||
if (launcherSettings.AvailableResolutions?.Any() is true)
|
||||
{
|
||||
this.Resolutions = new(launcherSettings.AvailableResolutions);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Resolutions = new(LauncherSettings.DefaultResolutions);
|
||||
}
|
||||
}
|
||||
|
||||
file.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.Hosts.Clear();
|
||||
this.Hosts.Add(new ServerHostSettings { Description = "Local ConnectServer", Address = "localhost", Port = 44405 });
|
||||
this.Hosts.Add(new ServerHostSettings { Description = "Local GameServer 1", Address = "localhost", Port = 55901 });
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveCurrentOptions()
|
||||
{
|
||||
var settings = new LauncherSettings
|
||||
{
|
||||
Hosts = this._hostsBindingList.ToList(),
|
||||
MainExePath = this.MainExePathTextBox.Text,
|
||||
AvailableResolutions = this.Resolutions.ToList(),
|
||||
};
|
||||
|
||||
var writer = new XmlSerializer(typeof(LauncherSettings));
|
||||
using var file = File.Create(ConfigFileName);
|
||||
writer.Serialize(file, settings);
|
||||
file.Close();
|
||||
}
|
||||
|
||||
private void SearchMainExeButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
var dialogResult = this.openFileDialog.ShowDialog(this);
|
||||
if (dialogResult == DialogResult.OK)
|
||||
{
|
||||
this.MainExePathTextBox.Text = this.openFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigurationDialogButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
using var configDialog = new ClientSettingsDialog();
|
||||
configDialog.Resolutions = this.Resolutions;
|
||||
configDialog.ShowDialog(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Changing the configuration of the MU game client is only supported on windows.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAddHostButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
using var dialog = new HostConfigurationDialog();
|
||||
if (dialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
var settings = dialog.Settings;
|
||||
this._hostsBindingList.Add(settings);
|
||||
this.SaveCurrentOptions();
|
||||
this.UpdateButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEditHostButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
var selectedConfiguration = (ServerHostSettings)this._serversComboBox.SelectedItem!;
|
||||
using var dialog = new HostConfigurationDialog();
|
||||
dialog.Settings = selectedConfiguration;
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
var editedConfiguration = dialog.Settings;
|
||||
selectedConfiguration.Port = editedConfiguration.Port;
|
||||
selectedConfiguration.Address = editedConfiguration.Address;
|
||||
selectedConfiguration.Description = editedConfiguration.Description;
|
||||
this.SaveCurrentOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRemoveHostButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
this._hostsBindingList.RemoveAt(this._serversComboBox.SelectedIndex);
|
||||
this.SaveCurrentOptions();
|
||||
}
|
||||
|
||||
private void OnServersComboBoxSelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.UpdateButtonStates();
|
||||
}
|
||||
|
||||
private void UpdateButtonStates()
|
||||
{
|
||||
var isServerSelected = this._serversComboBox.SelectedItem is ServerHostSettings;
|
||||
this._editHostButton.Enabled = isServerSelected;
|
||||
this._removeHostButton.Enabled = isServerSelected;
|
||||
this._launchButton.Enabled = isServerSelected;
|
||||
}
|
||||
}
|
||||
303
src/ClientLauncher/MainForm.resx
Normal file
303
src/ClientLauncher/MainForm.resx
Normal file
@@ -0,0 +1,303 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAMjIAAAEAIADIKAAAFgAAACgAAAAyAAAAZAAAAAEAIAAAAAAAECcAACMuAAAjLgAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/19fWfAAAAAAAAAAAAAAAAAAAAAPHx8RL29vZ09vb23Pb29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9/f3mv///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//X19Z8AAAAAAAAAAAAAAAD39/ce9vb23fb29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9fX1nP///wIAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9fX1nwAAAAAAAAAA9/f3Hvb2
|
||||
9t329vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9fX1nP///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ubm7/Wlpa/1paWv9aWlr/Wlpa/1paWv9aWlr/Wlpa/1paWv+oqKj/9vb2//b2
|
||||
9v/19fWfAAAAAPf39yD29vbf9vb2//b29v/19fX/paWl/2BgYP9aWlr/Wlpa/1paWv9aWlr/Wlpa/1pa
|
||||
Wv9aWlr/Wlpa/11dXf/MzMz/9vb2//b29v/29vb/9vb2bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/5ycnP/29vb/9vb2//X19Z/4+Pgl9vb24vb29v/29vb/9fX1/42Njf9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0tLS//U1NT/9vb2//b29v/19fWAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/WVlZ/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/nJyc//b29v/29vb/9vb2wPb29uT29vb/9vb2//X1
|
||||
9f+Pj4//QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/7Ky
|
||||
sv/29vb/9vb2//X19YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ZWVn/QkJC/0JCQv+lpaX/xsbG/8bGxv/Gxsb/xsbG/8bGxv/e3t7/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/19fX/jY2N/0JCQv9CQkL/QkJC/2xsbP/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bG
|
||||
xv/Gxsb/Y2Nj/0JCQv9CQkL/srKy//b29v/29vb/9fX1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/8nJyf/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9fX1/4iIiP9CQkL/QkJC/0JCQv9MTEz/5+fn//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v9vb2//QkJC/0JCQv+ysrL/9vb2//b29v/19fWAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/WVlZ/0JC
|
||||
Qv9CQkL/ycnJ//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//X19f+NjY3/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9gYGD/2NjY//b29v/29vb/9vb2//b29v/29vb/9vb2/29vb/9CQkL/QkJC/7Ky
|
||||
sv/29vb/9vb2//X19YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ZWVn/QkJC/0JCQv/Jycn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/19fX/iIiI/0JCQv9CQkL/QkJC/0lJSf9CQkL/QkJC/0JCQv9MTEz/ubm5//b29v/29vb/9vb2//b2
|
||||
9v/29vb/b29v/0JCQv9CQkL/srKy//b29v/29vb/9fX1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/8nJyf/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9fX1/4iIiP9CQkL/QkJC/0JCQv9tbW3/6enp/5GRkf9DQ0P/QkJC/0JC
|
||||
Qv9CQkL/jo6O//Ly8v/29vb/9vb2//b29v9vb2//QkJC/0JCQv+ysrL/9vb2//b29v/19fWAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/WVlZ/0JC
|
||||
Qv9CQkL/ycnJ//b29v/29vb/9vb2//b29v/29vb/9vb2//X19f+IiIj/QkJC/0JCQv9CQkL/bW1t/+3t
|
||||
7f/29vb/9vb2/8HBwf9OTk7/QkJC/0JCQv9CQkL/b29v/+vr6//29vb/9vb2/29vb/9CQkL/QkJC/7Ky
|
||||
sv/29vb/9vb2//X19YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v+tra3/oqKi/6Kiov/h4eH/9vb2//b29v/29vb/9vb2//b29v/19fX/iIiI/0JC
|
||||
Qv9CQkL/QkJC/21tbf/t7e3/9vb2//b29v/29vb/9vb2/9zc3P9hYWH/QkJC/0JCQv9CQkL/YGBg/+Hh
|
||||
4f/29vb/b29v/0JCQv9CQkL/srKy//b29v/29vb/9fX1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9fX1/4iIiP9CQkL/QkJC/0JCQv9tbW3/7e3t//b29v/29vb/9vb2//b29v/29vb/9vb2/+3t
|
||||
7f99fX3/QkJC/0JCQv9CQkL/VFRU/9XV1f9vb2//QkJC/0JCQv+ysrL/9vb2//b29v/19fWAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//X19f+IiIj/QkJC/0JCQv9CQkL/bW1t/+3t7f/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//X19f+UlJT/QkJC/0JCQv9CQkL/TExM/1VVVf9CQkL/QkJC/7Ky
|
||||
sv/29vb/9vb2//X19YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD39/eZ9/f3mff395n39/eZ9/f3mfX19bv29vb/9vb2//b29v/19fX/jY2N/0JCQv9CQkL/QkJC/2xs
|
||||
bP/s7Oz/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v+oqKj/Q0ND/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/srKy//b29v/29vb/9fX1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4+Pgk9vb24/b29v/29vb/9fX1/42N
|
||||
jf9CQkL/QkJC/0JCQv9sbGz/7Ozs//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v+2trb/RkZG/0JCQv9CQkL/QkJC/0JCQv+ysrL/9vb2//b29v/19fWfAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/f3Ifb2
|
||||
9uP29vb/9vb2//X19f+IiIj/QkJC/0JCQv9CQkL/bm5u/+3t7f/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/AwMD/RkZG/0JCQv9CQkL/QkJC/6ur
|
||||
q//29vb/9vb2//b29v/19fVqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAPf39x729vbd9vb2//b29v/19fX/jY2N/0JCQv9CQkL/QkJC/2xsbP/s7Oz/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v+8vLz/RUVF/0JCQv9CQkL/TExM/9fX1//29vb/9vb2//b29v329vZSAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD39/cg9vb23/b29v/29vb/9fX1/42Njf9CQkL/QkJC/0JC
|
||||
Qv9ubm7/7e3t//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v+xsbH/Q0ND/0JCQv9CQkL/WVlZ/+bm5v/29vb/9vb2//b2
|
||||
9vb29vY2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8fHxEvb29uD29vb/9vb2//X1
|
||||
9f+Ojo7/QkJC/0JCQv9CQkL/TExM/+zs7P/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v+pqan/QkJC/0JC
|
||||
Qv9CQkL/aGho//Hx8f/29vb/9vb2//b29t7v7+8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vZ09vb2//b29v/19fX/jo6O/0JCQv9CQkL/QkJC/0JCQv9CQkL/m5ub//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v+cnJz/QkJC/0JCQv9CQkL/ioqK//b29v/29vb/9vb2//b29qwAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29tz29vb/9vb2/6Wlpf9CQkL/QkJC/0JCQv9KSkr/QkJC/0JC
|
||||
Qv9ERET/ysrK//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//X19f99fX3/QkJC/0JCQv9CQkL/s7Oz//b2
|
||||
9v/29vb/9vb2//X19WgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/YGBg/0JC
|
||||
Qv9CQkL/ampq/+Pj4/9fX1//QkJC/0JCQv9TU1P/4+Pj//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2/+7u
|
||||
7v9jY2P/QkJC/0JCQv9JSUn/2dnZ//b29v/29vb/9vb28vb29hsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ZWVn/QkJC/0JCQv/IyMj/9vb2/9fX1/9JSUn/QkJC/0JCQv9oaGj/8PDw//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2/9ra2v9LS0v/QkJC/0JCQv9qamr/9PT0//b29v/29vb/9vb2pgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/8nJyf/29vb/9vb2/7Oz
|
||||
s/9CQkL/QkJC/0JCQv+Ghob/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/8/Pz/6Wlpf9kZGT/RkZG/1ZWVv+QkJD/5OTk//b29v/29vb/9vb2/7Ozs/9CQkL/QkJC/0JC
|
||||
Qv+jo6P/9vb2//b29v/29vb/9/f3QgAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2//b29v/29vb/WVlZ/0JC
|
||||
Qv9CQkL/ycnJ//b29v/29vb/9vb2/4iIiP9CQkL/QkJC/0JCQv+dnZ3/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//Pz8/95eXn/QkJC/0JCQv9CQkL/QkJC/0JCQv9WVlb/2tra//b2
|
||||
9v/29vb/9vb2/319ff9CQkL/QkJC/0hISP/c3Nz/9vb2//b29v/29vbQ////AQAAAAAAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ZWVn/QkJC/0JCQv/Jycn/9vb2//b29v/29vb/8PDw/2xsbP9CQkL/QkJC/0JC
|
||||
Qv+vr6//9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/o6Oj/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9ra2v/9fX1//b29v/29vb/5eXl/05OTv9CQkL/QkJC/3x8fP/29vb/9vb2//b2
|
||||
9v/19fVPAAAAAAAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/8nJyf/29vb/9vb2//b2
|
||||
9v/29vb/6enp/19fX/9CQkL/QkJC/0RERP++vr7/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v9ZWVn/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv/T09P/9vb2//b29v/29vb/sLCw/0JC
|
||||
Qv9CQkL/QkJC/8vLy//29vb/9vb2//b29s7///8BAAAAAAAAAAAAAAAA9vb2//b29v/29vb/WVlZ/0JC
|
||||
Qv9CQkL/ycnJ//b29v/29vb/9vb2//b29v/29vb/39/f/1RUVP9CQkL/QkJC/0hISP/IyMj/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/8PDw/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/7e3
|
||||
t//29vb/9vb2//b29v/19fX/ZGRk/0JCQv9CQkL/Z2dn//X19f/29vb/9vb2//X19UoAAAAAAAAAAAAA
|
||||
AAD29vb/9vb2//b29v9ZWVn/QkJC/0JCQv/Jycn/9vb2//b29v/29vb/9vb2//b29v/29vb/1NTU/0xM
|
||||
TP9CQkL/QkJC/0lJSf/BwcH/9vb2//b29v/29vb/9vb2//b29v/19fX/R0dH/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/wsLC//b29v/29vb/9vb2//b29v/FxcX/QkJC/0JCQv9CQkL/xMTE//b2
|
||||
9v/29vb/9vb2sQAAAAAAAAAAAAAAAPb29v/29vb/9vb2/1lZWf9CQkL/QkJC/2ZmZv9ycnL/cnJy/3Jy
|
||||
cv9ycnL/cnJy/3Jycv9ycnL/VlZW/0JCQv9CQkL/QkJC/0ZGRv+5ubn/9vb2//b29v/29vb/9vb2//b2
|
||||
9v94eHj/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/01NTf/u7u7/9vb2//b29v/29vb/9vb2//b2
|
||||
9v9ycnL/QkJC/0JCQv90dHT/9vb2//b29v/29vb79PT0GAAAAAAAAAAA9vb2//b29v/29vb/XFxc/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0RE
|
||||
RP+wsLD/9vb2//b29v/29vb/9vb2/9fX1/9KSkr/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/rq6u//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2/8TExP9CQkL/QkJC/0NDQ//Y2Nj/9vb2//b29v/29vZzAAAAAAAA
|
||||
AAD29vb/9vb2//b29v/MzMz/S0tL/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0NDQ/+goKD/9vb2//b29v/29vb/9vb2/8zMzP9YWFj/QkJC/0JC
|
||||
Qv9CQkL/S0tL/6urq//29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9fX1/2BgYP9CQkL/QkJC/42N
|
||||
jf/29vb/9vb2//b29tAAAAAAAAAAAPf395n29vb/9vb2//b29v/T09P/rq6u/66urv+urq7/rq6u/66u
|
||||
rv+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/p6en/01NTf9CQkL/QkJC/0JCQv+Dg4P/8PDw//b2
|
||||
9v/29vb/9vb2//Ly8v/ExMT/rq6u/7u7u//q6ur/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/q6ur/0JCQv9CQkL/U1NT//X19f/29vb/9vb2/vb29hsAAAAA////Afb29pX29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/2NjY/1dX
|
||||
V/9CQkL/QkJC/0JCQv9nZ2f/39/f//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/n5+f/RUVF/0JCQv9CQkL/zMzM//b29v/29vb/9/f3YQAA
|
||||
AAAAAAAA////Afb29pX29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/5OTk/2VlZf9CQkL/QkJC/0JCQv9MTEz/ubm5//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v90dHT/QkJC/0JC
|
||||
Qv+RkZH/9vb2//b29v/29vaoAAAAAAAAAAAAAAAA////AfX19Wb29vZ39vb2d/b29nf29vZ39vb2d/b2
|
||||
9nf29vZ39vb2d/b29nf29vZ39vb2d/b29nf19fWc9vb2//b29v/29vb/7+/v/4eHh/9CQkL/QkJC/0JC
|
||||
Qv9CQkL/goKC/+jo6P/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2/66urv9CQkL/QkJC/19fX//29vb/9vb2//b29uoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vZs9vb2/fb2
|
||||
9v/29vb/9vb2/7CwsP9ISEj/QkJC/0JCQv9CQkL/UVFR/7a2tv/19fX/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/2dnZ/0JCQv9CQkL/Q0ND/+zs7P/29vb/9vb2//X1
|
||||
9RoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD29vZR9vb29vb29v/29vb/9vb2/9jY2P9nZ2f/QkJC/0JCQv9CQkL/QkJC/2dn
|
||||
Z//Jycn/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/19fX/Tk5O/0JC
|
||||
Qv9CQkL/zMzM//b29v/29vb/9PT0SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vY59vb24fb29v/29vb/9vb2//Pz
|
||||
8/+fn5//RkZG/0JCQv9CQkL/QkJC/0JCQv91dXX/yMjI//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29v90dHT/QkJC/0JCQv+oqKj/9vb2//b29v/29vZ3AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADx8fES9vb2sPb29v/29vb/9vb2//b29v/Z2dn/d3d3/0JCQv9CQkL/QkJC/0JCQv9CQkL/ZWVl/7Gx
|
||||
sf/r6+v/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2/42Njf9CQkL/QkJC/42Njf/29vb/9vb2//X1
|
||||
9Z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8B9vb2bfb29vT29vb/9vb2//b29v/29vb/x8fH/2Rk
|
||||
ZP9CQkL/QkJC/0JCQv9CQkL/QkJC/0dHR/96enr/s7Oz/97e3v/29vb/9vb2//b29v/29vb/oqKi/0JC
|
||||
Qv9CQkL/gICA//b29v/29vb/9/f3twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9fX1Gvb2
|
||||
9qL29vb/9vb2//b29v/29vb/9fX1/8HBwf9wcHD/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/1RU
|
||||
VP97e3v/kZGR/6ioqP+NjY3/QkJC/0JCQv90dHT/9vb2//b29v/29vbNAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPT09Ej19fXW9vb2//b29v/29vb/9vb2//b29v/U1NT/iIiI/05O
|
||||
Tv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/2hoaP/29vb/9vb2//b2
|
||||
9uUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wL29vZV9vb20fb2
|
||||
9v/29vb/9vb2//b29v/29vb/8/Pz/8XFxf+Kior/WVlZ/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JC
|
||||
Qv9CQkL/ioqK//b29v/29vb/9vb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///8B9fX1Tvf397b29vb89vb2//b29v/29vb/9vb2//b29v/29vb/6enp/8TE
|
||||
xP+goKD/hYWF/3p6ev9ubm7/YWFh/4iIiP/09PT/9vb2//b29v/29vbkAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb29hz39/d69vb22Pb2
|
||||
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb26Pn5
|
||||
+SoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA+Pj4IvX19Wn29vaw9fX18fb29v/29vb/9vb2//b29v/29vb/9vb2//b2
|
||||
9v/29vb/9vb2//b29uf5+fkpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8B+Pj4Ivb2
|
||||
9lL19fWA9vb2qPb29sH19fXW9vb27fb29v/29vbn+fn5KQAAAAAAAAAAAADwAA//wAAAAOAAB//AAAAA
|
||||
wAAD/8AAAACAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/
|
||||
wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wADwAAAAA//AAOAA
|
||||
AAAB/8AAwAAAAAD/wACAAAAAAH/AAAAAAAAAP8AAAAAAAAA/wAAAAAAAAB/AAAAAAAAAD8AAAAAAAAAP
|
||||
wAAAAAAAAAfAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAHAAAAAAAAAAcAAAAAAAAABwAAAAAAAAADAAAAA
|
||||
AAAAAMAAAAAAAAAAwAAAAAAAAABAAAAAAAAAAEAAgAAAAAAAQADAAAAAAABAAP//gAAAAAAA///AAAAA
|
||||
AAD//+AAAAAAAP//8AAAAAAA///4AAAAAAD///4AAAAAAP///4AAAAAA////wAAAAAD////wAAAAAP//
|
||||
//4AAAAA/////8AAQAD/////+ADAAA==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
24
src/ClientLauncher/Program.cs
Normal file
24
src/ClientLauncher/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// <copyright file="Program.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.Windows.Forms;
|
||||
|
||||
/// <summary>
|
||||
/// The static main program.
|
||||
/// </summary>
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
internal static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
10
src/ClientLauncher/Properties/AssemblyInfo.cs
Normal file
10
src/ClientLauncher/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
// <copyright file="AssemblyInfo.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MUnique.OpenMU.ClientLauncher")]
|
||||
103
src/ClientLauncher/Properties/Resources.Designer.cs
generated
Normal file
103
src/ClientLauncher/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MUnique.OpenMU.ClientLauncher.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Add_16x {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Add_16x", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Edit_16x {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Edit_16x", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Remove_16x {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Remove_16x", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Settings_16x {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Settings_16x", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
133
src/ClientLauncher/Properties/Resources.resx
Normal file
133
src/ClientLauncher/Properties/Resources.resx
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="Add_16x" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Edit_16x" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Edit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Remove_16x" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Remove.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Settings_16x" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Settings_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
src/ClientLauncher/Resources/Add.png
Normal file
BIN
src/ClientLauncher/Resources/Add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 301 B |
BIN
src/ClientLauncher/Resources/Edit.png
Normal file
BIN
src/ClientLauncher/Resources/Edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 567 B |
BIN
src/ClientLauncher/Resources/Remove.png
Normal file
BIN
src/ClientLauncher/Resources/Remove.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 293 B |
BIN
src/ClientLauncher/Resources/Settings_16x.png
Normal file
BIN
src/ClientLauncher/Resources/Settings_16x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 480 B |
BIN
src/ClientLauncher/Rocket_16x.ico
Normal file
BIN
src/ClientLauncher/Rocket_16x.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
90
src/ClientLauncher/ServerHostSettings.cs
Normal file
90
src/ClientLauncher/ServerHostSettings.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
// <copyright file="ServerHostSettings.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.ClientLauncher;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for one server.
|
||||
/// </summary>
|
||||
public class ServerHostSettings : INotifyPropertyChanged
|
||||
{
|
||||
private string? _description;
|
||||
private string? _address;
|
||||
private int _port;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the configuration.
|
||||
/// </summary>
|
||||
public string? Description
|
||||
{
|
||||
get => this._description;
|
||||
set
|
||||
{
|
||||
if (value == this._description)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._description = value;
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the host ip.
|
||||
/// </summary>
|
||||
public string? Address
|
||||
{
|
||||
get => this._address;
|
||||
set
|
||||
{
|
||||
if (value == this._address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._address = value;
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the host port.
|
||||
/// </summary>
|
||||
public int Port
|
||||
{
|
||||
get => this._port;
|
||||
set
|
||||
{
|
||||
if (value == this._port)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._port = value;
|
||||
this.RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Description} ({this.Address}:{this.Port})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="PropertyChanged"/> event for the specified property.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">The name of the property.</param>
|
||||
protected virtual void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user