text:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
             If you want to change the Windows User Account Control level replace the
             requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Specifying requestedExecutionLevel element will disable file and registry virtualization.
            Remove this element if your application requires this virtualization for backwards
            compatibility.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
      <applicationRequestMinimum>
        <defaultAssemblyRequest permissionSetReference="Custom" />
        <PermissionSet ID="Custom" SameSite="site" Unrestricted="true" />
      </applicationRequestMinimum>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- A list of the Windows versions that this application has been tested on
           and is designed to work with. Uncomment the appropriate elements
           and Windows will automatically select the most compatible environment. -->
      <!-- Windows Vista -->
      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
      <!-- Windows 7 -->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
      <!-- Windows 8 -->
      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
      <!-- Windows 8.1 -->
      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
    </application>
  </compatibility>
  <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
       DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
       to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
       also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
  <!--
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
      <dpiAwarness>PerMonitorV2, PerMonitor</dpiAwarness>
    </windowsSettings>
  </application>
  -->
  <!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
  <!--
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>
  -->
  <!--
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add name="log" type="System.Diagnostics.TextWriterTraceListener" initializeData="utl-log.txt"/>
      </listeners>
    </trace>
  </system.diagnostics>
  -->
</assembly>


text:
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!--
    Microsoft ResX Schema

    Version 2.0

    The primary goals of this format is to allow a simple XML format
    that is mostly human readable. The generation and parsing of the
    various data types are done through the TypeConverter classes
    associated with the data types.

    Example:

    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>

    There are any number of "resheader" rows that contain simple
    name/value pairs.

    Each data row contains a name, and value. The row also contains a
    type or mimetype. Type corresponds to a .NET class that support
    text/value conversion through the TypeConverter architecture.
    Classes that don't support this are serialized and stored with the
    mimetype set.

    The mimetype is used for serialized objects, and tells the
    ResXResourceReader how to depersist the object. This is currently not
    extensible. For a given mimetype the value must be set accordingly:

    Note - application/x-microsoft.net.object.binary.base64 is the format
    that the ResXResourceWriter will generate, however the reader can
    read any of the formats listed below.

    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    <value>
[encoded data, 137452 characters]
</value>
  </data>
</root>

repo_name: thpatch/Universal-THCRAP-Launcher

repo_language: C#

mime_type: text/plain


text:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Universal_THCRAP_Launcher
{
    public static class I18N
    {
        public static readonly string I18NDir = Directory.GetCurrentDirectory() + @"\..\i18n\utl\";

        public static dynamic LangResource { get; private set; }

        public static int LangNumber()
        {
            if (Directory.Exists(I18NDir)) return Directory.GetFiles(I18NDir).Length;

            return 0;
        }

        private static dynamic GetLangResource(string filePath)
        {
            string raw = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject(raw);
        }

        public static void UpdateLangResource(string filePath)
        {
            try
            {
                LangResource = GetLangResource(filePath);
                Configuration.Lang = filePath.Replace(I18NDir, "");
            }
            catch (JsonReaderException e)
            {
                MessageBox.Show(e.Message, @"JSON Parser Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{E8802A2F-80F1-4727-A97D-78DED7F24E92}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <RootNamespace>Universal_THCRAP_Launcher</RootNamespace>
    <AssemblyName>Universal THCRAP Launcher</AssemblyName>
    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>false</Deterministic>
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <TargetFrameworkProfile />
    <PublishUrl>publish\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>false</MapFileExtensions>
    <SupportUrl>https://www.thpatch.net/</SupportUrl>
    <ErrorReportUrl>https://www.thpatch.net/</ErrorReportUrl>
    <ProductName>Universal THCRAP Launcher</ProductName>
    <PublisherName>Tudi20 %40 THPATCH</PublisherName>
    <SuiteName>THPATCH</SuiteName>
    <OpenBrowserOnPublish>false</OpenBrowserOnPublish>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.2.5.0</ApplicationVersion>
    <UseApplicationTrust>false</UseApplicationTrust>
    <PublishWizardCompleted>true</PublishWizardCompleted>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>TRACE;DEBUG</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>0</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>Resources\AbstractCactus_Icon_01.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup>
    <StartupObject>Universal_THCRAP_Launcher.Program</StartupObject>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <PropertyGroup>
    <SignManifests>false</SignManifests>
  </PropertyGroup>
  <PropertyGroup>
    <SignAssembly>false</SignAssembly>
  </PropertyGroup>
  <PropertyGroup>
    <AssemblyOriginatorKeyFile>
    </AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup>
    <TargetZone>LocalIntranet</TargetZone>
  </PropertyGroup>
  <PropertyGroup>
    <GenerateManifests>true</GenerateManifests>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestCertificateThumbprint>D3312BF3AE0D1F112DE1916859D2F9A021CA4A76</ManifestCertificateThumbprint>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestKeyFile>Universal THCRAP Launcher_1_TemporaryKey.pfx</ManifestKeyFile>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="I18N.cs" />
    <Compile Include="Log.cs" />
    <Compile Include="MainForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="MainForm.Designer.cs">
      <DependentUpon>MainForm.cs</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Properties\Settings1.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
      <DependentUpon>Settings.settings</DependentUpon>
    </Compile>
    <Compile Include="SettingsForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="SettingsForm.Designer.cs">
      <DependentUpon>SettingsForm.cs</DependentUpon>
    </Compile>
    <EmbeddedResource Include="MainForm.resx">
      <DependentUpon>MainForm.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <SubType>Designer</SubType>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="SettingsForm.resx">
      <DependentUpon>SettingsForm.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="app.manifest" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include=".NETFramework,Version=v4.6">
      <Visible>False</Visible>
      <ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Resources\Shinmera_Banner_5_mini_size.png" />
    <EmbeddedResource Include="Resources\Shinmera_Banner_5_mini_size_hover.png" />
    <EmbeddedResource Include="Resources\Sort-Ascending.png" />
    <EmbeddedResource Include="Resources\Sort-Descending.png" />
    <EmbeddedResource Include="Resources\Star.png" />
    <EmbeddedResource Include="Resources\Star_hollow.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <None Include="packages.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings1.Designer.cs</LastGenOutput>
    </None>
    <None Include="Resources\AbstractCactus_Icon_01.ico" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Custom.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Game.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\GameAndCustom.png" />
  </ItemGroup>
  <ItemGroup>
    <COMReference Include="IWshRuntimeLibrary">
      <Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>0</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\BuildDate.txt" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\BuildUser.txt" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Favorite.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Dice.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Trash.png" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PreBuildEvent>echo %25date%25 %25time%25 > "$(ProjectDir)Resources\BuildDate.txt"
echo %25USERNAME%25 > "$(ProjectDir)Resources\BuildUser.txt"</PreBuildEvent>
  </PropertyGroup>
</Project>


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Permissions;
using System.Security;
using System.Windows.Forms;

namespace Universal_THCRAP_Launcher
{
    class Log
    {
        private FileStream fs;
        private StreamWriter sw;

        public Log(string logFile)
        {
            var permissionSet = new PermissionSet(PermissionState.None);
            var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, Environment.CurrentDirectory + "\\" + logFile);
            permissionSet.AddPermission(writePermission);

            if (!permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
            {
                Console.WriteLine($"No write permission for {logFile}.");
                MessageBox.Show($"No write permission for {logFile}.");
                return;
            }

            // Delete log file if larger than 1 MB
            if (File.Exists(logFile) && new System.IO.FileInfo(logFile).Length >= 0x100000)
                File.Delete(logFile);

            string dirName = Path.GetDirectoryName(logFile);
            if (!Directory.Exists(dirName))
                Directory.CreateDirectory(dirName);

            fs = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
            sw = new StreamWriter(fs);
        }

        public void WriteLine(object text)
        {
            Console.WriteLine($"[{DateTime.Now.ToLongTimeString()}] " + text);
            if (sw == null) return;
            sw.WriteLine($"[{DateTime.Now.ToLongTimeString()}] " + text);
            sw.Flush();
            fs.Flush();
        }

        public void Write(object text)
        {
            Console.Write(text);
            if (sw == null) return;
            sw.Write(text);
            sw.Flush();
            fs.Flush();
        }

        ~Log()
        {
            if (sw != null)
            {
                sw.Flush();
                sw.Close();
                sw.Dispose();
            }
            if (fs != null)
            {
                fs.Flush();
                fs.Close();
                fs.Dispose();
            }
        }
    }
}


text:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
// ReSharper disable IdentifierTypo

namespace Universal_THCRAP_Launcher
{
    public partial class SettingsForm : Form
    {
        private readonly MainForm _mf;
        public SettingsForm(MainForm mainForm)
        {
            InitializeComponent();
            _mf = mainForm;
        }

        #region Globals
        private readonly Dictionary<string, string> _langNameToFile = new Dictionary<string, string>();
        private readonly Dictionary<string, string> _langFileToName = new Dictionary<string, string>();
        //private readonly Dictionary<string, string> _downNameToPatch = new Dictionary<string, string>();
        private int spaceWidth;

        #endregion

        #region Form Events
        private void SettingsForm_Load(object sender, EventArgs e)
        {

            spaceWidth = comboBox_gamesNamingType.Location.X - label_GameNames.Location.X - label_GameNames.Width;
            UpdateLang();
            cB_hidePatchExtension.Checked = MainForm.Configuration1.HidePatchExtension;
            closeOnExitCheckBox.Checked = MainForm.Configuration1.ExitAfterStartup;
            cB_ShowVanilla.Checked = MainForm.Configuration1.ShowVanilla;
            cB_OnlyAllowOneExe.Checked = MainForm.Configuration1.OnlyAllowOneExecutable;
            cB_onlyOneUTL.Checked = MainForm.Configuration1.OnlyAllowOneUtl;
            cb_ShowGameId.Checked = MainForm.Configuration1.ShowGameId;
            UpdateCredits();
            LoadLanguages();
        }
        #endregion

        #region GUI events
        private void TabControl_SelectedIndexChanged(object sender, EventArgs e) => UpdateAlign();
        private void closeOnExitCheckBox_CheckedChanged(object sender, EventArgs e) => MainForm.Configuration1.ExitAfterStartup = closeOnExitCheckBox.Checked;
        private void languageComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            _langNameToFile.TryGetValue(languageComboBox.SelectedItem.ToString(), out var file);
            I18N.UpdateLangResource(file);
            UpdateLang();
            UpdateCredits();
            _mf.PopulateGames();
            _mf.PopulatePatchList();
        }
        private void Btn_dwnlAllLangs_Click(object sender, EventArgs e)
        {
            btn_dwnlAllLangs.Text = I18N.LangResource.settingsForm.downloading != null ? (string)I18N.LangResource.settingsForm.downloading.ToString() : "Downloading...";
            btn_dwnlAllLangs.Enabled = false;
            try
            {
                string gh = ReadTextFromUrl("https://api.github.com/repos/Tudi20/Universal-THCRAP-Launcher/contents/langs?ref=master");
                dynamic objGh = JsonConvert.DeserializeObject(gh);
                foreach (dynamic item in objGh)
                {
                    string langtxt = ReadTextFromUrl(item.download_url.ToString());
                    File.WriteAllText(I18N.I18NDir + item.name, langtxt);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Couldn't connect to GitHub for pulling down languages.\nReason: {ex}");
                MessageBox.Show(I18N.LangResource.error.downloadError?.ToString(), I18N.LangResource.errors.error?.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            btn_dwnlAllLangs.Text = I18N.LangResource.settingsForm.downloadAll?.ToString();
            btn_dwnlAllLangs.Enabled = true;

            LoadLanguages();
        }
        private void CB_hidePatchExtension_CheckedChanged(object sender, EventArgs e)
        {
            MainForm.Configuration1.HidePatchExtension = cB_hidePatchExtension.Checked;
            _mf.PopulatePatchList();
        }
        private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e) => _mf.UpdateConfigFile();
        private void Cb_ShowGameId_CheckedChanged(object sender, EventArgs e)
        {
            MainForm.Configuration1.ShowGameId = cb_ShowGameId.Checked;
            _mf.PopulateGames();
        }
        private void CB_ShowVanilla_CheckedChanged(object sender, EventArgs e)
        {
            MainForm.Configuration1.ShowVanilla = cB_ShowVanilla.Checked;
            _mf.PopulatePatchList();
        }
        private void CB_OnlyAllowOneExe_CheckedChanged(object sender, EventArgs e) =>
            MainForm.Configuration1.OnlyAllowOneExecutable = cB_OnlyAllowOneExe.Checked;

        private void ComboBox_gamesNamingType_SelectedIndexChanged(object sender, EventArgs e)
        {
            MainForm.Configuration1.NamingForGames = (GameNameType)comboBox_gamesNamingType.SelectedIndex;
            cb_ShowGameId.Enabled = comboBox_gamesNamingType.SelectedIndex != 0;
            _mf.PopulateGames();
        }

        private void CB_onlyOneUTL_CheckedChanged(object sender, EventArgs e)
        {
            MainForm.Configuration1.OnlyAllowOneUtl = cB_onlyOneUTL.Checked;
            if (!cB_onlyOneUTL.Checked) return;
            Process[] processes = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            foreach (Process t in processes) if (t.Id != Process.GetCurrentProcess().Id) t.Kill();
        }
        #endregion

        #region GUI-releated Methods
        private void LoadLanguages()
        {
            #region LoadLanguages
            languageComboBox.Items.Clear();
            _langFileToName.Clear();
            _langNameToFile.Clear();
            Trace.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Loading languages...");
            foreach (var file in Directory.GetFiles(I18N.I18NDir))
            {
                string raw = File.ReadAllText(file);
                //Trace.WriteLine($"Language File: {file}. Here's the raw:\n{raw}");
                try
                {
                    dynamic langFile = JsonConvert.DeserializeObject(raw);
                    Trace.WriteLine($"\tLoading Language:\n\tFile: {file}\n\tEnglish name: {langFile.metadata.english}");
                    if (!_langNameToFile.ContainsKey($"{langFile.metadata.native} ({langFile.metadata.english})"))
                        _langNameToFile.Add($"{langFile.metadata.native} ({langFile.metadata.english})", file);
                    if (!_langFileToName.ContainsKey(file))
                        _langFileToName.Add(file, $"{langFile.metadata.native} ({langFile.metadata.english})");
                    if (!languageComboBox.Items.Contains($"{langFile.metadata.native} ({langFile.metadata.english})"))
                        languageComboBox.Items.Add($"{langFile.metadata.native} ({langFile.metadata.english})");
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Exception while parsing language file {file}\nException: {ex}");
                    MessageBox.Show(I18N.LangResource.errors.oops?.ToString() + Environment.CurrentDirectory, I18N.LangResource.errors.error?.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            #endregion
            Trace.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Language loading ended.");
            #region Select appropiate lang
            if (Configuration.Lang == null)
                languageComboBox.SelectedIndex = 0;
            else languageComboBox.SelectedItem = _langFileToName[I18N.I18NDir + Configuration.Lang];
            Debug.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Configuration.Lang is " + Configuration.Lang);
            Debug.WriteLine($"[{DateTime.Now.ToShortTimeString()}] Selected Language In GUI: " + languageComboBox.SelectedItem + " | " + languageComboBox.SelectedIndex);
            #endregion
        }
        private void UpdateLang()
        {
            Text = I18N.LangResource.settingsForm?.settings?.ToString();
            languageLabel.Text = I18N.LangResource.settingsForm?.language?.ToString() + ':';
            closeOnExitCheckBox.Text = I18N.LangResource.settingsForm?.closeOnExit?.ToString();
            btn_dwnlAllLangs.Text = I18N.LangResource.settingsForm?.downloadAll?.ToString();
            cB_hidePatchExtension.Text = I18N.LangResource.settingsForm?.hidePatchExtension?.ToString();
            tabPage_General.Text = I18N.LangResource.settingsForm?.tabs?.general?.ToString();
            tabPage_Language.Text = I18N.LangResource.settingsForm?.tabs?.language?.ToString();
            cB_ShowVanilla.Text = I18N.LangResource.settingsForm?.showVanilla?.ToString();
            cB_OnlyAllowOneExe.Text = I18N.LangResource.settingsForm?.onlyOneExe?.ToString();
            cB_onlyOneUTL.Text = I18N.LangResource.settingsForm?.onlyOneUTL?.ToString();
            cb_ShowGameId.Text = I18N.LangResource.settingsForm?.showGameId?.ToString();
            label_GameNames.Text = I18N.LangResource.settingsForm?.label_gameNaming?.ToString();
            comboBox_gamesNamingType.Items.Clear();
            for (var i = 0; i < 4; i++) comboBox_gamesNamingType.Items.Add(I18N.LangResource.settingsForm?.namingType?[i].ToString() ?? throw new InvalidOperationException());
            comboBox_gamesNamingType.SelectedIndex = (int)MainForm.Configuration1.NamingForGames;
            UpdateWidth();
            UpdateAlign();
        }

        private void UpdateAlign()
        {
            comboBox_gamesNamingType.Location = new Point(label_GameNames.Location.X + label_GameNames.Width + spaceWidth, comboBox_gamesNamingType.Location.Y);
            comboBox_gamesNamingType.Size = new Size(tabControl.Width - comboBox_gamesNamingType.Location.X - spaceWidth - comboBox_gamesNamingType.Margin.Horizontal - tabControl.Margin.Horizontal*2, comboBox_gamesNamingType.Height);
            languageComboBox.Location = new Point(label_GameNames.Location.X + languageLabel.Width + spaceWidth, languageComboBox.Location.Y);
            languageComboBox.Size = new Size(tabControl.Width - languageComboBox.Location.X - spaceWidth - languageComboBox.Margin.Horizontal - tabControl.Margin.Horizontal*2, languageComboBox.Height);
            btn_dwnlAllLangs.Size = new Size(tabControl.Width - btn_dwnlAllLangs.Location.X - spaceWidth - btn_dwnlAllLangs.Margin.Horizontal - tabControl.Margin.Horizontal*2, btn_dwnlAllLangs.Height);
        }

        private void UpdateWidth()
        {
            Width = 0;
            foreach (var item in tabPage_General.Controls)
            {
                if (!item.GetType().Equals(closeOnExitCheckBox.GetType())) continue;
                var width = ((CheckBox)item).Location.X + ((CheckBox)item).Width + tabControl.Margin.Horizontal*2 + ((CheckBox)item).Margin.Horizontal + ((CheckBox)item).Padding.Horizontal;
                if (width > Width)
                {
                    Width = width;
                    tabControl.Width = width;
                }
            }
        }

        private void UpdateCredits()
        {
            var credits = "";
            foreach (dynamic author in I18N.LangResource.metadata.authors)
            {
                credits += author?.ToString() + ", ";
            }
            credits = credits.TrimEnd(' ', ',');
            int place = credits.LastIndexOf(',');
            if (place != -1)
            {
                credits = credits.Remove(place, 1).Insert(place, " " + I18N.LangResource.settingsForm.and?.ToString());
            }
            langCreditsLabel.Text = string.Format(I18N.LangResource.settingsForm.langCredits?.ToString(), credits);
        }
        #endregion

        #region GUI-less Methods
        static string ReadTextFromUrl(string url)
        {
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            // Assume UTF8, but detect BOM - could also honor response charset I suppose
            var client = new WebClient();
            client.Headers.Add(HttpRequestHeader.UserAgent, "UTL");
            var stream = client.OpenRead(url);
            using (var textReader = new StreamReader(stream ?? throw new InvalidOperationException(), Encoding.UTF8, true))
            {
                return textReader.ReadToEnd();
            }
        }
        #endregion
    }
}