Merge branch 'AM2R-Community-Developers:main' into main

pull/32/head
Miepee 5 years ago committed by GitHub
commit 5c89e76590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ApplicationIcon>Resources\LauncherIcon.ico</ApplicationIcon> <ApplicationIcon>Resources\LauncherIcon.ico</ApplicationIcon>
<Authors>Lojemiru, Miepee</Authors> <Authors>Lojemiru, Miepee</Authors>
<Company>AM2R-Community-Developers</Company> <Company>AM2R-Community-Developers</Company>

@ -1,9 +1,10 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// the code is regenerated. // der Code erneut generiert wird.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -11,32 +12,46 @@ namespace AM2RLauncher.Language {
using System; using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] /// <summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()] /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()] /// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Text { public class Text {
private static System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Text() { internal Text() {
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
public static System.Resources.ResourceManager ResourceManager { /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.Equals(null, resourceMan)) { if (object.ReferenceEquals(resourceMan, null)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("AM2RLauncher.Language.Text", typeof(Text).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AM2RLauncher.Language.Text", typeof(Text).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
public static System.Globalization.CultureInfo Culture { /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@ -45,538 +60,809 @@ namespace AM2RLauncher.Language {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ABORT ähnelt.
/// </summary>
public static string Abort { public static string Abort {
get { get {
return ResourceManager.GetString("Abort", resourceCulture); return ResourceManager.GetString("Abort", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ADD NEW MOD ähnelt.
/// </summary>
public static string AddNewMod { public static string AddNewMod {
get { get {
return ResourceManager.GetString("AddNewMod", resourceCulture); return ResourceManager.GetString("AddNewMod", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select a mod to be installed. ähnelt.
/// </summary>
public static string AddNewModToolTip { public static string AddNewModToolTip {
get { get {
return ResourceManager.GetString("AddNewModToolTip", resourceCulture); return ResourceManager.GetString("AddNewModToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Can&apos;t create an APK. ähnelt.
/// </summary>
public static string ApkButtonDisabledToolTip { public static string ApkButtonDisabledToolTip {
get { get {
return ResourceManager.GetString("ApkButtonDisabledToolTip", resourceCulture); return ResourceManager.GetString("ApkButtonDisabledToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Create an APK for $NAME ähnelt.
/// </summary>
public static string ApkButtonEnabledToolTip { public static string ApkButtonEnabledToolTip {
get { get {
return ResourceManager.GetString("ApkButtonEnabledToolTip", resourceCulture); return ResourceManager.GetString("ApkButtonEnabledToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Do you want to archive $NAME? ähnelt.
/// </summary>
public static string ArchiveMod {
get {
return ResourceManager.GetString("ArchiveMod", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die This is an archive of a previously installed Community Update. It cannot be re-installed and will remove itself if its game files are deleted. It shares saves with the currently installed Community Updates, so be sure to create a backup of your saves before running this profile! ähnelt.
/// </summary>
public static string ArchiveNotesCommunityUpdates { public static string ArchiveNotesCommunityUpdates {
get { get {
return ResourceManager.GetString("ArchiveNotesCommunityUpdates", resourceCulture); return ResourceManager.GetString("ArchiveNotesCommunityUpdates", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die This is an archive of a previously installed Mod. It cannot be re-installed and will remove itself if its game files are deleted. ähnelt.
/// </summary>
public static string ArchiveNotesMods {
get {
return ResourceManager.GetString("ArchiveNotesMods", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Author(s): ähnelt.
/// </summary>
public static string Author { public static string Author {
get { get {
return ResourceManager.GetString("Author", resourceCulture); return ResourceManager.GetString("Author", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Automatically update AM2R ähnelt.
/// </summary>
public static string AutoUpdateAM2R { public static string AutoUpdateAM2R {
get { get {
return ResourceManager.GetString("AutoUpdateAM2R", resourceCulture); return ResourceManager.GetString("AutoUpdateAM2R", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Automatically update the AM2RLauncher ähnelt.
/// </summary>
public static string AutoUpdateLauncher { public static string AutoUpdateLauncher {
get { get {
return ResourceManager.GetString("AutoUpdateLauncher", resourceCulture); return ResourceManager.GetString("AutoUpdateLauncher", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Changelog ähnelt.
/// </summary>
public static string ChangelogTab { public static string ChangelogTab {
get { get {
return ResourceManager.GetString("ChangelogTab", resourceCulture); return ResourceManager.GetString("ChangelogTab", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Are you sure you want to cancel this now? This will delete all your progress! ähnelt.
/// </summary>
public static string CloseOnCloningText { public static string CloseOnCloningText {
get { get {
return ResourceManager.GetString("CloseOnCloningText", resourceCulture); return ResourceManager.GetString("CloseOnCloningText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Sorry, you can&apos;t close this while it&apos;s installing! Please wait until it&apos;s finished. ähnelt.
/// </summary>
public static string CloseOnInstallingText { public static string CloseOnInstallingText {
get { get {
return ResourceManager.GetString("CloseOnInstallingText", resourceCulture); return ResourceManager.GetString("CloseOnInstallingText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die There was a problem with your Patchdata folder. It has been deleted, please download it again. ähnelt.
/// </summary>
public static string CorruptPatchData { public static string CorruptPatchData {
get { get {
return ResourceManager.GetString("CorruptPatchData", resourceCulture); return ResourceManager.GetString("CorruptPatchData", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die CREATE APK ähnelt.
/// </summary>
public static string CreateAPK { public static string CreateAPK {
get { get {
return ResourceManager.GetString("CreateAPK", resourceCulture); return ResourceManager.GetString("CreateAPK", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die CREATING APK ähnelt.
/// </summary>
public static string CreatingAPK { public static string CreatingAPK {
get { get {
return ResourceManager.GetString("CreatingAPK", resourceCulture); return ResourceManager.GetString("CreatingAPK", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Current profile: ähnelt.
/// </summary>
public static string CurrentProfile { public static string CurrentProfile {
get { get {
return ResourceManager.GetString("CurrentProfile", resourceCulture); return ResourceManager.GetString("CurrentProfile", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Enter custom game environment variables: ähnelt.
/// </summary>
public static string CustomEnvVarLabel { public static string CustomEnvVarLabel {
get { get {
return ResourceManager.GetString("CustomEnvVarLabel", resourceCulture); return ResourceManager.GetString("CustomEnvVarLabel", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Use custom download mirror ähnelt.
/// </summary>
public static string CustomMirrorCheck { public static string CustomMirrorCheck {
get { get {
return ResourceManager.GetString("CustomMirrorCheck", resourceCulture); return ResourceManager.GetString("CustomMirrorCheck", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME couldn&apos;t be deleted. ähnelt.
/// </summary>
public static string DeleteModButtonCantDelete { public static string DeleteModButtonCantDelete {
get { get {
return ResourceManager.GetString("DeleteModButtonCantDelete", resourceCulture); return ResourceManager.GetString("DeleteModButtonCantDelete", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME was successfully deleted! ähnelt.
/// </summary>
public static string DeleteModButtonSuccess { public static string DeleteModButtonSuccess {
get { get {
return ResourceManager.GetString("DeleteModButtonSuccess", resourceCulture); return ResourceManager.GetString("DeleteModButtonSuccess", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die DELETE MOD ähnelt.
/// </summary>
public static string DeleteModButtonText { public static string DeleteModButtonText {
get { get {
return ResourceManager.GetString("DeleteModButtonText", resourceCulture); return ResourceManager.GetString("DeleteModButtonText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Delete $NAME. ähnelt.
/// </summary>
public static string DeleteModButtonToolTip { public static string DeleteModButtonToolTip {
get { get {
return ResourceManager.GetString("DeleteModButtonToolTip", resourceCulture); return ResourceManager.GetString("DeleteModButtonToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die This will delete all files for $NAME. Are you sure you want to continue? ähnelt.
/// </summary>
public static string DeleteModWarning { public static string DeleteModWarning {
get { get {
return ResourceManager.GetString("DeleteModWarning", resourceCulture); return ResourceManager.GetString("DeleteModWarning", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The Official AM2R Discord ähnelt.
/// </summary>
public static string DiscordToolTip { public static string DiscordToolTip {
get { get {
return ResourceManager.GetString("DiscordToolTip", resourceCulture); return ResourceManager.GetString("DiscordToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die DOWNLOAD ähnelt.
/// </summary>
public static string Download { public static string Download {
get { get {
return ResourceManager.GetString("Download", resourceCulture); return ResourceManager.GetString("Download", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die DOWNLOADING ähnelt.
/// </summary>
public static string Downloading { public static string Downloading {
get { get {
return ResourceManager.GetString("Downloading", resourceCulture); return ResourceManager.GetString("Downloading", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Download source: ähnelt.
/// </summary>
public static string DownloadSource { public static string DownloadSource {
get { get {
return ResourceManager.GetString("DownloadSource", resourceCulture); return ResourceManager.GetString("DownloadSource", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Error ähnelt.
/// </summary>
public static string ErrorWindowTitle { public static string ErrorWindowTitle {
get { get {
return ResourceManager.GetString("ErrorWindowTitle", resourceCulture); return ResourceManager.GetString("ErrorWindowTitle", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The Community-Developers Github Page ähnelt.
/// </summary>
public static string GithubToolTip { public static string GithubToolTip {
get { get {
return ResourceManager.GetString("GithubToolTip", resourceCulture); return ResourceManager.GetString("GithubToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Use high quality music when patching to Android ähnelt.
/// </summary>
public static string HighQualityAndroid { public static string HighQualityAndroid {
get { get {
return ResourceManager.GetString("HighQualityAndroid", resourceCulture); return ResourceManager.GetString("HighQualityAndroid", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Use high quality music when patching to PC ähnelt.
/// </summary>
public static string HighQualityPC { public static string HighQualityPC {
get { get {
return ResourceManager.GetString("HighQualityPC", resourceCulture); return ResourceManager.GetString("HighQualityPC", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die INSTALL ähnelt.
/// </summary>
public static string Install { public static string Install {
get { get {
return ResourceManager.GetString("Install", resourceCulture); return ResourceManager.GetString("Install", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die INSTALLING ähnelt.
/// </summary>
public static string Installing { public static string Installing {
get { get {
return ResourceManager.GetString("Installing", resourceCulture); return ResourceManager.GetString("Installing", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Couldn&apos;t establish an internet connection! Try again later! ähnelt.
/// </summary>
public static string InternetConnectionDrop { public static string InternetConnectionDrop {
get { get {
return ResourceManager.GetString("InternetConnectionDrop", resourceCulture); return ResourceManager.GetString("InternetConnectionDrop", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME is an invalid git URL! ähnelt.
/// </summary>
public static string InvalidGitURL { public static string InvalidGitURL {
get { get {
return ResourceManager.GetString("InvalidGitURL", resourceCulture); return ResourceManager.GetString("InvalidGitURL", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Java not found! Cannot generate an APK without a Java installation. Please make sure that Java is installed and added to PATH. ähnelt.
/// </summary>
public static string JavaNotFound { public static string JavaNotFound {
get { get {
return ResourceManager.GetString("JavaNotFound", resourceCulture); return ResourceManager.GetString("JavaNotFound", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Launcher Language: (requires restart to take effect) ähnelt.
/// </summary>
public static string LanguageNotice { public static string LanguageNotice {
get { get {
return ResourceManager.GetString("LanguageNotice", resourceCulture); return ResourceManager.GetString("LanguageNotice", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Settings ähnelt.
/// </summary>
public static string LauncherSettingsTab { public static string LauncherSettingsTab {
get { get {
return ResourceManager.GetString("LauncherSettingsTab", resourceCulture); return ResourceManager.GetString("LauncherSettingsTab", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die GitHub (Primary) ähnelt.
/// </summary>
public static string MirrorGithubText { public static string MirrorGithubText {
get { get {
return ResourceManager.GetString("MirrorGithubText", resourceCulture); return ResourceManager.GetString("MirrorGithubText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die GitLab (Mirror) ähnelt.
/// </summary>
public static string MirrorGitlabText { public static string MirrorGitlabText {
get { get {
return ResourceManager.GetString("MirrorGitlabText", resourceCulture); return ResourceManager.GetString("MirrorGitlabText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME is already installed! ähnelt.
/// </summary>
public static string ModIsAlreadyInstalledMessage { public static string ModIsAlreadyInstalledMessage {
get { get {
return ResourceManager.GetString("ModIsAlreadyInstalledMessage", resourceCulture); return ResourceManager.GetString("ModIsAlreadyInstalledMessage", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME cannot be installed! It&apos;s for $OS. Download the $CURRENTOS version instead if it exists, or ask the mod authors to make one. ähnelt.
/// </summary>
public static string ModIsForWrongOS { public static string ModIsForWrongOS {
get { get {
return ResourceManager.GetString("ModIsForWrongOS", resourceCulture); return ResourceManager.GetString("ModIsForWrongOS", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME is an invalid AM2R mod! ähnelt.
/// </summary>
public static string ModIsInvalidMessage { public static string ModIsInvalidMessage {
get { get {
return ResourceManager.GetString("ModIsInvalidMessage", resourceCulture); return ResourceManager.GetString("ModIsInvalidMessage", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Mod Settings ähnelt.
/// </summary>
public static string ModSettingsTab {
get {
return ResourceManager.GetString("ModSettingsTab", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $NAME was successfully added! Go to the Play Tab in order to install it! ähnelt.
/// </summary>
public static string ModSuccessfullyInstalledMessage { public static string ModSuccessfullyInstalledMessage {
get { get {
return ResourceManager.GetString("ModSuccessfullyInstalledMessage", resourceCulture); return ResourceManager.GetString("ModSuccessfullyInstalledMessage", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die News ähnelt.
/// </summary>
public static string NewsTab { public static string NewsTab {
get { get {
return ResourceManager.GetString("NewsTab", resourceCulture); return ResourceManager.GetString("NewsTab", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Couldn&apos;t establish an internet connection! You can still play the game, but updates will not occur until the launcher is restarted and can connect to the internet. ähnelt.
/// </summary>
public static string NoInternetConnection { public static string NoInternetConnection {
get { get {
return ResourceManager.GetString("NoInternetConnection", resourceCulture); return ResourceManager.GetString("NoInternetConnection", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die OPEN PROFILE FOLDER ähnelt.
/// </summary>
public static string OpenProfileFolder { public static string OpenProfileFolder {
get { get {
return ResourceManager.GetString("OpenProfileFolder", resourceCulture); return ResourceManager.GetString("OpenProfileFolder", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Opens the folder where game files are located for $NAME. ähnelt.
/// </summary>
public static string OpenProfileFolderToolTip { public static string OpenProfileFolderToolTip {
get { get {
return ResourceManager.GetString("OpenProfileFolderToolTip", resourceCulture); return ResourceManager.GetString("OpenProfileFolderToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die OPEN PROFILE SAVE FOLDER ähnelt.
/// </summary>
public static string OpenSaveFolder { public static string OpenSaveFolder {
get { get {
return ResourceManager.GetString("OpenSaveFolder", resourceCulture); return ResourceManager.GetString("OpenSaveFolder", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Opens the folder where save files are located for $NAME. ähnelt.
/// </summary>
public static string OpenSaveFolderToolTip { public static string OpenSaveFolderToolTip {
get { get {
return ResourceManager.GetString("OpenSaveFolderToolTip", resourceCulture); return ResourceManager.GetString("OpenSaveFolderToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die PLAY ähnelt.
/// </summary>
public static string Play { public static string Play {
get { get {
return ResourceManager.GetString("Play", resourceCulture); return ResourceManager.GetString("Play", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Currently downloading . . . ähnelt.
/// </summary>
public static string PlayButtonDownladingToolTip { public static string PlayButtonDownladingToolTip {
get { get {
return ResourceManager.GetString("PlayButtonDownladingToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonDownladingToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Download the necessary patch files. ähnelt.
/// </summary>
public static string PlayButtonDownloadToolTip { public static string PlayButtonDownloadToolTip {
get { get {
return ResourceManager.GetString("PlayButtonDownloadToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonDownloadToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Currently installing. . . ähnelt.
/// </summary>
public static string PlayButtonInstallingToolTip { public static string PlayButtonInstallingToolTip {
get { get {
return ResourceManager.GetString("PlayButtonInstallingToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonInstallingToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Install $NAME ähnelt.
/// </summary>
public static string PlayButtonInstallToolTip { public static string PlayButtonInstallToolTip {
get { get {
return ResourceManager.GetString("PlayButtonInstallToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonInstallToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Currently already playing! ähnelt.
/// </summary>
public static string PlayButtonPlayingToolTip { public static string PlayButtonPlayingToolTip {
get { get {
return ResourceManager.GetString("PlayButtonPlayingToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonPlayingToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Play ähnelt.
/// </summary>
public static string PlayButtonPlayToolTip { public static string PlayButtonPlayToolTip {
get { get {
return ResourceManager.GetString("PlayButtonPlayToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonPlayToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select your AM2R_1.1.zip ähnelt.
/// </summary>
public static string PlayButtonSelect11ToolTip { public static string PlayButtonSelect11ToolTip {
get { get {
return ResourceManager.GetString("PlayButtonSelect11ToolTip", resourceCulture); return ResourceManager.GetString("PlayButtonSelect11ToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die PLAYING ähnelt.
/// </summary>
public static string Playing { public static string Playing {
get { get {
return ResourceManager.GetString("Playing", resourceCulture); return ResourceManager.GetString("Playing", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Play ähnelt.
/// </summary>
public static string PlayTab { public static string PlayTab {
get { get {
return ResourceManager.GetString("PlayTab", resourceCulture); return ResourceManager.GetString("PlayTab", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Create game debug logs ähnelt.
/// </summary>
public static string ProfileDebugCheckBox { public static string ProfileDebugCheckBox {
get { get {
return ResourceManager.GetString("ProfileDebugCheckBox", resourceCulture); return ResourceManager.GetString("ProfileDebugCheckBox", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Profile notes: ähnelt.
/// </summary>
public static string ProfileNotes { public static string ProfileNotes {
get { get {
return ResourceManager.GetString("ProfileNotes", resourceCulture); return ResourceManager.GetString("ProfileNotes", resourceCulture);
} }
} }
public static string ProfileSettingsTab { /// <summary>
get { /// Sucht eine lokalisierte Zeichenfolge, die Progress: ähnelt.
return ResourceManager.GetString("ProfileSettingsTab", resourceCulture); /// </summary>
}
}
public static string ProgressbarProgress { public static string ProgressbarProgress {
get { get {
return ResourceManager.GetString("ProgressbarProgress", resourceCulture); return ResourceManager.GetString("ProgressbarProgress", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The Official AM2R Subreddit ähnelt.
/// </summary>
public static string RedditToolTip { public static string RedditToolTip {
get { get {
return ResourceManager.GetString("RedditToolTip", resourceCulture); return ResourceManager.GetString("RedditToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die WARNING: This profile uses the default save location! This could corrupt your save data - please ensure that you have made a backup. ähnelt.
/// </summary>
public static string SaveLocationWarning { public static string SaveLocationWarning {
get { get {
return ResourceManager.GetString("SaveLocationWarning", resourceCulture); return ResourceManager.GetString("SaveLocationWarning", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die SELECT AM2R_1.1.zip ähnelt.
/// </summary>
public static string Select11 { public static string Select11 {
get { get {
return ResourceManager.GetString("Select11", resourceCulture); return ResourceManager.GetString("Select11", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select AM2R_1.1.zip ähnelt.
/// </summary>
public static string Select11FileDialog { public static string Select11FileDialog {
get { get {
return ResourceManager.GetString("Select11FileDialog", resourceCulture); return ResourceManager.GetString("Select11FileDialog", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select your Mod ähnelt.
/// </summary>
public static string SelectModFileDialog { public static string SelectModFileDialog {
get { get {
return ResourceManager.GetString("SelectModFileDialog", resourceCulture); return ResourceManager.GetString("SelectModFileDialog", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Success ähnelt.
/// </summary>
public static string SuccessWindowTitle { public static string SuccessWindowTitle {
get { get {
return ResourceManager.GetString("SuccessWindowTitle", resourceCulture); return ResourceManager.GetString("SuccessWindowTitle", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die System Language ähnelt.
/// </summary>
public static string SystemLanguage { public static string SystemLanguage {
get { get {
return ResourceManager.GetString("SystemLanguage", resourceCulture); return ResourceManager.GetString("SystemLanguage", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Show Launcher ähnelt.
/// </summary>
public static string TrayButtonShow { public static string TrayButtonShow {
get { get {
return ResourceManager.GetString("TrayButtonShow", resourceCulture); return ResourceManager.GetString("TrayButtonShow", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Can&apos;t access the Folder in order to download the update! Consider moving the program, or disabling auto-updates. ähnelt.
/// </summary>
public static string UnauthorizedAccessMessage { public static string UnauthorizedAccessMessage {
get { get {
return ResourceManager.GetString("UnauthorizedAccessMessage", resourceCulture); return ResourceManager.GetString("UnauthorizedAccessMessage", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Unhandled Exception has occured in your Application. ähnelt.
/// </summary>
public static string UnhandledException { public static string UnhandledException {
get { get {
return ResourceManager.GetString("UnhandledException", resourceCulture); return ResourceManager.GetString("UnhandledException", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select Mod Update ähnelt.
/// </summary>
public static string UpdateMod { public static string UpdateMod {
get { get {
return ResourceManager.GetString("UpdateMod", resourceCulture); return ResourceManager.GetString("UpdateMod", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die UPDATE MOD ähnelt.
/// </summary>
public static string UpdateModButtonText { public static string UpdateModButtonText {
get { get {
return ResourceManager.GetString("UpdateModButtonText", resourceCulture); return ResourceManager.GetString("UpdateModButtonText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Select a zip to update $NAME. ähnelt.
/// </summary>
public static string UpdateModButtonToolTip { public static string UpdateModButtonToolTip {
get { get {
return ResourceManager.GetString("UpdateModButtonToolTip", resourceCulture); return ResourceManager.GetString("UpdateModButtonToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Can&apos;t update $NAME with $SELECT. Add $SELECT as a new mod instead! ähnelt.
/// </summary>
public static string UpdateModButtonWrongMod { public static string UpdateModButtonWrongMod {
get { get {
return ResourceManager.GetString("UpdateModButtonWrongMod", resourceCulture); return ResourceManager.GetString("UpdateModButtonWrongMod", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die This will replace all files for $NAME with the selected new version. Are you sure you want to continue? ähnelt.
/// </summary>
public static string UpdateModWarning { public static string UpdateModWarning {
get { get {
return ResourceManager.GetString("UpdateModWarning", resourceCulture); return ResourceManager.GetString("UpdateModWarning", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Version: ähnelt.
/// </summary>
public static string VersionLabel { public static string VersionLabel {
get { get {
return ResourceManager.GetString("VersionLabel", resourceCulture); return ResourceManager.GetString("VersionLabel", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die OK ähnelt.
/// </summary>
public static string WarningWindowOk { public static string WarningWindowOk {
get { get {
return ResourceManager.GetString("WarningWindowOk", resourceCulture); return ResourceManager.GetString("WarningWindowOk", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The AM2RLauncher can NOT validate custom mirror links.
///
///If somebody is telling you to paste a link in this field, they may be trying to infect your computer.
///
///Proceed with caution. ähnelt.
/// </summary>
public static string WarningWindowText { public static string WarningWindowText {
get { get {
return ResourceManager.GetString("WarningWindowText", resourceCulture); return ResourceManager.GetString("WarningWindowText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die WARNING ähnelt.
/// </summary>
public static string WarningWindowTitle { public static string WarningWindowTitle {
get { get {
return ResourceManager.GetString("WarningWindowTitle", resourceCulture); return ResourceManager.GetString("WarningWindowTitle", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Xdelta not found! Cannot install Profiles without it. Please install xdelta3 from your local package manager. ähnelt.
/// </summary>
public static string XdeltaNotFound { public static string XdeltaNotFound {
get { get {
return ResourceManager.GetString("XdeltaNotFound", resourceCulture); return ResourceManager.GetString("XdeltaNotFound", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The Community-Developers YouTube Channel ähnelt.
/// </summary>
public static string YoutubeToolTip { public static string YoutubeToolTip {
get { get {
return ResourceManager.GetString("YoutubeToolTip", resourceCulture); return ResourceManager.GetString("YoutubeToolTip", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Zip Archives (*.zip) ähnelt.
/// </summary>
public static string ZipArchiveText { public static string ZipArchiveText {
get { get {
return ResourceManager.GetString("ZipArchiveText", resourceCulture); return ResourceManager.GetString("ZipArchiveText", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The selected Zip is not AM2R 1.1! Please choose another Zip file. ähnelt.
/// </summary>
public static string ZipIsNotAM2R11 { public static string ZipIsNotAM2R11 {
get { get {
return ResourceManager.GetString("ZipIsNotAM2R11", resourceCulture); return ResourceManager.GetString("ZipIsNotAM2R11", resourceCulture);
} }
} }
public static string ArchiveMod {
get {
return ResourceManager.GetString("ArchiveMod", resourceCulture);
}
}
public static string ArchiveNotesMods {
get {
return ResourceManager.GetString("ArchiveNotesMods", resourceCulture);
}
}
} }
} }

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Profilnotizen:</value> <value>Profilnotizen:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Mod-Einstellungen</value> <value>Mod-Einstellungen</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Anotaciones del Perfil:</value> <value>Anotaciones del Perfil:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Opciones de mods</value> <value>Opciones de mods</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -305,7 +305,7 @@ ce profil !</value>
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Notes de profil :</value> <value>Notes de profil :</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Paramètres du mod</value> <value>Paramètres du mod</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Note di profilo:</value> <value>Note di profilo:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Impostazioni mod</value> <value>Impostazioni mod</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>プロファイルの注釈:</value> <value>プロファイルの注釈:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>MOD設定</value> <value>MOD設定</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -300,7 +300,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Notas do perfil:</value> <value>Notas do perfil:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Configurações de mod</value> <value>Configurações de mod</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Profile notes:</value> <value>Profile notes:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Mod Settings</value> <value>Mod Settings</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>Заметки профиля:</value> <value>Заметки профиля:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Настройки модификаций</value> <value>Настройки модификаций</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

@ -303,7 +303,7 @@
<data name="ProfileNotes" xml:space="preserve"> <data name="ProfileNotes" xml:space="preserve">
<value>游戏实例说明:</value> <value>游戏实例说明:</value>
</data> </data>
<data name="ProfileSettingsTab" xml:space="preserve"> <data name="ModSettingsTab" xml:space="preserve">
<value>Mod 设置</value> <value>Mod 设置</value>
</data> </data>
<data name="ProgressbarProgress" xml:space="preserve"> <data name="ProgressbarProgress" xml:space="preserve">

File diff suppressed because it is too large Load Diff

@ -1,4 +1,8 @@
using Eto.Forms; using AM2RLauncher.Core;
using AM2RLauncher.Language;
using Eto.Forms;
using LibGit2Sharp;
using System;
namespace AM2RLauncher namespace AM2RLauncher
{ {
@ -34,9 +38,52 @@ namespace AM2RLauncher
/// Safety check function before accessing <see cref="profileIndex"/>. /// Safety check function before accessing <see cref="profileIndex"/>.
/// </summary> /// </summary>
/// <returns><see langword="true"/> if it is valid, <see langword="false"/> if not.</returns> /// <returns><see langword="true"/> if it is valid, <see langword="false"/> if not.</returns>
//TODO: this should get a "membernotnullwhen" atttribute whenever i figure out how to apply it here
private bool IsProfileIndexValid() private bool IsProfileIndexValid()
{ {
return profileIndex != null; return profileIndex != null;
} }
/// <summary>
/// This is just a helper method for the git commands in order to have a progress bar display for them.
/// </summary>
private bool TransferProgressHandlerMethod(TransferProgress transferProgress)
{
// Thank you random issue on the gitlib2sharp repo!!!!
// Also tldr; rtfm
if (isGitProcessGettingCancelled) return false;
// This needs to be in an Invoke, in order to access the variables from the main thread
// Otherwise this will throw a runtime exception
Application.Instance.Invoke(() =>
{
progressBar.MinValue = 0;
progressBar.MaxValue = transferProgress.TotalObjects;
if (currentGitObject >= transferProgress.ReceivedObjects)
return;
progressLabel.Text = Text.ProgressbarProgress + " " + transferProgress.ReceivedObjects + " (" + ((int)transferProgress.ReceivedBytes / 1000000) + "MB) / " + transferProgress.TotalObjects + " objects";
currentGitObject = transferProgress.ReceivedObjects;
progressBar.Value = transferProgress.ReceivedObjects;
});
return true;
}
/// <summary>
/// Creates a single-file, zip-filtered file dialog.
/// </summary>
/// <param name="title">The title of the file dialog.</param>
/// <returns>The created file dialog.</returns>
private OpenFileDialog GetSingleZipDialog(string title = "")
{
OpenFileDialog fileDialog = new OpenFileDialog
{
Directory = new Uri(CrossPlatformOperations.CURRENTPATH),
MultiSelect = false,
Title = title
};
fileDialog.Filters.Add(new FileFilter(Text.ZipArchiveText, ".zip"));
return fileDialog;
}
} }
} }

@ -2,6 +2,7 @@
using System; using System;
using AM2RLauncher.Core; using AM2RLauncher.Core;
using AM2RLauncher.Core.XML; using AM2RLauncher.Core.XML;
using AM2RLauncher.Language;
namespace AM2RLauncher namespace AM2RLauncher
{ {
@ -18,61 +19,56 @@ namespace AM2RLauncher
UpdatePlayState(); UpdatePlayState();
UpdateApkState(); UpdateApkState();
UpdateProfileState(); UpdateProfileState();
UpdateProfileSettingsState(); UpdateModSettingsState();
} }
/// <summary> /// <summary>
/// Determines current conditions and calls <see cref="SetPlayButtonState(UpdateState)"/> accordingly. /// Determines current conditions and calls <see cref="SetPlayButtonState(PlayButtonState)"/> accordingly.
/// </summary> /// </summary>
private void UpdatePlayState() private void UpdatePlayState()
{ {
// If not downloading or installing... // If we're downloading or installing, dont't change anything
if ((updateState == UpdateState.Downloading) || (updateState == UpdateState.Installing)) if ((updateState == PlayButtonState.Downloading) || (updateState == PlayButtonState.Installing))
return; return;
// If we're currently creating an APK... // If we're currently creating an APK, we disable the play button
if (apkButtonState != ApkButtonState.Creating) if (apkButtonState == ApkButtonState.Creating)
{ {
playButton.Enabled = true; playButton.Enabled = false;
// If PatchData is cloned... return;
if (Profile.IsPatchDataCloned()) }
{
// If 1.1 is installed or if the current profile is invalid... playButton.Enabled = true;
if (Profile.Is11Installed()) // If PatchData isn't cloned, we still need to download
{ if (!Profile.IsPatchDataCloned())
var isProfileValid = IsProfileIndexValid(); {
// If current profile is installed... SetPlayButtonState(PlayButtonState.Download);
if (isProfileValid && Profile.IsProfileInstalled(profileList[profileIndex.Value])) return;
{
// We're ready to play!
SetPlayButtonState(UpdateState.Play);
}
// Otherwise, if profile is NOT installable...
else if (isProfileValid && profileList[profileIndex.Value].Installable == false)
{
// We delete the profile, because we can't install it and it therefore holds no value!
DeleteProfileAndAdjustLists(profileList[profileIndex.Value]);
}
// Otherwise, we still need to install.
else
{
SetPlayButtonState(UpdateState.Install);
}
}
else // We still need to select 1.1.
{
SetPlayButtonState(UpdateState.Select11);
}
}
else // We still need to download.
{
SetPlayButtonState(UpdateState.Download);
}
} }
else // We disable the Play button.
// If 1.1 isn't installed, we still need to select it
if (!Profile.Is11Installed())
{ {
playButton.Enabled = false; SetPlayButtonState(PlayButtonState.Select11);
return;
}
var isProfileValid = IsProfileIndexValid();
// If current profile is installed, we're ready to play!
if (isProfileValid && Profile.IsProfileInstalled(profileList[profileIndex.Value]))
{
SetPlayButtonState(PlayButtonState.Play);
return;
} }
// Otherwise, if profile is NOT installable, we delete the profile because we can't install it and therefore holds no value!
else if (isProfileValid && profileList[profileIndex.Value].Installable == false)
{
DeleteProfileAndAdjustLists(profileList[profileIndex.Value]);
return;
}
// Otherwise, we still need to install.
SetPlayButtonState(PlayButtonState.Install);
} }
/// <summary> /// <summary>
@ -83,30 +79,31 @@ namespace AM2RLauncher
// Safety check // Safety check
if (apkButton == null) if (apkButton == null)
return; return;
// Our default values
apkButton.Enabled = false;
apkButton.ToolTip = Text.ApkButtonDisabledToolTip;
// If profile supports Android and if we are NOT already creating an APK... // If profile supports Android and if we are NOT already creating an APK...
if (IsProfileIndexValid()) if (!IsProfileIndexValid())
return;
var profile = profileList[profileIndex.Value];
if (!profile.SupportsAndroid || !profile.Installable || apkButtonState != ApkButtonState.Create)
return;
// Switch status based on main button's state
switch (updateState)
{ {
var profile = profileList[profileIndex.Value]; case PlayButtonState.Download:
if (profile.SupportsAndroid && profile.Installable && (apkButtonState == ApkButtonState.Create)) case PlayButtonState.Downloading:
{ case PlayButtonState.Select11:
// Switch status based on main button's state case PlayButtonState.Installing:
switch (updateState) case PlayButtonState.Playing: return;
{
case UpdateState.Download: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break; case PlayButtonState.Install:
case UpdateState.Downloading: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break; case PlayButtonState.Play: apkButton.Enabled = true; apkButton.ToolTip = HelperMethods.GetText(Text.ApkButtonEnabledToolTip, profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Select11: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Install: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Installing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Play: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Playing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
}
return;
}
} }
apkButton.Enabled = false;
apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip;
} }
/// <summary> /// <summary>
@ -119,18 +116,17 @@ namespace AM2RLauncher
return; return;
switch (updateState) switch (updateState)
{ {
case UpdateState.Download: profileDropDown.Enabled = false; break; case PlayButtonState.Download:
case UpdateState.Downloading: profileDropDown.Enabled = false; break; case PlayButtonState.Downloading:
case UpdateState.Select11: profileDropDown.Enabled = true; break; case PlayButtonState.Select11:
case UpdateState.Install: profileDropDown.Enabled = true; break; case PlayButtonState.Installing:
case UpdateState.Installing: profileDropDown.Enabled = false; break; case PlayButtonState.Playing: profileDropDown.Enabled = false; break;
case UpdateState.Play: profileDropDown.Enabled = true; break;
case UpdateState.Playing: profileDropDown.Enabled = false; break; case PlayButtonState.Install:
} case PlayButtonState.Play: profileDropDown.Enabled = true; break;
switch (apkButtonState)
{
case ApkButtonState.Creating: profileDropDown.Enabled = false; break;
} }
if (apkButtonState == ApkButtonState.Creating) profileDropDown.Enabled = false;
Color col = profileDropDown.Enabled ? colGreen : colInactive; Color col = profileDropDown.Enabled ? colGreen : colInactive;
@ -144,79 +140,81 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// Determines current conditions and enables or disables <see cref="profilePage"/> controls accordingly. /// Determines current conditions and enables or disables <see cref="profilePage"/> controls accordingly.
/// </summary> /// </summary>
private void UpdateProfileSettingsState() private void UpdateModSettingsState()
{ {
// Safety check // Safety check
if (settingsProfileDropDown == null || settingsProfileDropDown.Items.Count <= 0) return; if (modSettingsProfileDropDown == null || modSettingsProfileDropDown.Items.Count <= 0) return;
bool enabled = false; bool enabled = false;
switch (updateState) switch (updateState)
{ {
case UpdateState.Download: case PlayButtonState.Download:
case UpdateState.Downloading: case PlayButtonState.Downloading:
case UpdateState.Select11: case PlayButtonState.Select11:
case UpdateState.Installing: case PlayButtonState.Installing:
case UpdateState.Playing: enabled = false; break; case PlayButtonState.Playing: enabled = false; break;
case UpdateState.Install:
case UpdateState.Play: enabled = true; break; case PlayButtonState.Install:
case PlayButtonState.Play: enabled = true; break;
} }
if (apkButtonState == ApkButtonState.Creating) enabled = false; if (apkButtonState == ApkButtonState.Creating) enabled = false;
string selectedProfileName = modSettingsProfileDropDown.Items[modSettingsProfileDropDown.SelectedIndex].Text;
settingsProfileLabel.TextColor = colGreen; settingsProfileLabel.TextColor = colGreen;
settingsProfileDropDown.Enabled = enabled; modSettingsProfileDropDown.Enabled = enabled;
profileButton.Enabled = enabled; profileButton.Enabled = enabled;
profileButton.ToolTip = Language.Text.OpenProfileFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); profileButton.ToolTip = HelperMethods.GetText(Text.OpenProfileFolderToolTip, selectedProfileName);
saveButton.Enabled = enabled; saveButton.Enabled = enabled;
saveButton.ToolTip = Language.Text.OpenSaveFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); saveButton.ToolTip = HelperMethods.GetText(Text.OpenSaveFolderToolTip, selectedProfileName);
addModButton.Enabled = enabled; addModButton.Enabled = enabled;
addModButton.ToolTip = Language.Text.AddNewModToolTip; addModButton.ToolTip = Text.AddNewModToolTip;
// Only enable these, when we're not on the community updates // Only enable these, when we're not on the community updates
if (settingsProfileDropDown.SelectedIndex > 0) if (modSettingsProfileDropDown.SelectedIndex > 0)
{ {
updateModButton.Enabled = profileList[settingsProfileDropDown.SelectedIndex].Installable; updateModButton.Enabled = profileList[modSettingsProfileDropDown.SelectedIndex].Installable;
updateModButton.ToolTip = Language.Text.UpdateModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); updateModButton.ToolTip = HelperMethods.GetText(Text.UpdateModButtonToolTip, selectedProfileName);
deleteModButton.Enabled = enabled; deleteModButton.Enabled = enabled;
deleteModButton.ToolTip = Language.Text.DeleteModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); deleteModButton.ToolTip = HelperMethods.GetText(Text.DeleteModButtonToolTip, selectedProfileName);
} }
Color col = enabled ? colGreen : colInactive; Color col = enabled ? colGreen : colInactive;
if (OS.IsWindows) if (OS.IsWindows)
settingsProfileDropDown.TextColor = col; modSettingsProfileDropDown.TextColor = col;
settingsProfileLabel.TextColor = col; settingsProfileLabel.TextColor = col;
if (enabled) if (enabled)
{ modSettingsProfileDropDown.SelectedIndex = profileDropDown.SelectedIndex;
settingsProfileDropDown.SelectedIndex = profileDropDown.SelectedIndex;
}
} }
/// <summary> /// <summary>
/// Sets the global <see cref="updateState"/> and then changes the state of <see cref="playButton"/> accordingly. /// Sets the global <see cref="updateState"/> and then changes the state of <see cref="playButton"/> accordingly.
/// </summary> /// </summary>
/// <param name="state">The state that should be set to.</param> /// <param name="state">The state that should be set to.</param>
private void SetPlayButtonState(UpdateState state) private void SetPlayButtonState(PlayButtonState state)
{ {
updateState = state; updateState = state;
string profileName = ((profileDropDown != null) && (profileDropDown.Items.Count > 0)) ? profileDropDown.Items[profileDropDown.SelectedIndex].Text : "";
switch (updateState) switch (updateState)
{ {
case UpdateState.Download: playButton.Enabled = true; playButton.ToolTip = Language.Text.PlayButtonDownloadToolTip; break; case PlayButtonState.Download:
case UpdateState.Downloading: playButton.Enabled = true; playButton.ToolTip = ""; playButton.ToolTip = Language.Text.PlayButtonDownladingToolTip; break; case PlayButtonState.Downloading:
case UpdateState.Select11: playButton.Enabled = true; playButton.ToolTip = Language.Text.PlayButtonSelect11ToolTip; break; case PlayButtonState.Select11:
case UpdateState.Install: playButton.Enabled = true; playButton.ToolTip = Language.Text.PlayButtonInstallToolTip.Replace("$NAME", profileName); break; case PlayButtonState.Install:
case UpdateState.Installing: playButton.Enabled = false; playButton.ToolTip = Language.Text.PlayButtonInstallingToolTip; break; case PlayButtonState.Play: playButton.Enabled = true; break;
case UpdateState.Play: playButton.Enabled = true; playButton.ToolTip = Language.Text.PlayButtonPlayToolTip.Replace("$NAME", profileName); break;
case UpdateState.Playing: playButton.Enabled = false; playButton.ToolTip = Language.Text.PlayButtonPlayingToolTip; break; case PlayButtonState.Installing:
case PlayButtonState.Playing: playButton.Enabled = false; break;
} }
playButton.Text = GetPlayButtonText(); playButton.Text = GetPlayButtonText();
playButton.ToolTip = GetPlayButtonTooltip();
playButton.Invalidate(); playButton.Invalidate();
UpdateProfileSettingsState(); UpdateModSettingsState();
} }
/// <summary> /// <summary>
@ -242,13 +240,33 @@ namespace AM2RLauncher
{ {
switch (updateState) switch (updateState)
{ {
case UpdateState.Download: return Language.Text.Download; case PlayButtonState.Download: return Text.Download;
case UpdateState.Downloading: return Language.Text.Abort; case PlayButtonState.Downloading: return Text.Abort;
case UpdateState.Select11: return Language.Text.Select11; case PlayButtonState.Select11: return Text.Select11;
case UpdateState.Install: return Language.Text.Install; case PlayButtonState.Install: return Text.Install;
case UpdateState.Installing: return Language.Text.Installing; case PlayButtonState.Installing: return Text.Installing;
case UpdateState.Play: return Language.Text.Play; case PlayButtonState.Play: return Text.Play;
case UpdateState.Playing: return Language.Text.Playing; case PlayButtonState.Playing: return Text.Playing;
default: return null;
}
}
/// <summary>
/// This returns the tooltip that <see cref="playButton"/> should have depending on the global updateState.
/// </summary>
/// <returns>The tooltip as a <see cref="String"/>, or <see langword="null"/> if the current State is invalid.</returns>
private string GetPlayButtonTooltip()
{
string profileName = ((profileDropDown != null) && (profileDropDown.Items.Count > 0)) ? profileDropDown.Items[profileDropDown.SelectedIndex].Text : "";
switch (updateState)
{
case PlayButtonState.Download: return Text.PlayButtonDownloadToolTip;
case PlayButtonState.Downloading: return Text.PlayButtonDownloadToolTip;
case PlayButtonState.Select11: return Text.PlayButtonSelect11ToolTip;
case PlayButtonState.Install: return playButton.ToolTip = HelperMethods.GetText(Text.PlayButtonInstallToolTip, profileName);
case PlayButtonState.Installing: return Text.PlayButtonInstallingToolTip;
case PlayButtonState.Play: return HelperMethods.GetText(Text.PlayButtonPlayToolTip, profileName);
case PlayButtonState.Playing: return Text.PlayButtonPlayingToolTip;
default: return null; default: return null;
} }
} }
@ -261,8 +279,8 @@ namespace AM2RLauncher
{ {
switch (apkButtonState) switch (apkButtonState)
{ {
case ApkButtonState.Create: return Language.Text.CreateAPK; case ApkButtonState.Create: return Text.CreateAPK;
case ApkButtonState.Creating: return Language.Text.CreatingAPK; case ApkButtonState.Creating: return Text.CreatingAPK;
default: return null; default: return null;
} }
} }
@ -286,11 +304,10 @@ namespace AM2RLauncher
// Archive version notes // Archive version notes
if (!profile.Installable) if (!profile.Installable)
{ {
//TODO: localizations
if (profile.Name.Contains("Community Updates")) if (profile.Name.Contains("Community Updates"))
profile.ProfileNotes = Language.Text.ArchiveNotesCommunityUpdates; profile.ProfileNotes = Text.ArchiveNotesCommunityUpdates;
else else
profile.ProfileNotes = Language.Text.ArchiveNotesMods + "\n\n" + profile.ProfileNotes; profile.ProfileNotes = Text.ArchiveNotesMods + "\n\n" + profile.ProfileNotes;
} }
profileDropDown.Items.Add(profile.Name); profileDropDown.Items.Add(profile.Name);
@ -317,15 +334,15 @@ namespace AM2RLauncher
} }
// Update stored profiles in the Profile Settings tab // Update stored profiles in the Profile Settings tab
settingsProfileDropDown.Items.Clear(); modSettingsProfileDropDown.Items.Clear();
settingsProfileDropDown.Items.AddRange(profileDropDown.Items); modSettingsProfileDropDown.Items.AddRange(profileDropDown.Items);
settingsProfileDropDown.SelectedIndex = profileDropDown.Items.Count != 0 ? 0 : -1; modSettingsProfileDropDown.SelectedIndex = profileDropDown.Items.Count != 0 ? 0 : -1;
// Refresh the author and version label on the main tab // Refresh the author and version label on the main tab
if (profileList.Count > 0) if (profileList.Count > 0)
{ {
profileAuthorLabel.Text = Language.Text.Author + " " + profileList[profileDropDown.SelectedIndex].Author; profileAuthorLabel.Text = Text.Author + " " + profileList[profileDropDown.SelectedIndex].Author;
profileVersionLabel.Text = Language.Text.VersionLabel + " " + profileList[profileDropDown.SelectedIndex].Version; profileVersionLabel.Text = Text.VersionLabel + " " + profileList[profileDropDown.SelectedIndex].Version;
} }
log.Info("Reloading UI components after loading successful."); log.Info("Reloading UI components after loading successful.");
@ -349,5 +366,18 @@ namespace AM2RLauncher
Profile.ArchiveProfile(profile); Profile.ArchiveProfile(profile);
LoadProfilesAndAdjustLists(); LoadProfilesAndAdjustLists();
} }
/// <summary>Enables and changes colors for <see cref="customMirrorTextBox"/> and <see cref="mirrorDropDown"/> accordingly.</summary>
private void EnableMirrorControlsAccordingly()
{
bool enabled = (bool)customMirrorCheck.Checked;
customMirrorTextBox.Enabled = enabled;
mirrorDropDown.Enabled = !enabled;
// Not sure why the dropdown menu needs this hack, but the textBox does not.
//TODO: eto feature request
if (OS.IsWindows)
mirrorDropDown.TextColor = mirrorDropDown.Enabled ? colGreen : colInactive;
mirrorLabel.TextColor = !enabled ? colGreen : colInactive;
}
} }
} }

@ -1,5 +1,7 @@
using AM2RLauncher.Core; using AM2RLauncher.Core;
using AM2RLauncher.Core.XML; using AM2RLauncher.Core.XML;
using AM2RLauncher.Language;
using AM2RLauncher.Properties;
using Eto.Drawing; using Eto.Drawing;
using Eto.Forms; using Eto.Forms;
using log4net; using log4net;
@ -30,15 +32,11 @@ namespace AM2RLauncher
/// </summary> /// </summary>
private const string VERSION = LauncherUpdater.VERSION; private const string VERSION = LauncherUpdater.VERSION;
/// <summary>
/// A <see cref="Bitmap"/> of the AM2R icon.
/// </summary>
private static readonly Bitmap am2rIcon = new Bitmap(AM2RLauncher.Properties.Resources.AM2RIcon);
/// <summary> /// <summary>
/// An enum, that has possible states for our Launcher. /// An enum, that has possible states for the play button.
/// </summary> /// </summary>
public enum UpdateState public enum PlayButtonState
{ {
Download, Download,
Downloading, Downloading,
@ -61,7 +59,7 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// This variable has the current global state of the Launcher. /// This variable has the current global state of the Launcher.
/// </summary> /// </summary>
private static UpdateState updateState = UpdateState.Download; private static PlayButtonState updateState = PlayButtonState.Download;
/// <summary> /// <summary>
/// This variable has the current global statue of the <see cref="apkButton"/>. /// This variable has the current global statue of the <see cref="apkButton"/>.
/// </summary> /// </summary>
@ -100,13 +98,9 @@ namespace AM2RLauncher
if (OS.IsWindows) if (OS.IsWindows)
{ {
Process current = Process.GetCurrentProcess(); Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName)) Process process = Process.GetProcessesByName(current.ProcessName).First(p => p.Id == current.Id);
{ if (process != null)
if (process.Id == current.Id)
continue;
Core.Core.SetForegroundWindow(process.MainWindowHandle); Core.Core.SetForegroundWindow(process.MainWindowHandle);
break;
}
} }
Environment.Exit(0); Environment.Exit(0);
} }
@ -133,8 +127,10 @@ namespace AM2RLauncher
#region VARIABLE INITIALIZATION #region VARIABLE INITIALIZATION
log.Info("Beginning UI initialization..."); log.Info("Beginning UI initialization...");
Bitmap am2rIcon = new Bitmap(AM2RLauncher.Properties.Resources.AM2RIcon);
// System tray indicator // System tray indicator
showButton = new ButtonMenuItem { Text = Language.Text.TrayButtonShow }; ButtonMenuItem showButton = new ButtonMenuItem { Text = Text.TrayButtonShow };
trayIndicator = new TrayIndicator trayIndicator = new TrayIndicator
{ {
Menu = new ContextMenu(showButton), Menu = new ContextMenu(showButton),
@ -150,6 +146,7 @@ namespace AM2RLauncher
// Create array from validCount // Create array from validCount
profileList = new List<ProfileXML>(); profileList = new List<ProfileXML>();
//TODO: whenever profileDropDown gets rewritten to use a datastore, scrap this
profileNames = new List<ListItem>(); profileNames = new List<ListItem>();
foreach (var profile in profileList) foreach (var profile in profileList)
{ {
@ -160,22 +157,6 @@ namespace AM2RLauncher
string splash = Splash.GetSplash(); string splash = Splash.GetSplash();
log.Info("Randomly chosen splash: " + splash); log.Info("Randomly chosen splash: " + splash);
// Load bitmaps
redditIcon = new Bitmap(AM2RLauncher.Properties.Resources.redditIcon48);
githubIcon = new Bitmap(AM2RLauncher.Properties.Resources.githubIcon48);
youtubeIcon = new Bitmap(AM2RLauncher.Properties.Resources.youtubeIcon48);
discordIcon = new Bitmap(AM2RLauncher.Properties.Resources.discordIcon48);
formBG = new Bitmap(AM2RLauncher.Properties.Resources.bgCentered);
// Load colors
colGreen = Color.FromArgb(142, 188, 35);
colRed = Color.FromArgb(188, 10, 35);
colInactive = Color.FromArgb(109, 109, 109);
colBGNoAlpha = Color.FromArgb(10, 10, 10);
colBG = Color.FromArgb(10, 10, 10, 80);
if (OS.IsLinux) colBG = colBGNoAlpha; // XORG can't display alpha anyway, and Wayland breaks with it.
colBGHover = Color.FromArgb(17, 28, 13);
Font smallButtonFont = new Font(SystemFont.Default, 10); Font smallButtonFont = new Font(SystemFont.Default, 10);
// Create mirror list - eventually this should be platform specific! // Create mirror list - eventually this should be platform specific!
@ -189,8 +170,8 @@ namespace AM2RLauncher
foreach (var mirror in mirrorList) foreach (var mirror in mirrorList)
{ {
string text = mirror; string text = mirror;
if (text.Contains("github.com")) text = Language.Text.MirrorGithubText; if (text.Contains("github.com")) text = Text.MirrorGithubText;
else if (text.Contains("gitlab.com")) text = Language.Text.MirrorGitlabText; else if (text.Contains("gitlab.com")) text = Text.MirrorGitlabText;
mirrorDescriptionList.Add(new ListItem() { Key = mirror, Text = text }); mirrorDescriptionList.Add(new ListItem() { Key = mirror, Text = text });
} }
#endregion #endregion
@ -246,7 +227,7 @@ namespace AM2RLauncher
// APK button // APK button
apkButton = new ColorButton apkButton = new ColorButton
{ {
Text = Language.Text.CreateAPK, Text = Text.CreateAPK,
Height = 40, Height = 40,
Width = 250, Width = 250,
TextColor = colGreen, TextColor = colGreen,
@ -286,7 +267,7 @@ namespace AM2RLauncher
{ {
BackgroundColor = colBG, BackgroundColor = colBG,
Height = 15, Height = 15,
Text = Language.Text.CurrentProfile, Text = Text.CurrentProfile,
TextColor = colGreen TextColor = colGreen
}; };
@ -315,7 +296,7 @@ namespace AM2RLauncher
{ {
BackgroundColor = colBG, BackgroundColor = colBG,
Height = 16, Height = 16,
Text = Language.Text.Author + " ", Text = Text.Author + " ",
TextColor = colGreen TextColor = colGreen
}; };
@ -325,7 +306,7 @@ namespace AM2RLauncher
{ {
BackgroundColor = colBG, BackgroundColor = colBG,
Height = 16, Height = 16,
Text = Language.Text.VersionLabel + " ", Text = Text.VersionLabel + " ",
TextColor = colGreen TextColor = colGreen
}; };
@ -337,7 +318,7 @@ namespace AM2RLauncher
BackgroundColor = colBG, BackgroundColor = colBG,
Width = 20, Width = 20,
Height = 55, Height = 55,
Text = Language.Text.SaveLocationWarning, Text = Text.SaveLocationWarning,
TextColor = colRed TextColor = colRed
}; };
@ -345,17 +326,21 @@ namespace AM2RLauncher
// Social buttons // Social buttons
var redditButton = new ImageButton { ToolTip = Language.Text.RedditToolTip, Image = redditIcon }; Bitmap redditIcon = new Bitmap(Resources.redditIcon48);
redditButton.Click += RedditIconOnClick; var redditButton = new ImageButton { ToolTip = Text.RedditToolTip, Image = redditIcon };
redditButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.reddit.com/r/AM2R");
var githubButton = new ImageButton { ToolTip = Language.Text.GithubToolTip, Image = githubIcon }; Bitmap githubIcon = new Bitmap(Resources.githubIcon48);
githubButton.Click += GithubIconOnClick; var githubButton = new ImageButton { ToolTip = Text.GithubToolTip, Image = githubIcon };
githubButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.github.com/AM2R-Community-Developers");
var youtubeButton = new ImageButton { ToolTip = Language.Text.YoutubeToolTip, Image = youtubeIcon }; Bitmap youtubeIcon = new Bitmap(Resources.youtubeIcon48);
youtubeButton.Click += YoutubeIconOnClick; var youtubeButton = new ImageButton { ToolTip = Text.YoutubeToolTip, Image = youtubeIcon };
youtubeButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://www.youtube.com/c/AM2RCommunityUpdates");
var discordButton = new ImageButton { ToolTip = Language.Text.DiscordToolTip, Image = discordIcon }; Bitmap discordIcon = new Bitmap(Resources.discordIcon48);
discordButton.Click += DiscordIconOnClick; var discordButton = new ImageButton { ToolTip = Text.DiscordToolTip, Image = discordIcon };
discordButton.Click += (sender, e) => CrossPlatformOperations.OpenURL("https://discord.gg/nk7UYPbd5u");
// Social button panel // Social button panel
@ -369,7 +354,12 @@ namespace AM2RLauncher
// Version number label // Version number label
versionLabel = new Label { Text = "v" + VERSION + (isThisRunningFromWine ? "-WINE" : ""), Width = 48, TextAlignment = TextAlignment.Right, TextColor = colGreen, Font = new Font(SystemFont.Default, 12) }; Label versionLabel = new Label
{
Text = "v" + VERSION + (isThisRunningFromWine ? "-WINE" : ""),
Width = 48, TextAlignment = TextAlignment.Right, TextColor = colGreen,
Font = new Font(SystemFont.Default, 12)
};
// Tie everything together // Tie everything together
var mainLayout = new DynamicLayout(); var mainLayout = new DynamicLayout();
@ -390,33 +380,34 @@ namespace AM2RLauncher
#region TABS #region TABS
#region MAIN PAGE
// [MAIN PAGE] // [MAIN PAGE]
mainPage = new TabPage TabPage mainPage = new TabPage
{ {
BackgroundColor = colBGNoAlpha, BackgroundColor = colBGNoAlpha,
Text = Language.Text.PlayTab, Text = Text.PlayTab,
Content = drawable Content = drawable
}; };
#endregion
#region CHANGELOG PAGE
// [CHANGELOG] // [CHANGELOG]
Uri changelogUri = new Uri("https://am2r-community-developers.github.io/DistributionCenter/changelog.html");
changelogUri = new Uri("https://am2r-community-developers.github.io/DistributionCenter/changelog.html"); WebView changelogWebView = new WebView { Url = changelogUri };
changelogWebView = new WebView { Url = changelogUri };
if (OS.IsUnix && !isInternetThere) if (OS.IsUnix && !isInternetThere)
changelogWebView = new WebView(); changelogWebView = new WebView();
changelogNoConnectionLabel = new Label Label changelogNoConnectionLabel = new Label
{ {
Text = Language.Text.NoInternetConnection, Text = Text.NoInternetConnection,
TextColor = colGreen TextColor = colGreen
}; };
changelogPage = new TabPage TabPage changelogPage = new TabPage
{ {
BackgroundColor = colBGNoAlpha, BackgroundColor = colBGNoAlpha,
Text = Language.Text.ChangelogTab, Text = Text.ChangelogTab,
Content = new TableLayout Content = new TableLayout
{ {
@ -427,22 +418,27 @@ namespace AM2RLauncher
} }
}; };
#endregion
#region NEWS PAGE
// [NEWS] // [NEWS]
newsUri = new Uri("https://am2r-community-developers.github.io/DistributionCenter/news.html"); Uri newsUri = new Uri("https://am2r-community-developers.github.io/DistributionCenter/news.html");
newsWebView = new WebView { Url = newsUri }; WebView newsWebView = new WebView { Url = newsUri };
//TODO: why exactly is this check necessary?
if (OS.IsUnix && !isInternetThere) if (OS.IsUnix && !isInternetThere)
newsWebView = new WebView(); newsWebView = new WebView();
newsNoConnectionLabel = new Label Label newsNoConnectionLabel = new Label
{ {
Text = Language.Text.NoInternetConnection, Text = Text.NoInternetConnection,
TextColor = colGreen TextColor = colGreen
}; };
newsPage = new TabPage TabPage newsPage = new TabPage
{ {
Text = Language.Text.NewsTab, Text = Text.NewsTab,
BackgroundColor = colBGNoAlpha, BackgroundColor = colBGNoAlpha,
Content = new TableLayout Content = new TableLayout
@ -454,6 +450,7 @@ namespace AM2RLauncher
} }
}; };
//TODO: this is hack because on linux / mac the other way doesn't work. eto issue?
if (OS.IsUnix && !isInternetThere) if (OS.IsUnix && !isInternetThere)
{ {
changelogPage.Content = new TableLayout changelogPage.Content = new TableLayout
@ -476,13 +473,17 @@ namespace AM2RLauncher
}; };
} }
#endregion
#region SETTINGS PAGE
// [LAUNCHER SETTINGS] // [LAUNCHER SETTINGS]
DynamicLayout settingsLayout = new DynamicLayout(); DynamicLayout settingsLayout = new DynamicLayout();
// LanguageLabel // LanguageLabel
languageLabel = new Label Label languageLabel = new Label
{ {
Text = Language.Text.LanguageNotice, Text = Text.LanguageNotice,
TextColor = colGreen TextColor = colGreen
}; };
@ -490,7 +491,7 @@ namespace AM2RLauncher
List<ListItem> languageList = new List<ListItem> List<ListItem> languageList = new List<ListItem>
{ {
Language.Text.SystemLanguage, Text.SystemLanguage,
"Deutsch", "Deutsch",
"English", "English",
"Español", "Español",
@ -525,7 +526,7 @@ namespace AM2RLauncher
autoUpdateAM2RCheck = new CheckBox autoUpdateAM2RCheck = new CheckBox
{ {
Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")),
Text = Language.Text.AutoUpdateAM2R, Text = Text.AutoUpdateAM2R,
TextColor = colGreen TextColor = colGreen
}; };
@ -534,7 +535,7 @@ namespace AM2RLauncher
autoUpdateLauncherCheck = new CheckBox autoUpdateLauncherCheck = new CheckBox
{ {
Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")),
Text = Language.Text.AutoUpdateLauncher, Text = Text.AutoUpdateLauncher,
TextColor = colGreen TextColor = colGreen
}; };
@ -542,7 +543,7 @@ namespace AM2RLauncher
hqMusicPCCheck = new CheckBox hqMusicPCCheck = new CheckBox
{ {
Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")),
Text = Language.Text.HighQualityPC, Text = Text.HighQualityPC,
TextColor = colGreen TextColor = colGreen
}; };
@ -550,7 +551,7 @@ namespace AM2RLauncher
hqMusicAndroidCheck = new CheckBox hqMusicAndroidCheck = new CheckBox
{ {
Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")),
Text = Language.Text.HighQualityAndroid, Text = Text.HighQualityAndroid,
TextColor = colGreen TextColor = colGreen
}; };
@ -558,17 +559,17 @@ namespace AM2RLauncher
profileDebugLogCheck = new CheckBox profileDebugLogCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("ProfileDebugLog")), Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("ProfileDebugLog")),
Text = Language.Text.ProfileDebugCheckBox, Text = Text.ProfileDebugCheckBox,
TextColor = colGreen TextColor = colGreen
}; };
// Custom environment variables label // Custom environment variables label
customEnvVarLabel = new Label(); Label customEnvVarLabel = new Label();
if (OS.IsLinux) if (OS.IsLinux)
{ {
customEnvVarLabel = new Label customEnvVarLabel = new Label
{ {
Text = Language.Text.CustomEnvVarLabel, Text = Text.CustomEnvVarLabel,
TextColor = colGreen TextColor = colGreen
}; };
} }
@ -588,7 +589,7 @@ namespace AM2RLauncher
// Mirror list // Mirror list
mirrorLabel = new Label mirrorLabel = new Label
{ {
Text = Language.Text.DownloadSource, Text = Text.DownloadSource,
TextColor = colGreen TextColor = colGreen
}; };
@ -611,7 +612,7 @@ namespace AM2RLauncher
customMirrorCheck = new CheckBox customMirrorCheck = new CheckBox
{ {
Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")),
Text = Language.Text.CustomMirrorCheck, Text = Text.CustomMirrorCheck,
TextColor = colGreen TextColor = colGreen
}; };
@ -622,6 +623,8 @@ namespace AM2RLauncher
TextColor = colGreen TextColor = colGreen
}; };
EnableMirrorControlsAccordingly();
settingsLayout.BeginHorizontal(); settingsLayout.BeginHorizontal();
settingsLayout.AddSpace(); settingsLayout.AddSpace();
settingsLayout.AddColumn(null, languageLabel, languageDropDown, autoUpdateAM2RCheck, autoUpdateLauncherCheck, hqMusicPCCheck, hqMusicAndroidCheck, profileDebugLogCheck, customEnvVarLabel, (Control)customEnvVarTextBox ?? new Label(), mirrorLabel, mirrorDropDown, customMirrorCheck, customMirrorTextBox, null); settingsLayout.AddColumn(null, languageLabel, languageDropDown, autoUpdateAM2RCheck, autoUpdateLauncherCheck, hqMusicPCCheck, hqMusicAndroidCheck, profileDebugLogCheck, customEnvVarLabel, (Control)customEnvVarTextBox ?? new Label(), mirrorLabel, mirrorDropDown, customMirrorCheck, customMirrorTextBox, null);
@ -631,18 +634,21 @@ namespace AM2RLauncher
{ {
BackgroundColor = colBGNoAlpha, BackgroundColor = colBGNoAlpha,
Content = settingsLayout, Content = settingsLayout,
Text = Language.Text.LauncherSettingsTab Text = Text.LauncherSettingsTab
}; };
// [MOD SETTINGS] #endregion
DynamicLayout profileLayout = new DynamicLayout(); #region MODSETTINGS PAGE
// [MOD SETTINGS]
DynamicLayout modSettingsLayout = new DynamicLayout();
addModButton = new ColorButton addModButton = new ColorButton
{ {
ToolTip = null, ToolTip = null,
Text = Language.Text.AddNewMod, Text = Text.AddNewMod,
Font = smallButtonFont, Font = smallButtonFont,
Height = 30, Height = 30,
Width = 275, Width = 275,
@ -659,12 +665,12 @@ namespace AM2RLauncher
settingsProfileLabel = new Label settingsProfileLabel = new Label
{ {
Text = Language.Text.CurrentProfile, Text = Text.CurrentProfile,
TextColor = colGreen, TextColor = colGreen,
Width = 275 Width = 275
}; };
settingsProfileDropDown = new DropDown modSettingsProfileDropDown = new DropDown
{ {
TextColor = colGreen, TextColor = colGreen,
BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color() BackgroundColor = OS.IsWindows ? colBGNoAlpha : new Color()
@ -672,14 +678,14 @@ namespace AM2RLauncher
// In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK. // In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK.
if (OS.IsLinux) if (OS.IsLinux)
settingsProfileDropDown = new DropDown(); modSettingsProfileDropDown = new DropDown();
settingsProfileDropDown.Items.AddRange(profileNames); // It's actually more comfortable if it's outside, because of GTK shenanigans modSettingsProfileDropDown.Items.AddRange(profileNames); // It's actually more comfortable if it's outside, because of GTK shenanigans
profileButton = new ColorButton profileButton = new ColorButton
{ {
ToolTip = null, ToolTip = null,
Text = Language.Text.OpenProfileFolder, Text = Text.OpenProfileFolder,
Font = smallButtonFont, Font = smallButtonFont,
Height = 30, Height = 30,
Width = 275, Width = 275,
@ -692,7 +698,7 @@ namespace AM2RLauncher
saveButton = new ColorButton saveButton = new ColorButton
{ {
ToolTip = null, ToolTip = null,
Text = Language.Text.OpenSaveFolder, Text = Text.OpenSaveFolder,
Font = smallButtonFont, Font = smallButtonFont,
Height = 30, Height = 30,
Width = 275, Width = 275,
@ -705,7 +711,7 @@ namespace AM2RLauncher
updateModButton = new ColorButton updateModButton = new ColorButton
{ {
ToolTip = null, ToolTip = null,
Text = Language.Text.UpdateModButtonText, Text = Text.UpdateModButtonText,
Font = smallButtonFont, Font = smallButtonFont,
Height = 30, Height = 30,
Width = 275, Width = 275,
@ -718,7 +724,7 @@ namespace AM2RLauncher
deleteModButton = new ColorButton deleteModButton = new ColorButton
{ {
ToolTip = null, ToolTip = null,
Text = Language.Text.DeleteModButtonText, Text = Text.DeleteModButtonText,
Font = smallButtonFont, Font = smallButtonFont,
Height = 30, Height = 30,
Width = 275, Width = 275,
@ -736,23 +742,25 @@ namespace AM2RLauncher
SpellCheck = false, SpellCheck = false,
Width = 275, Width = 275,
Height = 150, Height = 150,
Text = Language.Text.ProfileNotes Text = Text.ProfileNotes
}; };
profileLayout.BeginHorizontal(); modSettingsLayout.BeginHorizontal();
profileLayout.AddSpace(); modSettingsLayout.AddSpace();
profileLayout.AddColumn(null, addModButton, modSpacer, settingsProfileLabel, settingsProfileDropDown, profileButton, saveButton, updateModButton, deleteModButton, profileNotesTextArea, null); modSettingsLayout.AddColumn(null, addModButton, modSpacer, settingsProfileLabel, modSettingsProfileDropDown, profileButton, saveButton, updateModButton, deleteModButton, profileNotesTextArea, null);
profileLayout.AddSpace(); modSettingsLayout.AddSpace();
profilePage = new TabPage TabPage modSettingsPage = new TabPage
{ {
BackgroundColor = colBGNoAlpha, BackgroundColor = colBGNoAlpha,
Content = profileLayout, Content = modSettingsLayout,
Text = Language.Text.ProfileSettingsTab Text = Text.ModSettingsTab
}; };
#endregion #endregion
#endregion
Content = new TabControl Content = new TabControl
{ {
Pages = Pages =
@ -765,7 +773,7 @@ namespace AM2RLauncher
settingsPage, settingsPage,
profilePage modSettingsPage
} }
}; };
@ -782,7 +790,6 @@ namespace AM2RLauncher
hqMusicAndroidCheck.CheckedChanged += HqMusicAndroidCheckChanged; hqMusicAndroidCheck.CheckedChanged += HqMusicAndroidCheckChanged;
hqMusicPCCheck.CheckedChanged += HqMusicPCCheckChanged; hqMusicPCCheck.CheckedChanged += HqMusicPCCheckChanged;
customMirrorCheck.CheckedChanged += CustomMirrorCheckChanged; customMirrorCheck.CheckedChanged += CustomMirrorCheckChanged;
customMirrorCheck.LoadComplete += CustomMirrorCheckLoadComplete;
apkButton.Click += ApkButtonClickEvent; apkButton.Click += ApkButtonClickEvent;
apkButton.LoadComplete += (sender, e) => UpdateApkState(); apkButton.LoadComplete += (sender, e) => UpdateApkState();
profileDropDown.LoadComplete += (sender, e) => UpdateProfileState(); profileDropDown.LoadComplete += (sender, e) => UpdateProfileState();
@ -790,11 +797,11 @@ namespace AM2RLauncher
playButton.LoadComplete += PlayButtonLoadComplete; playButton.LoadComplete += PlayButtonLoadComplete;
customMirrorTextBox.LostFocus += CustomMirrorTextBoxLostFocus; customMirrorTextBox.LostFocus += CustomMirrorTextBoxLostFocus;
mirrorDropDown.SelectedIndexChanged += MirrorDropDownSelectedIndexChanged; mirrorDropDown.SelectedIndexChanged += MirrorDropDownSelectedIndexChanged;
profileLayout.LoadComplete += ProfileLayoutLoadComplete; modSettingsLayout.LoadComplete += ProfileLayoutLoadComplete;
addModButton.Click += AddModButtonClicked; addModButton.Click += AddModButtonClicked;
profileButton.Click += ProfilesButtonClickEvent; profileButton.Click += ProfileDataButtonClickEvent;
saveButton.Click += SaveButtonClickEvent; saveButton.Click += SaveButtonClickEvent;
settingsProfileDropDown.SelectedIndexChanged += SettingsProfileDropDownSelectedIndexChanged; modSettingsProfileDropDown.SelectedIndexChanged += ModSettingsProfileDropDownSelectedIndexChanged;
deleteModButton.Click += DeleteModButtonClicked; deleteModButton.Click += DeleteModButtonClicked;
updateModButton.Click += UpdateModButtonClicked; updateModButton.Click += UpdateModButtonClicked;
profileDebugLogCheck.CheckedChanged += ProfileDebugLogCheckedChanged; profileDebugLogCheck.CheckedChanged += ProfileDebugLogCheckedChanged;
@ -802,8 +809,8 @@ namespace AM2RLauncher
customEnvVarTextBox.LostFocus += CustomEnvVarTextBoxLostFocus; customEnvVarTextBox.LostFocus += CustomEnvVarTextBoxLostFocus;
//TODO: Retest if these now work on mac //TODO: Retest if these now work on mac
newsWebView.DocumentLoaded += NewsWebViewDocumentLoaded; newsWebView.DocumentLoaded += (sender, e) => ChangeToEmptyPageOnNoInternet(newsPage, newsNoConnectionLabel);
changelogWebView.DocumentLoaded += ChangelogWebViewDocumentLoaded; changelogWebView.DocumentLoaded += (sender, e) => ChangeToEmptyPageOnNoInternet(changelogPage, changelogNoConnectionLabel);
log.Info("Events linked successfully."); log.Info("Events linked successfully.");
@ -815,40 +822,32 @@ namespace AM2RLauncher
// Visual studio does it like this for normal winforms projects, so I just used the same format. // Visual studio does it like this for normal winforms projects, so I just used the same format.
/// <summary>The tray indicator</summary> /// <summary>The tray indicator</summary>
TrayIndicator trayIndicator; private TrayIndicator trayIndicator;
/// <summary>The "Show" Button on the tray indicator</summary>
ButtonMenuItem showButton;
/// <summary><see cref="List{T}"/> of <see cref="ProfileXML"/>s, used for actually working with profile data.</summary> /// <summary><see cref="List{T}"/> of <see cref="ProfileXML"/>s, used for actually working with profile data.</summary>
//TODO: this should be moved into AM2RLauncher.Core
List<ProfileXML> profileList; List<ProfileXML> profileList;
/// <summary><see cref="List{T}"/> of <see cref="ListItem"/>s so that Eto's annoying <see cref="IListItem"/> interface is appeased. Used for profile name display in DropDowns.</summary> /// <summary><see cref="List{T}"/> of <see cref="ListItem"/>s so that Eto's annoying <see cref="IListItem"/> interface is appeased. Used for profile name display in DropDowns.</summary>
List<ListItem> profileNames; List<ListItem> profileNames;
// Bitmaps
/// <summary>The Reddit icon.</summary>
private Bitmap redditIcon;
/// <summary>The Github icon.</summary>
private Bitmap githubIcon;
/// <summary>The YouTube icon.</summary>
private Bitmap youtubeIcon;
/// <summary>The Discord icon.</summary>
private Bitmap discordIcon;
/// <summary>The planet Background.</summary> /// <summary>The planet Background.</summary>
private Bitmap formBG; private readonly Bitmap formBG = new Bitmap(Resources.bgCentered);
// Colors // Colors
/// <summary>The main green color.</summary> /// <summary>The main green color.</summary>
private Color colGreen; private readonly Color colGreen = Color.FromArgb(142, 188, 35);
/// <summary>The warning red color.</summary> /// <summary>The warning red color.</summary>
private Color colRed; private readonly Color colRed = Color.FromArgb(188, 10, 35);
/// <summary>The main inactive color.</summary> /// <summary>The main inactive color.</summary>
private Color colInactive; private readonly Color colInactive = Color.FromArgb(109, 109, 109);
/// <summary>The black background color without alpha value.</summary> /// <summary>The black background color without alpha value.</summary>
private Color colBGNoAlpha; private readonly Color colBGNoAlpha = Color.FromArgb(10, 10, 10);
/// <summary>The black background color.</summary> /// <summary>The black background color.</summary>
private Color colBG; // XORG can't display alpha anyway, and Wayland breaks with it.
// TODO: that sounds like an Eto bug. investigate, try to open eto issue.
private readonly Color colBG = OS.IsLinux ? Color.FromArgb(10, 10, 10) : Color.FromArgb(10, 10, 10, 80);
/// <summary>The lighter green color on hover.</summary> /// <summary>The lighter green color on hover.</summary>
private Color colBGHover; private readonly Color colBGHover = Color.FromArgb(17, 28, 13);
// Mirror lists // Mirror lists
/// <summary><see cref="List{String}"/> of mirror <see cref="string"/>s, used for actually working with mirrors.</summary> /// <summary><see cref="List{String}"/> of mirror <see cref="string"/>s, used for actually working with mirrors.</summary>
@ -857,7 +856,7 @@ namespace AM2RLauncher
private List<ListItem> mirrorDescriptionList; private List<ListItem> mirrorDescriptionList;
// UI Elements // UI Elements
/// <summary>The main control of the <see cref="mainPage"/>, used to draw the <see cref="formBG"/> and hold the main interface.</summary> /// <summary>The main control of the main page, used to draw the <see cref="formBG"/> and hold the main interface.</summary>
private Drawable drawable; private Drawable drawable;
/// <summary>A <see cref="ColorButton"/> that acts as the main Button</summary> /// <summary>A <see cref="ColorButton"/> that acts as the main Button</summary>
@ -875,8 +874,6 @@ namespace AM2RLauncher
/// <summary>A <see cref="ColorButton"/> that is used to delete a mod</summary> /// <summary>A <see cref="ColorButton"/> that is used to delete a mod</summary>
private ColorButton deleteModButton; private ColorButton deleteModButton;
/// <summary>The <see cref="Label"/> that gives information for <see cref="languageDropDown"/>.</summary>
private Label languageLabel;
/// <summary>The <see cref="Label"/> that entitles <see cref="profileDropDown"/>.</summary> /// <summary>The <see cref="Label"/> that entitles <see cref="profileDropDown"/>.</summary>
private Label profileLabel; private Label profileLabel;
/// <summary>The <see cref="Label"/> that gives author information for <see cref="profileDropDown"/>.</summary> /// <summary>The <see cref="Label"/> that gives author information for <see cref="profileDropDown"/>.</summary>
@ -885,22 +882,12 @@ namespace AM2RLauncher
private Label profileVersionLabel; private Label profileVersionLabel;
/// <summary>The <see cref="Label"/> that gives information for <see cref="mirrorDropDown"/>.</summary> /// <summary>The <see cref="Label"/> that gives information for <see cref="mirrorDropDown"/>.</summary>
private Label mirrorLabel; private Label mirrorLabel;
/// <summary>The <see cref="Label"/> that displays <see cref="VERSION"/>, aka the current launcher version.</summary> /// <summary>The <see cref="Label"/> that gives information for <see cref="modSettingsProfileDropDown"/>.</summary>
private Label versionLabel;
/// <summary>The <see cref="Label"/> that gives information for <see cref="settingsProfileDropDown"/>.</summary>
private Label settingsProfileLabel; private Label settingsProfileLabel;
/// <summary>The <see cref="Label"/> that compliments <see cref="progressBar"/>.</summary> /// <summary>The <see cref="Label"/> that compliments <see cref="progressBar"/>.</summary>
private Label progressLabel; private Label progressLabel;
/// <summary>The <see cref="Label"/> that gives a warning on failure to load the <see cref="newsWebView"/>.</summary>
private Label newsNoConnectionLabel;
/// <summary>The <see cref="Label"/> that gives a warning on failure to load the <see cref="changelogWebView"/>.</summary>
private Label changelogNoConnectionLabel;
/// <summary>The <see cref="Label"/> that gives a warning if the current selected <see cref="ProfileXML"/> shares the same save location has default AM2R.</summary> /// <summary>The <see cref="Label"/> that gives a warning if the current selected <see cref="ProfileXML"/> shares the same save location has default AM2R.</summary>
private Label saveWarningLabel; private Label saveWarningLabel;
/// <summary>The <see cref="Label"/> that describes <see cref="customEnvVarTextBox"/>.</summary>
private Label customEnvVarLabel;
/// <summary>A <see cref="CheckBox"/>, that indicates wether to automatically update AM2R or not.</summary> /// <summary>A <see cref="CheckBox"/>, that indicates wether to automatically update AM2R or not.</summary>
private CheckBox autoUpdateAM2RCheck; private CheckBox autoUpdateAM2RCheck;
@ -922,38 +909,20 @@ namespace AM2RLauncher
/// <summary>A <see cref="DropDown"/> where profiles can be chosen.</summary> /// <summary>A <see cref="DropDown"/> where profiles can be chosen.</summary>
private DropDown profileDropDown; private DropDown profileDropDown;
/// <summary>A <see cref="DropDown"/> where profiles can be chosen (located in Profile Settings).</summary> /// <summary>A <see cref="DropDown"/> where profiles can be chosen (located in Profile Settings).</summary>
private DropDown settingsProfileDropDown; //TODO: Use MVVM bindings: https://github.com/picoe/Eto/wiki/Data-Binding#mvvm-binding
private DropDown modSettingsProfileDropDown;
/// <summary>A <see cref="TextBox"/>, where the user can input their custom mirror.</summary> /// <summary>A <see cref="TextBox"/>, where the user can input their custom mirror.</summary>
private TextBox customMirrorTextBox; private TextBox customMirrorTextBox;
/// <summary>A <see cref="TextBox"/>, where the user can input their custom environment variables.</summary> /// <summary>A <see cref="TextBox"/>, where the user can input their custom environment variables.</summary>
private TextBox customEnvVarTextBox; private TextBox customEnvVarTextBox;
/// <summary>A <see cref="TextArea"/>, where the notes from the current selected profile in <see cref="settingsProfileDropDown"/> are displayed.</summary> /// <summary>A <see cref="TextArea"/>, where the notes from the current selected profile in <see cref="modSettingsProfileDropDown"/> are displayed.</summary>
private TextArea profileNotesTextArea; private TextArea profileNotesTextArea;
/// <summary>A <see cref="ProgressBar"/> that can be used to show progress for a specific task.</summary> /// <summary>A <see cref="ProgressBar"/> that can be used to show progress for a specific task.</summary>
private ProgressBar progressBar; private ProgressBar progressBar;
/// <summary>The Uri used by <see cref="newsWebView"/>.</summary>
private Uri newsUri;
/// <summary>The Uri used by <see cref="changelogWebView"/>.</summary>
private Uri changelogUri;
/// <summary>A <see cref="WebView"/> to display the DistributionCenter news page.</summary>
private WebView newsWebView;
/// <summary>A <see cref="WebView"/> to display the DistributionCenter changelog page.</summary>
private WebView changelogWebView;
/// <summary>A <see cref="TabPage"/> for the Launcher's main interface.</summary>
private TabPage mainPage;
/// <summary>A <see cref="TabPage"/> for the Launcher's news integration.</summary>
private TabPage newsPage;
/// <summary>A <see cref="TabPage"/> for the Launcher's changelog integration.</summary>
private TabPage changelogPage;
/// <summary>A <see cref="TabPage"/> for the Launcher's profile settings.</summary>
private TabPage profilePage;
#endregion #endregion
} }
} }

@ -353,7 +353,6 @@ public static class CrossPlatformOperations
try try
{ {
xdelta.Start(); xdelta.Start();
xdelta.WaitForExit(); xdelta.WaitForExit();
} }
catch (System.ComponentModel.Win32Exception) catch (System.ComponentModel.Win32Exception)

@ -1,6 +1,7 @@
using log4net; using log4net;
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Security.Cryptography; using System.Security.Cryptography;
@ -160,4 +161,15 @@ public static class HelperMethods
log.Info("Internet connection established!"); log.Info("Internet connection established!");
return true; return true;
} }
/// <summary>
/// Gets <paramref name="languageText"/> and replaces "$NAME" with <paramref name="replacementText"/>.
/// </summary>
/// <param name="languageText">The text to get</param>
/// <param name="replacementText">The text to replace "$NAME" with.</param>
/// <returns></returns>
public static string GetText(string languageText, string replacementText = "")
{
return languageText.Replace("$NAME", replacementText);
}
} }

@ -47,13 +47,14 @@ public static class Profile
/// <summary> /// <summary>
/// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists. /// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists.
/// This method will store the result in a cache and return that, unless it's invalidated by <paramref name="invalidateCache"/>.
/// </summary> /// </summary>
/// <param name="invalidateCache">Determines if the AM2R_11 Cache should be invalidated</param> /// <param name="invalidateCache">Determines if the AM2R_11 Cache should be invalidated.</param>
/// <returns></returns> /// <returns></returns>
public static bool Is11Installed(bool invalidateCache = false) public static bool Is11Installed(bool invalidateCache = false)
{ {
// Only invalidate if we need to // Only invalidate if we need to
if (invalidateCache) InvalidateAM2R11InstallCacheIfNecessary(); if (invalidateCache) InvalidateAM2R11InstallCache();
// If we have a cache, return that instead // If we have a cache, return that instead
if (isAM2R11InstalledCache != null) return isAM2R11InstalledCache.Value; if (isAM2R11InstalledCache != null) return isAM2R11InstalledCache.Value;
@ -78,7 +79,7 @@ public static class Profile
/// <summary> /// <summary>
/// Invalidates <see cref="isAM2R11InstalledCache"/> if necessary. /// Invalidates <see cref="isAM2R11InstalledCache"/> if necessary.
/// </summary> /// </summary>
private static void InvalidateAM2R11InstallCacheIfNecessary() private static void InvalidateAM2R11InstallCache()
{ {
// If the file exists, and its hash matches with ours, don't invalidate // If the file exists, and its hash matches with ours, don't invalidate
if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") && if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") &&
@ -88,6 +89,64 @@ public static class Profile
isAM2R11InstalledCache = null; isAM2R11InstalledCache = null;
} }
/// <summary>
/// Checks if a Zip file is a valid AM2R_1.1 zip.
/// </summary>
/// <param name="zipPath">Full Path to the Zip file to check.</param>
/// <returns><see cref="IsZipAM2R11ReturnCodes"/> detailing the result</returns>
public static IsZipAM2R11ReturnCodes CheckIfZipIsAM2R11(string zipPath)
{
const string d3dHash = "86e39e9161c3d930d93822f1563c280d";
const string dataWinHash = "f2b84fe5ba64cb64e284be1066ca08ee";
const string am2rHash = "15253f7a66d6ea3feef004ebbee9b438";
string tmpPath = Path.GetTempPath() + Path.GetFileNameWithoutExtension(zipPath);
// Clean up in case folder exists already
if (Directory.Exists(tmpPath))
Directory.Delete(tmpPath, true);
Directory.CreateDirectory(tmpPath);
// Open archive
ZipArchive am2rZip = ZipFile.OpenRead(zipPath);
// Check if exe exists anywhere
ZipArchiveEntry am2rExe = am2rZip.Entries.FirstOrDefault(x => x.FullName.Contains("AM2R.exe"));
if (am2rExe == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
// Check if it's not in a subfolder. if it'd be in a subfolder, fullname would be "folder/AM2R.exe"
if (am2rExe.FullName != "AM2R.exe")
return IsZipAM2R11ReturnCodes.GameIsInASubfolder;
// Check validity
am2rExe.ExtractToFile(tmpPath + "/" + am2rExe.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + am2rExe.FullName) != am2rHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
// Check if data.win exists / is valid
ZipArchiveEntry dataWin = am2rZip.Entries.FirstOrDefault(x => x.FullName == "data.win");
if (dataWin == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
dataWin.ExtractToFile(tmpPath + "/" + dataWin.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + dataWin.FullName) != dataWinHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
// Check if d3d.dll exists / is valid
ZipArchiveEntry d3dx = am2rZip.Entries.FirstOrDefault(x => x.FullName == "D3DX9_43.dll");
if (d3dx == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
d3dx.ExtractToFile(tmpPath + "/" + d3dx.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + d3dx.FullName) != d3dHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
// Clean up
Directory.Delete(tmpPath, true);
// If we didn't exit before, everything is fine
log.Info("AM2R_11 check successful!");
return IsZipAM2R11ReturnCodes.Successful;
}
/// <summary> /// <summary>
/// Git Pulls from the repository. /// Git Pulls from the repository.
/// </summary> /// </summary>
@ -240,9 +299,7 @@ public static class Profile
// Delete folder in Mods // Delete folder in Mods
if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath)) if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath))
{
HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath); HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath);
}
// Delete the zip file in Mods // Delete the zip file in Mods
if (File.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip")) if (File.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip"))
@ -254,9 +311,7 @@ public static class Profile
// Delete folder in Profiles // Delete folder in Profiles
if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name))
{
HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name); HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name);
}
log.Info("Successfully deleted profile " + profile.Name + "."); log.Info("Successfully deleted profile " + profile.Name + ".");
} }
@ -497,6 +552,7 @@ public static class Profile
progress.Report(100); progress.Report(100);
return; return;
} }
log.Info("Creating Android APK for profile " + profile.Name + "."); log.Info("Creating Android APK for profile " + profile.Name + ".");
// Create working dir after some cleanup // Create working dir after some cleanup
@ -782,62 +838,4 @@ public static class Profile
// isValid seems to only check for a .git folder, and there are cases where that exists, but not the profile.xml // isValid seems to only check for a .git folder, and there are cases where that exists, but not the profile.xml
return Repository.IsValid(CrossPlatformOperations.CURRENTPATH + "/PatchData") && File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml"); return Repository.IsValid(CrossPlatformOperations.CURRENTPATH + "/PatchData") && File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml");
} }
/// <summary>
/// Checks if a Zip file is a valid AM2R_1.1 zip.
/// </summary>
/// <param name="zipPath">Full Path to the Zip file to check.</param>
/// <returns><see cref="IsZipAM2R11ReturnCodes"/> detailing the result</returns>
public static IsZipAM2R11ReturnCodes CheckIfZipIsAM2R11(string zipPath)
{
const string d3dHash = "86e39e9161c3d930d93822f1563c280d";
const string dataWinHash = "f2b84fe5ba64cb64e284be1066ca08ee";
const string am2rHash = "15253f7a66d6ea3feef004ebbee9b438";
string tmpPath = Path.GetTempPath() + Path.GetFileNameWithoutExtension(zipPath);
// Clean up in case folder exists already
if (Directory.Exists(tmpPath))
Directory.Delete(tmpPath, true);
Directory.CreateDirectory(tmpPath);
// Open archive
ZipArchive am2rZip = ZipFile.OpenRead(zipPath);
// Check if exe exists anywhere
ZipArchiveEntry am2rExe = am2rZip.Entries.FirstOrDefault(x => x.FullName.Contains("AM2R.exe"));
if (am2rExe == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
// Check if it's not in a subfolder. if it'd be in a subfolder, fullname would be "folder/AM2R.exe"
if (am2rExe.FullName != "AM2R.exe")
return IsZipAM2R11ReturnCodes.GameIsInASubfolder;
// Check validity
am2rExe.ExtractToFile(tmpPath + "/" + am2rExe.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + am2rExe.FullName) != am2rHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
// Check if data.win exists / is valid
ZipArchiveEntry dataWin = am2rZip.Entries.FirstOrDefault(x => x.FullName == "data.win");
if (dataWin == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
dataWin.ExtractToFile(tmpPath + "/" + dataWin.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + dataWin.FullName) != dataWinHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
// Check if d3d.dll exists / is valid
ZipArchiveEntry d3dx = am2rZip.Entries.FirstOrDefault(x => x.FullName == "D3DX9_43.dll");
if (d3dx == null)
return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
d3dx.ExtractToFile(tmpPath + "/" + d3dx.FullName);
if (HelperMethods.CalculateMD5(tmpPath + "/" + d3dx.FullName) != d3dHash)
return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
// Clean up
Directory.Delete(tmpPath, true);
// If we didn't exit before, everything is fine
log.Info("AM2R_11 check successful!");
return IsZipAM2R11ReturnCodes.Successful;
}
} }
Loading…
Cancel
Save