Commiting launcher 1.0.1.3 modified version as init commit
41
.gitignore
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Autosave files
|
||||
*~
|
||||
|
||||
# build
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
TestResults/
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.DS_Store
|
||||
*.sln.cache
|
||||
*.suo
|
||||
*.cache
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.log
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.user
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
Thumbs.db
|
||||
.vs/
|
||||
packages/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# resharper
|
||||
*_Resharper.*
|
||||
*.Resharper
|
||||
|
||||
# dotCover
|
||||
*.dotCover
|
6
CleanAndLaunch/App.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
</configuration>
|
52
CleanAndLaunch/CleanAndLaunch.csproj
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?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>{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>CleanAndLaunch</RootNamespace>
|
||||
<AssemblyName>CleanAndLaunch</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<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.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
120
CleanAndLaunch/Program.cs
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
|
||||
// The goal of this application is just to clean old files in the system and launch the new launcher... EZ RIGHT ? The app is called after the self updater included in the whole NaturalLauncher.
|
||||
// This is not used anymore. Meh !
|
||||
namespace CleanAndLaunch
|
||||
{
|
||||
class Program
|
||||
{
|
||||
public static string curDir = Directory.GetCurrentDirectory();
|
||||
public static string ProcessName = "NaturalLauncher.exe";
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
DeleteOldFiles();
|
||||
|
||||
System.Timers.Timer ReLaunchTimer = new System.Timers.Timer();
|
||||
ReLaunchTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
|
||||
ReLaunchTimer.Interval = 100;
|
||||
ReLaunchTimer.Enabled = true;
|
||||
Console.Read();
|
||||
}
|
||||
|
||||
public static void OnTimedEvent(object source, ElapsedEventArgs e)
|
||||
{
|
||||
if (IsProcessOpen(ProcessName)==false)
|
||||
{
|
||||
Launch();
|
||||
}
|
||||
}
|
||||
|
||||
static void Launch()
|
||||
{
|
||||
Console.WriteLine("Launching...");
|
||||
|
||||
Process myprocess = new Process();
|
||||
myprocess.StartInfo.FileName = curDir + Path.DirectorySeparatorChar + ProcessName;
|
||||
try
|
||||
{
|
||||
ProcessStartInfo processInfo = new ProcessStartInfo();
|
||||
processInfo.WorkingDirectory = curDir;
|
||||
processInfo.FileName = ProcessName;
|
||||
processInfo.ErrorDialog = true;
|
||||
processInfo.UseShellExecute = false;
|
||||
processInfo.RedirectStandardOutput = true;
|
||||
processInfo.RedirectStandardError = true;
|
||||
Process proc = Process.Start(processInfo);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static bool IsProcessOpen(string name)
|
||||
{
|
||||
foreach (Process clsProcess in Process.GetProcesses())
|
||||
{
|
||||
if (clsProcess.ProcessName.Contains(name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void DeleteOldFiles()
|
||||
{
|
||||
Console.WriteLine("Cleaning old and update files ...");
|
||||
foreach (string file in Directory.GetFiles(curDir))
|
||||
{
|
||||
// Cleaning BAK files
|
||||
if (Path.GetExtension(file) == ".bak")
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
string localPath = ToLocalPath(curDir, file);
|
||||
|
||||
// Cleaning UpdateLogs files
|
||||
if (localPath.StartsWith("/UpdateLog"))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToLocalPath(string root, string dir)
|
||||
{
|
||||
return dir.Replace(root, "").Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
}
|
36
CleanAndLaunch/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Les informations générales relatives à un assembly dépendent de
|
||||
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
|
||||
// associées à un assembly.
|
||||
[assembly: AssemblyTitle("CleanAndLaunch")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CleanAndLaunch")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
|
||||
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
|
||||
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
|
||||
[assembly: Guid("8e7856fd-fa68-4356-9c88-54c9ef5a9d20")]
|
||||
|
||||
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
|
||||
//
|
||||
// Version principale
|
||||
// Version secondaire
|
||||
// Numéro de build
|
||||
// Révision
|
||||
//
|
||||
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
|
||||
// en utilisant '*', comme indiqué ci-dessous :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
25
LICENSE
|
@ -1,16 +1,15 @@
|
|||
MIT License
|
||||
This programm is an updater to keep your Natural Selection 1 mod folder up with the latest updates.
|
||||
|
||||
Copyright (c) 2018 ENSL
|
||||
Copyright (C) <2018> <Mael "Khelben" Vignaux>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version. Commercial use is prohibited.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
@ -19,3 +18,9 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
6
ManifestBuilder/App.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
</configuration>
|
40
ManifestBuilder/LauncherManifest.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ManifestBuilder
|
||||
{
|
||||
class LauncherManifest
|
||||
{
|
||||
public LauncherManifest()
|
||||
{
|
||||
Files = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public Dictionary<string, string> Files
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
58
ManifestBuilder/ManifestBuilder.csproj
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?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>{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>ManifestBuilder</RootNamespace>
|
||||
<AssemblyName>ManifestBuilder</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.11.0.2\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.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="LauncherManifest.cs" />
|
||||
<Compile Include="ManifestBuildor.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
86
ManifestBuilder/ManifestBuildor.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ManifestBuilder
|
||||
{
|
||||
class ManifestBuildor
|
||||
{
|
||||
public static string ManifestName = "Manifest.txt";
|
||||
|
||||
public static void BuildManifest(string directory)
|
||||
{
|
||||
|
||||
LauncherManifest manifest = new LauncherManifest();
|
||||
|
||||
md5 = MD5.Create();
|
||||
|
||||
RecursiveBuildManifest(directory, "", manifest);
|
||||
|
||||
string ManifestPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + ManifestName;
|
||||
File.WriteAllText(ManifestPath, JsonConvert.SerializeObject(manifest, Formatting.Indented));
|
||||
}
|
||||
|
||||
private static MD5 md5;
|
||||
|
||||
private static void RecursiveBuildManifest(string projectRoot, string dir, LauncherManifest manifest)
|
||||
{
|
||||
string path = projectRoot + dir;
|
||||
|
||||
foreach (string file in Directory.GetFiles(path))
|
||||
{
|
||||
string localPath = ToLocalPath(projectRoot, file);
|
||||
string hash = ComputeMD5(file);
|
||||
|
||||
if(!localPath.EndsWith("_.cfg") && localPath != "/ManifestBuilder.exe" && localPath != "/Manifest.txt"
|
||||
&& localPath != "/Newtonsoft.Json.dll") //we don't want cfg files to get updated here cept config.cfg which is in ignore.list
|
||||
manifest.Files[localPath] = hash;
|
||||
}
|
||||
|
||||
foreach (string nextDir in Directory.GetDirectories(path))
|
||||
{
|
||||
RecursiveBuildManifest(projectRoot, ToLocalPath(projectRoot, nextDir), manifest);
|
||||
}
|
||||
}
|
||||
|
||||
private static string ToLocalPath(string root, string dir)
|
||||
{
|
||||
return dir.Replace(root, "").Replace("\\", "/");
|
||||
}
|
||||
|
||||
public static string ComputeMD5(string file)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
|
||||
string hash = "";
|
||||
using (var stream = File.OpenRead(file))
|
||||
{
|
||||
hash = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "");
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
39
ManifestBuilder/Program.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace ManifestBuilder
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string curDir = Directory.GetCurrentDirectory();
|
||||
Console.WriteLine("Building manifest in : " + curDir);
|
||||
ManifestBuildor.BuildManifest(curDir);
|
||||
}
|
||||
}
|
||||
}
|
36
ManifestBuilder/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Les informations générales relatives à un assembly dépendent de
|
||||
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
|
||||
// associées à un assembly.
|
||||
[assembly: AssemblyTitle("ManifestBuilder")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ManifestBuilder")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
|
||||
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
|
||||
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
|
||||
[assembly: Guid("6a7dbe40-6bfb-49f5-bfc1-9f0752ec31be")]
|
||||
|
||||
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
|
||||
//
|
||||
// Version principale
|
||||
// Version secondaire
|
||||
// Numéro de build
|
||||
// Révision
|
||||
//
|
||||
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
|
||||
// en utilisant '*', comme indiqué ci-dessous :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
4
ManifestBuilder/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net462" />
|
||||
</packages>
|
37
NaturalLauncher.sln
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27703.2042
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NaturalLauncher", "NaturalLauncher\NaturalLauncher.csproj", "{0138DD06-7386-4820-9BCE-3F8412CAD801}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManifestBuilder", "ManifestBuilder\ManifestBuilder.csproj", "{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanAndLaunch", "CleanAndLaunch\CleanAndLaunch.csproj", "{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06E5B626-B631-47BF-84D5-A157442007E0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
44
NaturalLauncher/App.config
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="NaturalLauncher.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<NaturalLauncher.Properties.Settings>
|
||||
<setting name="ConfigurationUrl" serializeAs="String">
|
||||
<value>http://ensl.gk-servers.de/</value>
|
||||
</setting>
|
||||
<setting name="IndexURL" serializeAs="String">
|
||||
<value>http://ensl.gk-servers.de/</value>
|
||||
</setting>
|
||||
<setting name="CreditURL" serializeAs="String">
|
||||
<value>http://ensl.gk-servers.de/</value>
|
||||
</setting>
|
||||
<setting name="GameUrl" serializeAs="String">
|
||||
<value>http://ensl.gk-servers.de/ns</value>
|
||||
</setting>
|
||||
<setting name="GatherURL" serializeAs="String">
|
||||
<value>https://www.ensl.org/gathers/latest/ns1</value>
|
||||
</setting>
|
||||
<setting name="NineLegendUrl" serializeAs="String">
|
||||
<value>http://www.elseware-experience.com/vignauxmael/NaturalLauncher/NLPack</value>
|
||||
</setting>
|
||||
<setting name="LauncherUrl" serializeAs="String">
|
||||
<value>http://ensl.gk-servers.de/Launcher/</value>
|
||||
</setting>
|
||||
</NaturalLauncher.Properties.Settings>
|
||||
</userSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
9
NaturalLauncher/App.xaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<Application x:Class="NaturalLauncher.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:NaturalLauncher"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
12
NaturalLauncher/App.xaml.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
using System.Windows;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
123
NaturalLauncher/ConsoleManager.cs
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
public static class ConsoleManager
|
||||
{
|
||||
private const string Kernel32_DllName = "kernel32.dll";
|
||||
|
||||
[DllImport(Kernel32_DllName)]
|
||||
private static extern bool AllocConsole();
|
||||
|
||||
[DllImport(Kernel32_DllName)]
|
||||
private static extern bool FreeConsole();
|
||||
|
||||
[DllImport(Kernel32_DllName)]
|
||||
private static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[DllImport(Kernel32_DllName)]
|
||||
private static extern int GetConsoleOutputCP();
|
||||
|
||||
public static bool HasConsole
|
||||
{
|
||||
get { return GetConsoleWindow() != IntPtr.Zero; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new console instance if the process is not attached to a console already.
|
||||
/// </summary>
|
||||
public static void Show()
|
||||
{
|
||||
//#if DEBUG
|
||||
if (!HasConsole)
|
||||
{
|
||||
AllocConsole();
|
||||
InvalidateOutAndError();
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown.
|
||||
/// </summary>
|
||||
public static void Hide()
|
||||
{
|
||||
//#if DEBUG
|
||||
if (HasConsole)
|
||||
{
|
||||
SetOutAndErrorNull();
|
||||
FreeConsole();
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
public static void Toggle()
|
||||
{
|
||||
if (HasConsole)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
Show();
|
||||
}
|
||||
}
|
||||
|
||||
static void InvalidateOutAndError()
|
||||
{
|
||||
Type type = typeof(System.Console);
|
||||
|
||||
System.Reflection.FieldInfo _out = type.GetField("_out",
|
||||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
|
||||
|
||||
System.Reflection.FieldInfo _error = type.GetField("_error",
|
||||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
|
||||
|
||||
System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
|
||||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
|
||||
|
||||
Debug.Assert(_out != null);
|
||||
Debug.Assert(_error != null);
|
||||
|
||||
Debug.Assert(_InitializeStdOutError != null);
|
||||
|
||||
_out.SetValue(null, null);
|
||||
_error.SetValue(null, null);
|
||||
|
||||
_InitializeStdOutError.Invoke(null, new object[] { true });
|
||||
}
|
||||
|
||||
static void SetOutAndErrorNull()
|
||||
{
|
||||
Console.SetOut(TextWriter.Null);
|
||||
Console.SetError(TextWriter.Null);
|
||||
}
|
||||
}
|
||||
}
|
275
NaturalLauncher/Launcher.cs
Normal file
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using DiscordRPC;
|
||||
using Newtonsoft.Json;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class Launcher
|
||||
{
|
||||
public static string curDir = Directory.GetCurrentDirectory();
|
||||
public static Uri MainPageURL = new Uri(Properties.Settings.Default.IndexURL);
|
||||
public static Uri CreditPageURL = new Uri(Properties.Settings.Default.CreditURL);
|
||||
|
||||
public static string HLFolder = "";
|
||||
public static string NSFolder;
|
||||
|
||||
public static string VersionFileName = "app.version";
|
||||
public static string ManifestName = "Manifest.txt";
|
||||
public static string NLManifestName = "NLManifest.txt";
|
||||
public static string configName = "Launcher.xml";
|
||||
|
||||
public static bool keepLauncherAlive = true;
|
||||
public static DateTime LAUNCHTIME = System.DateTime.UtcNow;
|
||||
public static string discordCustomStatus = "Currently In The Launcher";
|
||||
|
||||
public static void PlayGame()
|
||||
{
|
||||
LAUNCHTIME = System.DateTime.UtcNow; //new time is launch time
|
||||
UpdateDiscord(true); //doesnt work cause the timer set it back to false. need static var TODO
|
||||
Process.Start("steam://rungameid/17558255459196993606");
|
||||
//Environment.Exit(0); // not stopping the process to let discord rpc live
|
||||
if (!keepLauncherAlive)
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
internal static void UpdateDiscord(bool InGame)
|
||||
{
|
||||
int gatherPlayers = Util.ReadGathererCount();
|
||||
UpdatePubServ(out int pubPlayers, out int maxPlayers);
|
||||
|
||||
int displayPlayers = pubPlayers; //by default
|
||||
string discordState = "Players in public";
|
||||
|
||||
if (gatherPlayers > 6)
|
||||
{
|
||||
displayPlayers = gatherPlayers;
|
||||
discordState = "Gather forming";
|
||||
}
|
||||
|
||||
if (!InGame)
|
||||
{
|
||||
MainWindow.Discordclient.SetPresence(new RichPresence()
|
||||
{
|
||||
Details = discordCustomStatus,
|
||||
State = discordState,
|
||||
/*Secrets = new Secrets()
|
||||
{
|
||||
JoinSecret = "MTI4NzM0OjFpMmhuZToxMjMxMjM",
|
||||
},*/
|
||||
Party = new Party()
|
||||
{
|
||||
ID = "ae488379 - 351d - 4a4f - ad32 - 2b9b01c91657",
|
||||
Size = displayPlayers,
|
||||
Max = 12,
|
||||
},
|
||||
Timestamps = new Timestamps()
|
||||
{
|
||||
Start = LAUNCHTIME,
|
||||
},
|
||||
Assets = new Assets()
|
||||
{
|
||||
LargeImageKey = "portrait_png",
|
||||
LargeImageText = "Natural Selection Enhanced Launcher",
|
||||
SmallImageKey = "skulku_png",
|
||||
},
|
||||
});
|
||||
}
|
||||
if (InGame)
|
||||
{
|
||||
MainWindow.Discordclient.SetPresence(new RichPresence()
|
||||
{
|
||||
Details = "In Game",
|
||||
State = "Next gather",
|
||||
Party = new Party()
|
||||
{
|
||||
ID = "ae488379 - 351d - 4a4f - ad32 - 2b9b01c91657",
|
||||
Size = Util.ReadGathererCount(),
|
||||
Max = 12,
|
||||
},
|
||||
Timestamps = new Timestamps()
|
||||
{
|
||||
Start = LAUNCHTIME,
|
||||
},
|
||||
Assets = new Assets()
|
||||
{
|
||||
LargeImageKey = "portrait_png",
|
||||
LargeImageText = "Natural Selection Enhanced Launcher",
|
||||
SmallImageKey = "skulku_png",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void LaunchWebsite(string Url)
|
||||
{
|
||||
Process.Start(Url);
|
||||
}
|
||||
|
||||
public static void RefreshInternetPageAsync(string whichPage)
|
||||
{
|
||||
using (var webClient = new WebClient())
|
||||
{
|
||||
if(whichPage == "Main")
|
||||
{
|
||||
string FileName = "index.html";
|
||||
webClient.DownloadFileAsync(MainPageURL, FileName);
|
||||
}
|
||||
|
||||
if (whichPage == "Credit")
|
||||
{
|
||||
string CreditFileName = "credit.html";
|
||||
webClient.DownloadFileAsync(CreditPageURL, CreditFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckInstallDirectory()
|
||||
{
|
||||
bool NeedDirectory = false;
|
||||
|
||||
if (File.Exists(curDir + Path.DirectorySeparatorChar + configName))
|
||||
{
|
||||
string IndicatedFolder = "";
|
||||
bool IsNLPack = false;
|
||||
XmlBuilder.ReadConfigXml(out IndicatedFolder, out IsNLPack, out string discordStatus, out bool keepAlive);
|
||||
|
||||
if (IndicatedFolder.Length >0)
|
||||
{
|
||||
HLFolder = IndicatedFolder;
|
||||
discordCustomStatus = discordStatus;
|
||||
keepLauncherAlive = keepAlive;
|
||||
}
|
||||
else
|
||||
NeedDirectory = true;
|
||||
|
||||
if (!Directory.Exists(IndicatedFolder))
|
||||
NeedDirectory = true;
|
||||
}
|
||||
else
|
||||
NeedDirectory = true;
|
||||
|
||||
if (NeedDirectory)
|
||||
{
|
||||
string folderPath = Util.AskForHLFolder();
|
||||
|
||||
if (folderPath!=null)
|
||||
{
|
||||
HLFolder = folderPath;
|
||||
NSFolder = HLFolder + Path.DirectorySeparatorChar + "ns";
|
||||
XmlBuilder.CreateConfigXml();
|
||||
|
||||
if (Directory.Exists(NSFolder))
|
||||
{
|
||||
if(System.Windows.Forms.MessageBox.Show("Warning, you are updating an existing NS installation: "
|
||||
+ Environment.NewLine + "A backup of your old ns folder can be made under the name ns_saved.zip"
|
||||
+ Environment.NewLine + "Please choose if you want to backup your current ns folder.", "", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)== DialogResult.Yes)
|
||||
{ Util.ZipDirectory(NSFolder); }
|
||||
}
|
||||
else
|
||||
{
|
||||
Directory.CreateDirectory(NSFolder);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Environment.Exit(0); //stop the process
|
||||
}
|
||||
}
|
||||
|
||||
NSFolder = HLFolder + Path.DirectorySeparatorChar + "ns";
|
||||
|
||||
}
|
||||
|
||||
public static bool IsNLPack()
|
||||
{
|
||||
bool Result = false; //by default
|
||||
if (File.Exists(curDir + Path.DirectorySeparatorChar + configName))
|
||||
{
|
||||
string IndicatedFolder = "";
|
||||
XmlBuilder.ReadConfigXml(out IndicatedFolder, out Result, out string plop, out bool noob);
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PlaySoundFX("error");
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Launcher Config file not found");
|
||||
|
||||
CheckInstallDirectory();
|
||||
return false;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
public static void SetIsNLPack(bool IsNlPack)
|
||||
{
|
||||
XmlBuilder.CreateConfigXml();
|
||||
}
|
||||
|
||||
public static void AddToIgnoreList()
|
||||
{
|
||||
Util.GetIgnoreManifest(true); //let's verify we have a ignore list from the start
|
||||
|
||||
string IgnorePath = curDir + Path.DirectorySeparatorChar + "customignore.list";
|
||||
string IgnoreString = File.ReadAllText(IgnorePath);
|
||||
LauncherManifest IgnoreManifest = JsonConvert.DeserializeObject<LauncherManifest>(IgnoreString);// then get it
|
||||
|
||||
var dialog = new System.Windows.Forms.OpenFileDialog();
|
||||
|
||||
dialog.InitialDirectory = NSFolder;
|
||||
dialog.Multiselect = true;
|
||||
|
||||
dialog.Title = "Please indicate what file(s) to add in the ignore list !";
|
||||
|
||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
foreach(string file in dialog.FileNames)
|
||||
{
|
||||
string localPath = Util.ToLocalPath(NSFolder, file);
|
||||
IgnoreManifest.Files[localPath] = "1"; //we using the launchermanifest but set "1" to ignore verify and update ("0" is ignore only update)
|
||||
}
|
||||
|
||||
File.WriteAllText(IgnorePath, JsonConvert.SerializeObject(IgnoreManifest, Formatting.Indented));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdatePubServ(out int publicPlayers, out int maxPlayers)
|
||||
{
|
||||
// TO BE CONTINUED but so far we can retrieve pub serv info...
|
||||
string serverIP = "104.156.251.121"; //public us
|
||||
int port = 27015;
|
||||
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(serverIP), port);
|
||||
|
||||
var ServInfo = new ServerChecker.A2S_INFO(remoteEP);
|
||||
|
||||
publicPlayers = ServInfo.Players; //out
|
||||
maxPlayers = ServInfo.MaxPlayers; //out
|
||||
// Check for the launcher to self update
|
||||
}
|
||||
}
|
||||
}
|
40
NaturalLauncher/LauncherManifest.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class LauncherManifest
|
||||
{
|
||||
public LauncherManifest()
|
||||
{
|
||||
Files = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public Dictionary<string, string> Files
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
76
NaturalLauncher/MainWindow.xaml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<Window x:Name="Launcher_Window" x:Class="NaturalLauncher.MainWindow"
|
||||
Closed="MainWindow_Closed"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:NaturalLauncher"
|
||||
mc:Ignorable="d"
|
||||
Title="Natural Launcher v ...." Height="615.5" Width="930" MinWidth="930" MinHeight="550" BorderThickness="0,0,0,0">
|
||||
<Window.TaskbarItemInfo>
|
||||
<TaskbarItemInfo Description="The Natural Launcher"
|
||||
ProgressValue="0" ProgressState="Normal"/>
|
||||
</Window.TaskbarItemInfo>
|
||||
<Window.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Open Natural Selection Folder" Click="OpenNSFolder"/>
|
||||
<MenuItem Header="Check for updaters update" Click="CheckLauncherUpdate"/>
|
||||
<MenuItem Header="Add files to ignore list" Click="AddToIgnore"/>
|
||||
<Separator />
|
||||
<MenuItem Header="Join the official Discord !" Click="JoinDiscord"/>
|
||||
<MenuItem Header="Credits" Click="SeeCredit"/>
|
||||
<Separator />
|
||||
<MenuItem Header="Build Manifest (dev)" Click="BuildManifest"/>
|
||||
</ContextMenu>
|
||||
</Window.ContextMenu>
|
||||
<Window.Icon>
|
||||
<ImageSource>Ressources/nsl_icon.ico</ImageSource>
|
||||
</Window.Icon>
|
||||
<Window.Background>
|
||||
<ImageBrush ImageSource="Ressources/background_blur.png"/>
|
||||
</Window.Background>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="9*"/>
|
||||
<ColumnDefinition Width="598*"/>
|
||||
<ColumnDefinition Width="268*"/>
|
||||
<ColumnDefinition Width="47*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label x:Name="TitleLabel" Content="Natural Selection Launcher" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" FontSize="24" FontFamily="Britannic Bold" FontWeight="Bold" Height="32" Width="336" Foreground="#FFEEC160" RenderTransformOrigin="0.5,0.5" Grid.Column="1">
|
||||
<Label.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform/>
|
||||
<SkewTransform/>
|
||||
<RotateTransform Angle="-0.229"/>
|
||||
<TranslateTransform/>
|
||||
</TransformGroup>
|
||||
</Label.RenderTransform>
|
||||
</Label>
|
||||
<Rectangle Fill="#A50D0D0C" Margin="0,0,10,32" Stroke="Black" Grid.ColumnSpan="3" Height="46" VerticalAlignment="Bottom" Grid.Column="1"/>
|
||||
<Label x:Name="VersionLabel" Content="checking" Margin="341,10,0,0" VerticalAlignment="Top" FontStyle="Italic" Background="#00000000" Foreground="#FF5ACAFF" Height="38" Grid.Column="1" FontWeight="Bold" FontSize="14" HorizontalAlignment="Left" Width="74" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
<WebBrowser x:Name="MainWebBrowser" Margin="0,47,10,83" UseLayoutRounding="False" RenderTransformOrigin="0.498,0.492" Grid.ColumnSpan="3" Grid.Column="1"/>
|
||||
<Button x:Name="StartButton" Content="Start" Margin="0,0,10,32" FontWeight="Bold" FontSize="24" Background="#A5151513" Padding="1,1,1,3" Height="46" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="296" Click="Start_Click" Grid.Column="2" BorderBrush="#FF5A71FF" Foreground="#FF2149D3" BorderThickness="2,1" Grid.ColumnSpan="2"/>
|
||||
<Button x:Name="WebsiteButton" Content="Join Gather" HorizontalAlignment="Left" Margin="0,0,0,32" Width="218" FontSize="18" Background="#A5151513" Padding="1,1,1,3" Height="46" VerticalAlignment="Bottom" Click="Website_Click" BorderBrush="#FFCD6E52" Grid.Column="1" Foreground="#FF2EB2F0" FontWeight="Bold"/>
|
||||
<Button x:Name="SettingButton" Content="Settings" Margin="223,0,0,32" FontSize="18" Background="#A5151513" Padding="1,1,1,3" Height="46" VerticalAlignment="Bottom" Click="Setting_Click" Grid.Column="1" BorderBrush="#FF787539" HorizontalAlignment="Left" Width="180" Foreground="#FF2EB2F0" FontWeight="Bold"/>
|
||||
<ProgressBar x:Name="UpdateProgressBar" Margin="0,0,0,6" Grid.ColumnSpan="2" Height="21" VerticalAlignment="Bottom" Foreground="#FF8CC197" Grid.Column="1">
|
||||
<ProgressBar.Background>
|
||||
<SolidColorBrush Color="#FFD8D8D8" Opacity="0.6"/>
|
||||
</ProgressBar.Background>
|
||||
</ProgressBar>
|
||||
<Label x:Name="ProgressLabel" Content="" Margin="48,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.ColumnSpan="2" Height="32" VerticalAlignment="Bottom" Foreground="Black" Grid.Column="1" FontWeight="Bold" FontSize="14"/>
|
||||
<Button x:Name="VerifyButton" Content="Verify" Margin="408,0,0,32" FontSize="18" Background="#A5151513" Padding="1,1,1,3" Height="46" VerticalAlignment="Bottom" Click="Verify_Click" Grid.Column="1" BorderBrush="#FF239758" HorizontalAlignment="Left" Width="180" Foreground="#FF2EB2F0" FontWeight="Bold"/>
|
||||
<Button x:Name="PauseButton" Content="" Grid.Column="3" Margin="5,0,10,6" FontWeight="Bold" FontStyle="Italic" FontSize="14" BorderBrush="#FF5993E6" Height="21" VerticalAlignment="Bottom" Click="Pause_Click">
|
||||
<Button.Background>
|
||||
<ImageBrush ImageSource="Ressources/pauseimage.png" Stretch="Uniform"/>
|
||||
</Button.Background>
|
||||
</Button>
|
||||
<Image Grid.Column="2" Margin="9,24,0,0" Source="Ressources/steam_icon.png" Stretch="Fill" Height="18" VerticalAlignment="Top" HorizontalAlignment="Left" Width="25"/>
|
||||
<Label x:Name="ServInfoLabel" Content="Public Server :" Grid.Column="2" HorizontalAlignment="Left" Margin="34,20,0,0" VerticalAlignment="Top" Foreground="White" FontFamily="Segoe WP Black" Width="224">
|
||||
<Label.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Join the server" Click="JoinPublicServer"/>
|
||||
</ContextMenu>
|
||||
</Label.ContextMenu>
|
||||
</Label>
|
||||
</Grid>
|
||||
</Window>
|
661
NaturalLauncher/MainWindow.xaml.cs
Normal file
|
@ -0,0 +1,661 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using System.Threading;
|
||||
using DiscordRPC;
|
||||
using System.Timers;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Resources;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
// TODO We need to know if ns files are being updated to lock the verify/update functions if so (with a file on the main serv).
|
||||
|
||||
public static bool IsDebugMode = false; //no use anymore, but stay here just in case I need him
|
||||
public static bool IsVerification = true; //true by default since it's more commun to verify than to update
|
||||
|
||||
public static Settings sw;
|
||||
|
||||
public static string versionNumber;
|
||||
public static string remoteVersionNumber;
|
||||
|
||||
public static bool downloadCancelled = false;
|
||||
|
||||
public BackgroundWorker backgroundWorker;
|
||||
public static DiscordRpcClient Discordclient;
|
||||
|
||||
Uri LocalIndexURL = new Uri(String.Format("file:///{0}/index.html", Launcher.curDir));
|
||||
|
||||
private static string LogReportPath = Launcher.curDir;
|
||||
TextWriter UpdateLog;
|
||||
|
||||
public void MainWindow_Closed(object sender, EventArgs e)
|
||||
{
|
||||
if (sw != null)
|
||||
{
|
||||
sw.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
#if DEBUG
|
||||
IsDebugMode = true;
|
||||
#endif
|
||||
|
||||
SelfUpdater.DeleteOldFiles(); // not really needed since CleanAndLaunch.exe
|
||||
|
||||
SelfUpdater TheSelfUpdater = new SelfUpdater();
|
||||
TheSelfUpdater.SetMainWindowRef(this);
|
||||
TheSelfUpdater.UpdateLauncher();
|
||||
|
||||
|
||||
if (SelfUpdater.LaucherRemoteVNumber != SelfUpdater.LaucherLocalVNumber && SelfUpdater.isSelfUpdating)
|
||||
{
|
||||
this.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the title of the window with the correct launcher version
|
||||
if (SelfUpdater.isSelfUpdating)
|
||||
Launcher_Window.Title = "Natural Launcher v " + SelfUpdater.LaucherLocalVNumber;
|
||||
else
|
||||
Launcher_Window.Title = "Natural Launcher";
|
||||
|
||||
// CHECK THE HL AND NS INSTALL DIR AND WRITE IT IN THE LAUNCHER XML
|
||||
Launcher.CheckInstallDirectory();
|
||||
|
||||
//Util.ChangeAValueInCfg("net_graph", "2"); //this is not useful but might be someday, that's why I still let it live
|
||||
|
||||
// WE SET DISCORD PRESENCE
|
||||
string ApplicationID = "474144509048127503";
|
||||
Discordclient = new DiscordRpcClient(ApplicationID);
|
||||
|
||||
Discordclient.Initialize();
|
||||
|
||||
OnlineStatusAtLaunch();
|
||||
|
||||
System.Timers.Timer PresenceTimer = new System.Timers.Timer();
|
||||
PresenceTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
|
||||
PresenceTimer.Enabled = true;
|
||||
PresenceTimer.Interval = 5000;
|
||||
|
||||
// *** Get the main index.html if connected *** \\
|
||||
if (Util.CheckForInternetConnection(Launcher.MainPageURL.AbsoluteUri)) //if we are connected
|
||||
{
|
||||
Launcher.RefreshInternetPageAsync("Main"); // we refresh the page
|
||||
MainWebBrowser.Source = Launcher.MainPageURL; // and display it from source
|
||||
}
|
||||
else // if not simply show the saved file
|
||||
{
|
||||
MainWebBrowser.Navigate(LocalIndexURL.AbsolutePath);
|
||||
}
|
||||
|
||||
// CHECK APP.VERSION NUMBER
|
||||
Check_Version();
|
||||
|
||||
if (versionNumber != remoteVersionNumber && versionNumber != "0.0.0.0")
|
||||
{
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Update Needed !", "Update", MessageBoxButton.OK, MessageBoxImage.Exclamation);
|
||||
StartButton.Content = "Please Update";
|
||||
IsVerification = false;
|
||||
}
|
||||
if (versionNumber == "0.0.0.0")
|
||||
{
|
||||
StartButton.Content = "Verify";
|
||||
IsVerification = false;
|
||||
|
||||
}
|
||||
if (versionNumber == remoteVersionNumber && versionNumber != "0.0.0.0")
|
||||
{
|
||||
StartButton.Content = "Play"; // TODO The algorithm to verify btween local and remote manifest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ReadyLauncherForUpdate(string FirstLogLine)
|
||||
{
|
||||
StartButton.IsEnabled = false;
|
||||
VerifyButton.IsEnabled = false;
|
||||
SettingButton.IsEnabled = false;
|
||||
UpdateLog = new StreamWriter(LogReportPath + Path.DirectorySeparatorChar + "UpdateLog_" + Util.GetLongTimeString() + ".txt", true); // dt forget to close()
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + FirstLogLine);
|
||||
}
|
||||
|
||||
private void OnTimedEvent(object source, ElapsedEventArgs e)
|
||||
{
|
||||
Launcher.UpdateDiscord(false);
|
||||
|
||||
Delegate myDelegate = (Action)Update_gatherButton;
|
||||
Delegate secondDelegate = (Action)Update_ServLabel;
|
||||
WebsiteButton.Dispatcher.Invoke(myDelegate);
|
||||
ServInfoLabel.Dispatcher.Invoke(secondDelegate);
|
||||
}
|
||||
|
||||
private void OnlineStatusAtLaunch()
|
||||
{
|
||||
Launcher.UpdateDiscord(false);
|
||||
|
||||
Delegate myDelegate = (Action)Update_gatherButton;
|
||||
Delegate secondDelegate = (Action)Update_ServLabel;
|
||||
WebsiteButton.Dispatcher.Invoke(myDelegate);
|
||||
ServInfoLabel.Dispatcher.Invoke(secondDelegate);
|
||||
}
|
||||
|
||||
private void Update_gatherButton()
|
||||
{
|
||||
if(Util.ReadGathererCount()>0)
|
||||
WebsiteButton.Content = "Join Gather ( " + Util.ReadGathererCount() + " / 12 )";
|
||||
else
|
||||
WebsiteButton.Content = "Join Gather";
|
||||
}
|
||||
|
||||
private void Update_ServLabel()
|
||||
{
|
||||
Launcher.UpdatePubServ(out int pubPlayers, out int maxPlayers);
|
||||
ServInfoLabel.Content = "Public Server : " + pubPlayers + " / " + maxPlayers;
|
||||
|
||||
}
|
||||
|
||||
private void Check_Version()
|
||||
{
|
||||
// *** Get the version number *** \\
|
||||
versionNumber = Util.LocalVersion(Launcher.curDir + Path.DirectorySeparatorChar + Launcher.VersionFileName);
|
||||
remoteVersionNumber = Util.RemoteVersion(Properties.Settings.Default.IndexURL + Launcher.VersionFileName);
|
||||
|
||||
if (versionNumber != null)
|
||||
{
|
||||
VersionLabel.Content = versionNumber;
|
||||
}
|
||||
else //if it doesn exist, we need to inform the user
|
||||
{
|
||||
versionNumber = "0.0.0.0";
|
||||
VersionLabel.Content = "Verify";
|
||||
StartButton.Content = "Verify";
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Please verify the installation" + Environment.NewLine
|
||||
+ "This message will show up if this is the first time you launch this software"
|
||||
, "Alert", MessageBoxButton.OK, MessageBoxImage.Exclamation); //not true anymore
|
||||
SettingButton.IsEnabled = false;
|
||||
IsVerification = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region clicks
|
||||
private void Start_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (SelfUpdater.CheckOneFileSignature("NaturalLauncher.exe") || !SelfUpdater.isSelfUpdating)
|
||||
{
|
||||
if (versionNumber != remoteVersionNumber || versionNumber == "0.0.0.0")
|
||||
{
|
||||
ReadyLauncherForUpdate("Start Update from play button");
|
||||
StartButton.Content = "Verifying...";
|
||||
IsVerification = false;
|
||||
UpdateGame(); //verify the game with the right click context menu
|
||||
}
|
||||
else
|
||||
{
|
||||
Launcher.PlayGame();
|
||||
Util.PlaySoundFX("finish");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PlaySoundFX("error");
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Your launcher is corrupted or out of date, please relaunch" + Environment.NewLine
|
||||
+ "if the problem persist, please redownload the launcher from an official source (ensl.org)");
|
||||
File.Delete(Launcher.curDir + Path.DirectorySeparatorChar + "launcher.version");
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void Website_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Launcher.LaunchWebsite(Properties.Settings.Default.GatherURL);
|
||||
}
|
||||
|
||||
private void Setting_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sw == null)
|
||||
{
|
||||
sw = new Settings();
|
||||
}
|
||||
sw.SetMainWindowRef(this);
|
||||
sw.Show();
|
||||
}
|
||||
|
||||
private void Verify_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReadyLauncherForUpdate("Verification started from launcher");
|
||||
|
||||
if (versionNumber != remoteVersionNumber || versionNumber == "0.0.0.0")
|
||||
{
|
||||
IsVerification = false;
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "but it's an update");
|
||||
}
|
||||
else
|
||||
{
|
||||
IsVerification = true;
|
||||
}
|
||||
|
||||
UpdateGame(); //verify the game with the right click context menu
|
||||
}
|
||||
|
||||
private void Pause_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var brush = new ImageBrush();
|
||||
try
|
||||
{
|
||||
if (!downloadCancelled)
|
||||
{
|
||||
downloadCancelled = true;
|
||||
backgroundWorker.CancelAsync();
|
||||
|
||||
Uri resourceUri = new Uri("Ressources/playimage.png", UriKind.Relative); //"pack://application:,,,/NaturalLauncher;component/Images/Resource_Image.png"
|
||||
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
|
||||
|
||||
BitmapFrame temp = BitmapFrame.Create(streamInfo.Stream);
|
||||
brush.ImageSource = temp;
|
||||
|
||||
PauseButton.Background = brush;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadyLauncherForUpdate("Verification resumed from launcher");
|
||||
UpdateGame(); //verify the game with the right click context menu
|
||||
|
||||
Uri resourceUri = new Uri("Ressources/pauseimage.png", UriKind.Relative);
|
||||
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
|
||||
|
||||
BitmapFrame temp = BitmapFrame.Create(streamInfo.Stream);
|
||||
brush.ImageSource = temp;
|
||||
|
||||
PauseButton.Background = brush;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
downloadCancelled = false;
|
||||
Uri resourceUri = new Uri("Ressources/pauseimage.png", UriKind.Relative);
|
||||
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
|
||||
|
||||
BitmapFrame temp = BitmapFrame.Create(streamInfo.Stream);
|
||||
brush.ImageSource = temp;
|
||||
|
||||
PauseButton.Background = brush;
|
||||
} //I don't give a f if it doesnt catch shit
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ContextMenu
|
||||
private void BuildManifest(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManifestBuilder.BuildManifest(Launcher.NSFolder); // build the manifest of the file to update
|
||||
}
|
||||
private void VerifyTheGame(object sender, RoutedEventArgs e)
|
||||
{
|
||||
/*UpdateLog = new StreamWriter(LogReportPath + Path.DirectorySeparatorChar + "UpdateLog_" + Util.GetLongTimeString() + ".txt", true); // dt forget to close()
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Verification started from context menu");
|
||||
UpdateGame(); //verify the game with the right click context menu*/ //not used anymore
|
||||
}
|
||||
private void CheckLauncherUpdate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SelfUpdater TheSelfUpdater = new SelfUpdater();
|
||||
TheSelfUpdater.allowMessage = true;
|
||||
TheSelfUpdater.UpdateLauncher();
|
||||
}
|
||||
private void JoinDiscord(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("https://discord.gg/ZUSSBUA");
|
||||
}
|
||||
private void SeeCredit(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("https://discord.gg/ZUSSBUA");
|
||||
}
|
||||
private void JoinPublicServer(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("steam://connect/104.156.251.121:27015");
|
||||
}
|
||||
private void AddToIgnore(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Launcher.AddToIgnoreList();
|
||||
}
|
||||
|
||||
private void OpenNSFolder(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start(Launcher.NSFolder);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateMaelAlgo
|
||||
|
||||
public void UpdateGame()
|
||||
{
|
||||
Util.PlaySoundFX("start");
|
||||
TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
|
||||
downloadCancelled = false;
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
backgroundWorker.WorkerReportsProgress = true;
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.DoWork += UpdateGame_Worker;
|
||||
backgroundWorker.ProgressChanged += UpdateGame_ProgressChanged;
|
||||
backgroundWorker.RunWorkerCompleted += UpdateGame_RunWorkerCompleted;
|
||||
backgroundWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
|
||||
public void CallUpdateGame() //same as updategame for now
|
||||
{
|
||||
ReadyLauncherForUpdate("update Called from a setting's change");
|
||||
UpdateGame();
|
||||
}
|
||||
|
||||
|
||||
public void UpdateGame_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Cancelled)
|
||||
{
|
||||
StartButton.Content = "Error";
|
||||
UpdateProgressBar.Value = 0;
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Error while downloading, please try again");
|
||||
ProgressLabel.Content = "Error while downloading, please try again";
|
||||
TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadCancelled)
|
||||
{
|
||||
ProgressLabel.Content = "Paused !";
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Stop requested by the user...");
|
||||
TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Paused; //yellow thing
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressLabel.Content = "Up to date !";
|
||||
StartButton.Content = "Play";
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Completed the update or verify work");
|
||||
TaskbarItemInfo.ProgressValue = 0;
|
||||
TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
|
||||
Util.CreateLocalVersionFile(Launcher.curDir, Launcher.VersionFileName, remoteVersionNumber); //update the version with the new one
|
||||
|
||||
Check_Version(); // we should have a changed app.version file to check
|
||||
}
|
||||
|
||||
UpdateLog.Close();
|
||||
backgroundWorker.Dispose();
|
||||
|
||||
Util.PlaySoundFX("finish");
|
||||
|
||||
StartButton.IsEnabled = true;
|
||||
SettingButton.IsEnabled = true;
|
||||
VerifyButton.IsEnabled = true;
|
||||
}
|
||||
|
||||
public void UpdateGame_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||
{
|
||||
ProgressLabel.Content = e.UserState as string;
|
||||
UpdateProgressBar.Value = e.ProgressPercentage;
|
||||
TaskbarItemInfo.ProgressValue = (double)((float)e.ProgressPercentage / 100f);
|
||||
}
|
||||
|
||||
public void UpdateGame_Worker(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
backgroundWorker.ReportProgress(0, "Downloading Manifest...");
|
||||
|
||||
string ManifestURL = Launcher.MainPageURL.AbsoluteUri + Launcher.ManifestName;
|
||||
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
|
||||
webClient.DownloadProgressChanged += webClient_DownloadProgressChanged;
|
||||
webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
|
||||
|
||||
string manifest = webClient.DownloadString(ManifestURL);
|
||||
LauncherManifest RemoteManifest = JsonConvert.DeserializeObject<LauncherManifest>(manifest);
|
||||
|
||||
if (Launcher.IsNLPack())
|
||||
{
|
||||
string NLManifestURL = Launcher.MainPageURL.AbsoluteUri + Launcher.NLManifestName;
|
||||
string NLmanifest = webClient.DownloadString(NLManifestURL);
|
||||
LauncherManifest NLManifest = JsonConvert.DeserializeObject<LauncherManifest>(NLmanifest);
|
||||
|
||||
RemoteManifest = Util.CleanManifestWithOptions(RemoteManifest, NLManifest); //cleaning the manifest hash consequently
|
||||
}
|
||||
|
||||
LauncherManifest IgnoreManifest = Util.GetIgnoreManifest(IsVerification); //attention, might not exist, if so it has to be downloaded, if not let's use it !
|
||||
|
||||
string gameInstallDir = Launcher.NSFolder;
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Install Directory located in : " + gameInstallDir);
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "NL Pack installed : " + Launcher.IsNLPack().ToString());
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Distant Manifest located at : " + ManifestURL);
|
||||
|
||||
var md5 = MD5.Create();
|
||||
int totalFiles = RemoteManifest.Files.Count;
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Total file to update : " + totalFiles);
|
||||
|
||||
int curFile = 0;
|
||||
|
||||
// Update the standard files
|
||||
foreach (KeyValuePair<string, string> kv in RemoteManifest.Files)
|
||||
{
|
||||
bool ShouldDownload = false;
|
||||
string gameFilePath = gameInstallDir + kv.Key.Replace("/", Path.DirectorySeparatorChar.ToString());
|
||||
IgnoreManifest.Files.TryGetValue(kv.Key, out string IgnoreValue); //get the ignore file value in manifest ("0" ignore only verif, "1" ignore verif + update)
|
||||
|
||||
bool Condition1 = File.Exists(gameFilePath) && IgnoreManifest.Files.ContainsKey(kv.Key) == false;//if the file exists and not in the ignore manifest, let's have it !
|
||||
bool Condition2 = File.Exists(gameFilePath) && IgnoreManifest.Files.ContainsKey(kv.Key) && IgnoreValue == "0" && !IsVerification; //if the file exists, is in the ignore manifest, but is updatable and... it's update time !
|
||||
|
||||
if (Condition1 || Condition2)
|
||||
{
|
||||
int progress = (int)(((float)curFile / (float)totalFiles) * 100);
|
||||
backgroundWorker.ReportProgress(progress, "(" + (curFile) + " / " + totalFiles + ") Checking " + kv.Key);
|
||||
|
||||
//Check its md5 hash
|
||||
using (var stream = File.OpenRead(gameFilePath))
|
||||
{
|
||||
var hash = Util.ComputeMD5(gameFilePath);
|
||||
|
||||
if (hash != kv.Value)
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " needs to be updated");
|
||||
ShouldDownload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!File.Exists(gameFilePath))
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " not existing, needs downloading");
|
||||
ShouldDownload = true;
|
||||
}
|
||||
if (File.Exists(gameFilePath) && IgnoreManifest.Files.ContainsKey(kv.Key) && IgnoreValue == "1") // ignore everything
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " Is Ignored for update, not checking");
|
||||
ShouldDownload = false;
|
||||
}
|
||||
if (File.Exists(gameFilePath) && IgnoreManifest.Files.ContainsKey(kv.Key) && IsVerification && IgnoreValue == "0") //if we need to ignore update and it's verification, we ignore !
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " Is Ignored for verifications, not checking");
|
||||
ShouldDownload = false;
|
||||
}
|
||||
|
||||
|
||||
if (ShouldDownload)
|
||||
{
|
||||
DownloadFile(curFile, totalFiles, kv, RemoteManifest, gameFilePath, Properties.Settings.Default.GameUrl, webClient);
|
||||
|
||||
var hash = Util.ComputeMD5(gameFilePath);
|
||||
|
||||
if (hash != kv.Value)
|
||||
{
|
||||
//MessageBox.Show("Failed Validating " + kv.Key + " : Redownloading"); //problem with double validation, is it too soon in the chain of event ?
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "failed to verify newly downloaded file, redownloading");
|
||||
DownloadFile(curFile, totalFiles, kv, RemoteManifest, gameFilePath, Properties.Settings.Default.GameUrl, webClient);
|
||||
}
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Download complete for file: " + kv.Key + " with new hash :" + hash + " for manifest hash : " + kv.Value);
|
||||
}
|
||||
if (backgroundWorker.CancellationPending)
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Update cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
curFile++;
|
||||
}
|
||||
|
||||
// Update the NineLegend pack files if requiered
|
||||
/*if (Launcher.IsNLPack())
|
||||
{
|
||||
string NLManifestURL = Launcher.MainPageURL.AbsoluteUri + Launcher.NLManifestName;
|
||||
string NLmanifest = webClient.DownloadString(NLManifestURL);
|
||||
LauncherManifest NLManifest = JsonConvert.DeserializeObject<LauncherManifest>(NLmanifest);
|
||||
curFile = curFile - NLManifest.Files.Count;
|
||||
|
||||
foreach (KeyValuePair<string, string> kv in NLManifest.Files)
|
||||
{
|
||||
bool ShouldDownload = false;
|
||||
string gameFilePath = gameInstallDir + kv.Key.Replace("/", Path.DirectorySeparatorChar.ToString());
|
||||
if (File.Exists(gameFilePath))
|
||||
{
|
||||
int progress = (int)(((float)curFile / (float)totalFiles) * 100);
|
||||
backgroundWorker.ReportProgress(progress, "(" + (curFile) + " / " + totalFiles + ") Checking " + kv.Key);
|
||||
//Check its md5 hash
|
||||
using (var stream = File.OpenRead(gameFilePath))
|
||||
{
|
||||
var hash = Util.ComputeMD5(gameFilePath);
|
||||
|
||||
if (hash != kv.Value)
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " needs to be updated");
|
||||
ShouldDownload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + gameFilePath + " not existing, needs downloading");
|
||||
ShouldDownload = true;
|
||||
}
|
||||
|
||||
if (ShouldDownload)
|
||||
{
|
||||
DownloadFile(curFile, totalFiles, kv, NLManifest, gameFilePath, Properties.Settings.Default.NineLegendUrl, webClient);
|
||||
|
||||
var hash = Util.ComputeMD5(gameFilePath);
|
||||
|
||||
if (hash != kv.Value)
|
||||
{
|
||||
//MessageBox.Show("Failed Validating " + kv.Key + " : Redownloading"); //problem with double validation, is it too soon in the chain of event ?
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "failed to verify newly downloaded file, redownloading");
|
||||
DownloadFile(curFile, totalFiles, kv, NLManifest, gameFilePath, Properties.Settings.Default.NineLegendUrl, webClient);
|
||||
}
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Download complete for NineLegend file: " + kv.Key + " with new hash :" + hash + " for manifest hash : " + kv.Value);
|
||||
}
|
||||
if (backgroundWorker.CancellationPending)
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Update cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
curFile++;
|
||||
}
|
||||
}*/
|
||||
|
||||
backgroundWorker.ReportProgress(100, "Writing Local Manifest");
|
||||
|
||||
/* string manifestDirectory = Launcher.curDir + Path.DirectorySeparatorChar + Launcher.ManifestName;
|
||||
|
||||
File.WriteAllText(manifestDirectory, manifest); // replace all with function in util */
|
||||
}
|
||||
|
||||
private void DownloadFile(int curFile, int totalFiles, KeyValuePair<string, string> kv, LauncherManifest RemoteManifest, string gameFilePath, string folderURL, WebClient webClient)
|
||||
{
|
||||
int progress = (int)(((float)curFile / (float)totalFiles) * 100);
|
||||
|
||||
string status = "(" + (curFile) + " / " + totalFiles + ") Downloading: " + kv.Key;
|
||||
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Downloading file: " + kv.Key);
|
||||
|
||||
backgroundWorker.ReportProgress(progress, status);
|
||||
|
||||
string remoteFile = (folderURL + "/" + kv.Key.Substring(1));
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(gameFilePath));
|
||||
if (File.Exists(gameFilePath))
|
||||
{
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "File exist, deleting old file");
|
||||
File.Delete(gameFilePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
webClient.DownloadFileAsync(new Uri(remoteFile), gameFilePath, status);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("new file not found");
|
||||
UpdateLog.WriteLine(Util.GetShortTimeString() + "Failed Downloading file: " + kv.Key + "with message : " + e.Message);
|
||||
backgroundWorker.CancelAsync();
|
||||
}
|
||||
|
||||
while (webClient.IsBusy)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
string status = e.UserState as string + " ( " + Util.Size(e.BytesReceived) + " / " + Util.Size(e.TotalBytesToReceive) + " )";
|
||||
backgroundWorker.ReportProgress(e.ProgressPercentage, status);
|
||||
}
|
||||
|
||||
void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
System.Windows.MessageBox.Show(e.Error.ToString());
|
||||
backgroundWorker.CancelAsync();
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
74
NaturalLauncher/ManifestBuilder.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class ManifestBuilder
|
||||
{
|
||||
|
||||
private static MD5 md5;
|
||||
|
||||
public static void BuildManifest(string directory)
|
||||
{
|
||||
LauncherManifest manifest = new LauncherManifest();
|
||||
|
||||
md5 = MD5.Create();
|
||||
|
||||
RecursiveBuildManifest(directory, "", manifest);
|
||||
|
||||
/*SaveFileDialog dialog = new SaveFileDialog(); // commented but needed when you want to save a manifest somewhere else (could be usefull for a manifest builder console app
|
||||
dialog.InitialDirectory = Environment.CurrentDirectory;
|
||||
dialog.FileName = "Manifest.txt";
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
File.WriteAllText(dialog.FileName, JsonConvert.SerializeObject(manifest, Formatting.Indented));
|
||||
}*/
|
||||
|
||||
string ManifestPath = Launcher.curDir + Path.DirectorySeparatorChar + Launcher.ManifestName;
|
||||
File.WriteAllText(ManifestPath, JsonConvert.SerializeObject(manifest, Formatting.Indented));
|
||||
}
|
||||
|
||||
private static void RecursiveBuildManifest(string projectRoot, string dir, LauncherManifest manifest)
|
||||
{
|
||||
string path = projectRoot + dir;
|
||||
|
||||
foreach (string file in Directory.GetFiles(path))
|
||||
{
|
||||
string localPath = Util.ToLocalPath(projectRoot, file);
|
||||
string hash = Util.ComputeMD5(file);
|
||||
|
||||
if (!localPath.EndsWith("_.cfg") && localPath != "/Manifest.txt" && localPath != "/ManifestBuilder.exe"
|
||||
&& localPath != "/Newtonsoft.Json.dll") //we don't want cfg files to get updated here cept config.cfg which is in ignore.list
|
||||
manifest.Files[localPath] = hash;
|
||||
}
|
||||
|
||||
foreach (string nextDir in Directory.GetDirectories(path))
|
||||
{
|
||||
RecursiveBuildManifest(projectRoot, Util.ToLocalPath(projectRoot, nextDir), manifest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
211
NaturalLauncher/NaturalLauncher.csproj
Normal file
|
@ -0,0 +1,211 @@
|
|||
<?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>{0138DD06-7386-4820-9BCE-3F8412CAD801}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>NaturalLauncher</RootNamespace>
|
||||
<AssemblyName>NaturalLauncher</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>true</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>true</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<TargetCulture>en</TargetCulture>
|
||||
<ProductName>Natural Launcher</ProductName>
|
||||
<PublisherName>Mael Vignaux</PublisherName>
|
||||
<MinimumRequiredVersion>1.0.0.0</MinimumRequiredVersion>
|
||||
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
|
||||
<AutorunEnabled>true</AutorunEnabled>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</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>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Ressources\nsl_icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestCertificateThumbprint>D8B30162E74CFDDB757978150D09F39672490FAC</ManifestCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestKeyFile>NaturalLauncher_TemporaryKey.pfx</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>true</SignManifests>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DiscordRPC, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\DiscordRPC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.8.5.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.8.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="ConsoleManager.cs" />
|
||||
<Compile Include="LauncherManifest.cs" />
|
||||
<Compile Include="ManifestBuilder.cs" />
|
||||
<Compile Include="ProjectSettings.cs" />
|
||||
<Compile Include="SelfUpdater.cs" />
|
||||
<Compile Include="ServerChecker.cs" />
|
||||
<Compile Include="Settings.xaml.cs">
|
||||
<DependentUpon>Settings.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Util.cs" />
|
||||
<Compile Include="XmlBuilder.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Launcher.cs" />
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="Settings.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="NaturalLauncher_TemporaryKey.pfx" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Resource Include="Ressources\Commande.lex" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\background.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\small_discordicon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\nsl_icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="nsl_icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\background_blur.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6.2">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.6.2 %28x86 et 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>
|
||||
<Resource Include="Ressources\pauseimage.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\playimage.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\sdx_error.wav" />
|
||||
<Resource Include="Ressources\sdx_finished.wav" />
|
||||
<Resource Include="Ressources\sdx_started.wav" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Ressources\steam_icon.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
37
NaturalLauncher/NaturalLauncher.sln
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27703.2042
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NaturalLauncher", "NaturalLauncher\NaturalLauncher.csproj", "{0138DD06-7386-4820-9BCE-3F8412CAD801}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManifestBuilder", "ManifestBuilder\ManifestBuilder.csproj", "{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanAndLaunch", "CleanAndLaunch\CleanAndLaunch.csproj", "{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0138DD06-7386-4820-9BCE-3F8412CAD801}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6A7DBE40-6BFB-49F5-BFC1-9F0752EC31BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8E7856FD-FA68-4356-9C88-54C9EF5A9D20}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06E5B626-B631-47BF-84D5-A157442007E0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
30
NaturalLauncher/ProjectSettings.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
|
||||
namespace ArtefactsLauncher
|
||||
{
|
||||
public class ProjectSettings
|
||||
{
|
||||
// Attention, it is very important to keep the exact same names as in the json
|
||||
public float ScreenPercentage;
|
||||
public float BeeFactor;
|
||||
}
|
||||
}
|
53
NaturalLauncher/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// Les informations générales relatives à un assembly dépendent de
|
||||
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
|
||||
// associées à un assembly.
|
||||
[assembly: AssemblyTitle("NaturalLauncher")]
|
||||
[assembly: AssemblyDescription("The launcher and updater for natural selection 1")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Mael Vignaux")]
|
||||
[assembly: AssemblyProduct("NaturalLauncher")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
|
||||
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
|
||||
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//Pour commencer à générer des applications localisables, définissez
|
||||
//<UICulture>CultureUtiliséePourCoder</UICulture> dans votre fichier .csproj
|
||||
//dans <PropertyGroup>. Par exemple, si vous utilisez le français
|
||||
//dans vos fichiers sources, définissez <UICulture> à fr-FR. Puis, supprimez les marques de commentaire de
|
||||
//l'attribut NeutralResourceLanguage ci-dessous. Mettez à jour "fr-FR" dans
|
||||
//la ligne ci-après pour qu'elle corresponde au paramètre UICulture du fichier projet.
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //où se trouvent les dictionnaires de ressources spécifiques à un thème
|
||||
//(utilisé si une ressource est introuvable dans la page,
|
||||
// ou dictionnaires de ressources de l'application)
|
||||
ResourceDictionaryLocation.SourceAssembly //où se trouve le dictionnaire de ressources générique
|
||||
//(utilisé si une ressource est introuvable dans la page,
|
||||
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)
|
||||
)]
|
||||
|
||||
|
||||
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
|
||||
//
|
||||
// Version principale
|
||||
// Version secondaire
|
||||
// Numéro de build
|
||||
// Révision
|
||||
//
|
||||
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
|
||||
// en utilisant '*', comme indiqué ci-dessous :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
63
NaturalLauncher/Properties/Resources.Designer.cs
generated
Normal file
|
@ -0,0 +1,63 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Ce code a été généré par un outil.
|
||||
// Version du runtime :4.0.30319.42000
|
||||
//
|
||||
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
|
||||
// le code est régénéré.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace NaturalLauncher.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
|
||||
/// </summary>
|
||||
// Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
|
||||
// à l'aide d'un outil, tel que ResGen ou Visual Studio.
|
||||
// Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
|
||||
// avec l'option /str ou régénérez votre projet VS.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NaturalLauncher.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remplace la propriété CurrentUICulture du thread actuel pour toutes
|
||||
/// les recherches de ressources à l'aide de cette classe de ressource fortement typée.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
NaturalLauncher/Properties/Resources.resx
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?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.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: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" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
110
NaturalLauncher/Properties/Settings.Designer.cs
generated
Normal file
|
@ -0,0 +1,110 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Ce code a été généré par un outil.
|
||||
// Version du runtime :4.0.30319.42000
|
||||
//
|
||||
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
|
||||
// le code est régénéré.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace NaturalLauncher.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://ensl.gk-servers.de/")]
|
||||
public string ConfigurationUrl {
|
||||
get {
|
||||
return ((string)(this["ConfigurationUrl"]));
|
||||
}
|
||||
set {
|
||||
this["ConfigurationUrl"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://ensl.gk-servers.de/")]
|
||||
public string IndexURL {
|
||||
get {
|
||||
return ((string)(this["IndexURL"]));
|
||||
}
|
||||
set {
|
||||
this["IndexURL"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://ensl.gk-servers.de/")]
|
||||
public string CreditURL {
|
||||
get {
|
||||
return ((string)(this["CreditURL"]));
|
||||
}
|
||||
set {
|
||||
this["CreditURL"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://ensl.gk-servers.de/ns")]
|
||||
public string GameUrl {
|
||||
get {
|
||||
return ((string)(this["GameUrl"]));
|
||||
}
|
||||
set {
|
||||
this["GameUrl"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://www.ensl.org/gathers/latest/ns1")]
|
||||
public string GatherURL {
|
||||
get {
|
||||
return ((string)(this["GatherURL"]));
|
||||
}
|
||||
set {
|
||||
this["GatherURL"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.elseware-experience.com/vignauxmael/NaturalLauncher/NLPack")]
|
||||
public string NineLegendUrl {
|
||||
get {
|
||||
return ((string)(this["NineLegendUrl"]));
|
||||
}
|
||||
set {
|
||||
this["NineLegendUrl"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://ensl.gk-servers.de/Launcher/")]
|
||||
public string LauncherUrl {
|
||||
get {
|
||||
return ((string)(this["LauncherUrl"]));
|
||||
}
|
||||
set {
|
||||
this["LauncherUrl"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
NaturalLauncher/Properties/Settings.settings
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="NaturalLauncher.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="ConfigurationUrl" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://ensl.gk-servers.de/</Value>
|
||||
</Setting>
|
||||
<Setting Name="IndexURL" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://ensl.gk-servers.de/</Value>
|
||||
</Setting>
|
||||
<Setting Name="CreditURL" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://ensl.gk-servers.de/</Value>
|
||||
</Setting>
|
||||
<Setting Name="GameUrl" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://ensl.gk-servers.de/ns</Value>
|
||||
</Setting>
|
||||
<Setting Name="GatherURL" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">https://www.ensl.org/gathers/latest/ns1</Value>
|
||||
</Setting>
|
||||
<Setting Name="NineLegendUrl" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://www.elseware-experience.com/vignauxmael/NaturalLauncher/NLPack</Value>
|
||||
</Setting>
|
||||
<Setting Name="LauncherUrl" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">http://ensl.gk-servers.de/Launcher/</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
144
NaturalLauncher/Ressources/Commande.lex
Normal file
|
@ -0,0 +1,144 @@
|
|||
parameter
|
||||
value
|
||||
_snd_mixahead
|
||||
ati_npatch
|
||||
bgmvolume
|
||||
bottomcolor
|
||||
brightness
|
||||
cl_allowdownload
|
||||
cl_allowupload
|
||||
cl_autohelp
|
||||
cl_backspeed
|
||||
cl_buildmessages
|
||||
cl_centerentityid
|
||||
cl_cmdbackup
|
||||
cl_cmdrate
|
||||
cl_cmhotkeys
|
||||
cl_cross
|
||||
cl_cross_alpha
|
||||
cl_cross_bottom_line
|
||||
cl_cross_color
|
||||
cl_cross_dot_color
|
||||
cl_cross_dot_outline
|
||||
cl_cross_dot_size
|
||||
cl_cross_gap
|
||||
cl_cross_left_line
|
||||
cl_cross_outline
|
||||
cl_cross_outline_inner
|
||||
cl_cross_right_line
|
||||
cl_cross_size
|
||||
cl_cross_thickness
|
||||
cl_cross_top_line
|
||||
cl_customcrosshair
|
||||
cl_dlmax
|
||||
cl_download_ingame
|
||||
cl_dynamiclights
|
||||
cl_forcedefaultfov
|
||||
cl_forwardspeed
|
||||
cl_gammaramp
|
||||
cl_highdetail
|
||||
cl_himodels
|
||||
cl_hudmapzoom
|
||||
cl_iconb
|
||||
cl_icong
|
||||
cl_iconr
|
||||
cl_idealpitchscale
|
||||
cl_labelhivesight
|
||||
cl_labelmaps
|
||||
cl_lc
|
||||
cl_logocolor
|
||||
cl_logofile
|
||||
cl_lw
|
||||
cl_mousegrab
|
||||
cl_musicdelay
|
||||
cl_musicdirectory
|
||||
cl_musicenabled
|
||||
cl_musicvolume
|
||||
cl_particleinfo
|
||||
cl_quickselecttime
|
||||
cl_timeout
|
||||
cl_updaterate
|
||||
cl_vsmoothing
|
||||
cl_widescreen
|
||||
con_color
|
||||
con_mono
|
||||
console
|
||||
crosshair
|
||||
fps_max
|
||||
gamma
|
||||
gl_dither
|
||||
gl_flipmatrix
|
||||
gl_fog
|
||||
gl_monolights
|
||||
gl_overbright
|
||||
gl_polyoffset
|
||||
gl_vsync
|
||||
hisound
|
||||
hpk_maxsize
|
||||
hud_capturemouse
|
||||
hud_centerid
|
||||
hud_classautokill
|
||||
hud_draw
|
||||
hud_fastswitch
|
||||
hud_takesshots
|
||||
joystick
|
||||
lookspring
|
||||
lookstrafe
|
||||
m_customaccel
|
||||
m_customaccel_exponent
|
||||
m_customaccel_max
|
||||
m_customaccel_scale
|
||||
m_filter
|
||||
m_forward
|
||||
m_mousethread_sleep
|
||||
m_pitch
|
||||
m_rawinput
|
||||
m_side
|
||||
m_yaw
|
||||
model
|
||||
MP3FadeTime
|
||||
MP3Volume
|
||||
mp_decals
|
||||
name
|
||||
net_graph
|
||||
net_scale
|
||||
r_detailtextures
|
||||
sensitivity
|
||||
skin
|
||||
suitvolume
|
||||
sv_aim
|
||||
sv_voiceenable
|
||||
team
|
||||
topcolor
|
||||
viewsize
|
||||
voice_enable
|
||||
voice_forcemicrecord
|
||||
voice_modenable
|
||||
voice_scale
|
||||
volume
|
||||
sv_cheats
|
||||
hud_style
|
||||
cl_cmdrate
|
||||
cl_updaterate
|
||||
ex_extrapmax
|
||||
cl_cmdbackup
|
||||
rate
|
||||
ex_interp
|
||||
gl_wateramp
|
||||
gl_zmax
|
||||
gl_ztrick
|
||||
r_drawviewmodel
|
||||
r_mmx
|
||||
r_dynamic
|
||||
r_decals
|
||||
r_mirroralpha
|
||||
r_bmodelhighfrac
|
||||
violence_ablood
|
||||
violence_agibs
|
||||
violence_hblood
|
||||
violence_hgibs
|
||||
cl_labelmaps
|
||||
senslock
|
||||
cl_ambientsound
|
||||
cl_widescreen
|
||||
sv_jumpmode
|
BIN
NaturalLauncher/Ressources/background.png
Normal file
After Width: | Height: | Size: 2 MiB |
BIN
NaturalLauncher/Ressources/background_blur.png
Normal file
After Width: | Height: | Size: 926 KiB |
BIN
NaturalLauncher/Ressources/nsl_icon.ico
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
NaturalLauncher/Ressources/pauseimage.png
Normal file
After Width: | Height: | Size: 890 B |
BIN
NaturalLauncher/Ressources/playimage.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
NaturalLauncher/Ressources/sdx_error.wav
Normal file
BIN
NaturalLauncher/Ressources/sdx_finished.wav
Normal file
BIN
NaturalLauncher/Ressources/sdx_started.wav
Normal file
BIN
NaturalLauncher/Ressources/small_discordicon.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
NaturalLauncher/Ressources/steam_icon.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
325
NaturalLauncher/SelfUpdater.cs
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class SelfUpdater
|
||||
{
|
||||
public static bool isSelfUpdating = true;
|
||||
|
||||
public static string LaucherLocalVNumber;
|
||||
public static string LaucherRemoteVNumber;
|
||||
public static string curDir = Directory.GetCurrentDirectory();
|
||||
|
||||
public static MainWindow MainWindowReference;
|
||||
|
||||
public static string LauncherFolderURL = Properties.Settings.Default.LauncherUrl;
|
||||
public static string VersionFileName = "launcher.version";
|
||||
public static string PublicKeyPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "NslKey.cer";
|
||||
public static string manifestUrl = Properties.Settings.Default.IndexURL + "CryptoManifest.txt";
|
||||
|
||||
public static LauncherManifest CryptoManifest = new LauncherManifest();
|
||||
|
||||
public static int NumberOfFiles = 0;
|
||||
|
||||
public bool allowMessage=false;
|
||||
|
||||
public BackgroundWorker backgroundWorker;
|
||||
|
||||
public void SetMainWindowRef(MainWindow MainWindowRef)
|
||||
{
|
||||
MainWindowReference = MainWindowRef;
|
||||
}
|
||||
|
||||
public void UpdateLauncher()
|
||||
{
|
||||
if(isSelfUpdating)
|
||||
{
|
||||
CheckUpdaterVersion();
|
||||
|
||||
DeleteOldFiles(); //delete all the updatelog and .bak files
|
||||
|
||||
if (LaucherLocalVNumber != LaucherRemoteVNumber)
|
||||
{
|
||||
UpdateCryptoManifest();
|
||||
|
||||
// Move the files in the launcher directory to a name with .bak
|
||||
MoveLauncherFiles(); //Attention, non recursive !!!
|
||||
|
||||
// falsify all the buttons
|
||||
MainWindowReference.StartButton.IsEnabled = false;
|
||||
MainWindowReference.VerifyButton.IsEnabled = false;
|
||||
MainWindowReference.SettingButton.IsEnabled = false;
|
||||
|
||||
// We gotta update the launcher !
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("The Launcher Will be self updating !" + Environment.NewLine + "It will restart itself once done..."); //not true anymore
|
||||
ConsoleManager.Show();
|
||||
|
||||
// background worker download the files and switch the launcher when over
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.DoWork += UpdateLauncher_Worker;
|
||||
backgroundWorker.RunWorkerCompleted += UpdateLauncher_RunWorkerCompleted;
|
||||
backgroundWorker.RunWorkerAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allowMessage) //inform the player we don't need update (only when using context menu so far)
|
||||
{
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("No Update Required !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void UpdateCryptoManifest()
|
||||
{
|
||||
using (WebClient webClient = new WebClient())
|
||||
{
|
||||
Console.WriteLine("Downloading the CryptoManifest");
|
||||
string dasManifest = webClient.DownloadString(new Uri(manifestUrl));
|
||||
CryptoManifest = JsonConvert.DeserializeObject<LauncherManifest>(dasManifest);
|
||||
NumberOfFiles = CryptoManifest.Files.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckUpdaterVersion()
|
||||
{
|
||||
LaucherLocalVNumber = Util.LocalVersion(curDir + Path.DirectorySeparatorChar + VersionFileName);
|
||||
Console.WriteLine("Checking launcher's Version ...");
|
||||
Console.WriteLine("Local Version of the updater is :" + LaucherLocalVNumber);
|
||||
if (LaucherLocalVNumber != null)
|
||||
{
|
||||
LaucherRemoteVNumber = Util.RemoteVersion(Launcher.MainPageURL + VersionFileName);
|
||||
Console.WriteLine("Got the remote version with success :" + LaucherRemoteVNumber);
|
||||
}
|
||||
else //if it doesn exist, we need to inform the user
|
||||
{
|
||||
LaucherLocalVNumber = "0.0.0.0";
|
||||
Util.PlaySoundFX("error");
|
||||
LaucherRemoteVNumber = Util.RemoteVersion(Launcher.MainPageURL + VersionFileName);
|
||||
Console.WriteLine("Couldnt find remote version number");
|
||||
}
|
||||
}
|
||||
|
||||
public static void MoveLauncherFiles()
|
||||
{
|
||||
foreach (KeyValuePair<string, string> kv in CryptoManifest.Files)
|
||||
{
|
||||
string fullpath = curDir + Path.DirectorySeparatorChar + kv.Key.Remove(0,1);
|
||||
if (File.Exists(fullpath))
|
||||
{
|
||||
Console.WriteLine(fullpath + " : Changing to .bak extension ...");
|
||||
System.IO.File.Move(fullpath, fullpath + ".bak");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public static void AddNewFilesToChangeList()
|
||||
{
|
||||
// Check the new files
|
||||
List<string> NewFiles = Util.GetDirectoryFilesFromUrl(LauncherFolderURL);
|
||||
|
||||
// we add the new files into the changedlist
|
||||
foreach (string file in NewFiles)
|
||||
{
|
||||
if (!ChangedFiles.Contains(file))
|
||||
ChangedFiles.Add(file);
|
||||
}
|
||||
|
||||
NumberOfFiles = ChangedFiles.Count;
|
||||
}*/
|
||||
|
||||
public void UpdateLauncher_Worker(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
|
||||
webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
|
||||
|
||||
// Download the changed files
|
||||
foreach (KeyValuePair<string, string> kv in CryptoManifest.Files)
|
||||
{
|
||||
string smtg = kv.Key.Remove(0, 1);
|
||||
DownloadLauncherFiles(kv.Key.Remove(0,1), webClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UpdateLauncher_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (!backgroundWorker.IsBusy && NumberOfFiles<=0) //double check but somehow it executed twice oO
|
||||
{
|
||||
CheckSignatureAndLaunch();
|
||||
}
|
||||
}
|
||||
|
||||
public void DownloadLauncherFiles(string file, WebClient webClient)
|
||||
{
|
||||
Console.WriteLine(file + " : Downloading ...");
|
||||
webClient.DownloadFileAsync(new Uri(LauncherFolderURL+ file), curDir + Path.DirectorySeparatorChar + file);
|
||||
|
||||
while (webClient.IsBusy)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
System.Windows.MessageBox.Show(e.Error.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
NumberOfFiles--;
|
||||
Console.WriteLine("Downloaded !" + NumberOfFiles.ToString() + " more files to go !");
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteOldFiles()
|
||||
{
|
||||
Console.WriteLine("Cleaning old and update files ...");
|
||||
foreach (string file in Directory.GetFiles(curDir))
|
||||
{
|
||||
// Cleaning BAK files
|
||||
if(Path.GetExtension(file)==".bak")
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
string localPath = Util.ToLocalPath(curDir, file);
|
||||
|
||||
// Cleaning UpdateLogs files
|
||||
if (localPath.StartsWith("/UpdateLog"))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckSignatureAndLaunch()
|
||||
{
|
||||
Console.WriteLine("Starting signature check");
|
||||
foreach (KeyValuePair<string, string> kv in CryptoManifest.Files)
|
||||
{
|
||||
string FullPath = curDir + Path.DirectorySeparatorChar + kv.Key.Remove(0, 1);
|
||||
var stream = File.ReadAllBytes(FullPath);
|
||||
string signatureHexaString = "";
|
||||
CryptoManifest.Files.TryGetValue(kv.Key, out signatureHexaString);
|
||||
|
||||
if (!Verify(stream, PublicKeyPath, signatureHexaString))
|
||||
{
|
||||
Util.PlaySoundFX("error");
|
||||
System.Windows.MessageBox.Show(kv.Key + " unvalidated. Your version is corrupted, please redownload the launcher from a trusted source (ensl.org)");
|
||||
Console.WriteLine(kv.Key + " : UNVALIDATED and DELETED...");
|
||||
File.Delete(FullPath);
|
||||
Console.Read();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
else
|
||||
Console.WriteLine(kv.Key + " : validated ...");
|
||||
}
|
||||
|
||||
Task.Delay(10);
|
||||
Console.WriteLine("Refreshing version Number");
|
||||
Util.CreateLocalVersionFile(curDir, VersionFileName, LaucherRemoteVNumber);
|
||||
|
||||
Util.LaunchAgain(curDir + Path.DirectorySeparatorChar + "CleanAndLaunch.exe");
|
||||
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
public static bool Verify(byte[] data, string PublicKeyPath, string SignatureHexaString)
|
||||
{
|
||||
X509Certificate2 publicKey = LoadPublicKey(PublicKeyPath);
|
||||
byte[] signature = StringToByte(SignatureHexaString);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException("data");
|
||||
}
|
||||
|
||||
if (publicKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("publicKey");
|
||||
}
|
||||
|
||||
if (signature == null)
|
||||
{
|
||||
throw new ArgumentNullException("signature");
|
||||
}
|
||||
|
||||
var provider = (RSACryptoServiceProvider)publicKey.PublicKey.Key;
|
||||
|
||||
return provider.VerifyData(data, new SHA1CryptoServiceProvider(), signature);
|
||||
|
||||
}
|
||||
|
||||
public static X509Certificate2 LoadPublicKey(string PublicKeyPath)
|
||||
{
|
||||
return new X509Certificate2(PublicKeyPath);
|
||||
}
|
||||
|
||||
public static byte[] StringToByte(string str)
|
||||
{
|
||||
String[] arr = str.Split('-');
|
||||
byte[] array = new byte[arr.Length];
|
||||
for (int i = 0; i < arr.Length; i++) array[i] = Convert.ToByte(arr[i], 16);
|
||||
return array;
|
||||
}
|
||||
|
||||
public static bool CheckOneFileSignature(string fileName)
|
||||
{
|
||||
UpdateCryptoManifest(); //first let's update the crypto manifest with latest values
|
||||
|
||||
foreach (KeyValuePair<string, string> kv in CryptoManifest.Files)
|
||||
{
|
||||
if (kv.Key.Remove(0, 1) == fileName) // we found the filename in the manifest
|
||||
{
|
||||
string FullPath = curDir + Path.DirectorySeparatorChar + kv.Key.Remove(0, 1);
|
||||
var stream = File.ReadAllBytes(FullPath);
|
||||
string signatureHexaString = "";
|
||||
CryptoManifest.Files.TryGetValue(kv.Key, out signatureHexaString);
|
||||
return Verify(stream, PublicKeyPath, signatureHexaString);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
183
NaturalLauncher/ServerChecker.cs
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class ServerChecker
|
||||
{
|
||||
public class A2S_INFO
|
||||
{
|
||||
// \xFF\xFF\xFF\xFFTSource Engine Query\x00 because UTF-8 doesn't like to encode 0xFF
|
||||
public static readonly byte[] REQUEST = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00 };
|
||||
#region Strong Typing Enumerators
|
||||
[Flags]
|
||||
public enum ExtraDataFlags : byte
|
||||
{
|
||||
GameID = 0x01,
|
||||
SteamID = 0x10,
|
||||
Keywords = 0x20,
|
||||
Spectator = 0x40,
|
||||
Port = 0x80
|
||||
}
|
||||
public enum VACFlags : byte
|
||||
{
|
||||
Unsecured = 0,
|
||||
Secured = 1
|
||||
}
|
||||
public enum VisibilityFlags : byte
|
||||
{
|
||||
Public = 0,
|
||||
Private = 1
|
||||
}
|
||||
public enum EnvironmentFlags : byte
|
||||
{
|
||||
Linux = 0x6C, //l
|
||||
Windows = 0x77, //w
|
||||
Mac = 0x6D, //m
|
||||
MacOsX = 0x6F //o
|
||||
}
|
||||
public enum ServerTypeFlags : byte
|
||||
{
|
||||
Dedicated = 0x64, //d
|
||||
Nondedicated = 0x6C, //l
|
||||
SourceTV = 0x70 //p
|
||||
}
|
||||
#endregion
|
||||
public byte Header { get; set; } // I
|
||||
public byte Protocol { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Map { get; set; }
|
||||
public string Folder { get; set; }
|
||||
public string Game { get; set; }
|
||||
public short ID { get; set; }
|
||||
public byte Players { get; set; }
|
||||
public byte MaxPlayers { get; set; }
|
||||
public byte Bots { get; set; }
|
||||
public ServerTypeFlags ServerType { get; set; }
|
||||
public EnvironmentFlags Environment { get; set; }
|
||||
public VisibilityFlags Visibility { get; set; }
|
||||
public VACFlags VAC { get; set; }
|
||||
public string Version { get; set; }
|
||||
public ExtraDataFlags ExtraDataFlag { get; set; }
|
||||
#region Extra Data Flag Members
|
||||
public ulong GameID { get; set; } //0x01
|
||||
public ulong SteamID { get; set; } //0x10
|
||||
public string Keywords { get; set; } //0x20
|
||||
public string Spectator { get; set; } //0x40
|
||||
public short SpectatorPort { get; set; } //0x40
|
||||
public short Port { get; set; } //0x80
|
||||
#endregion
|
||||
|
||||
public A2S_INFO(IPEndPoint ep)
|
||||
{
|
||||
UdpClient udp = new UdpClient();
|
||||
udp.Send(REQUEST, REQUEST.Length, ep);
|
||||
MemoryStream ms = new MemoryStream(udp.Receive(ref ep)); // Saves the received data in a memory buffer
|
||||
BinaryReader br = new BinaryReader(ms, Encoding.UTF8); // A binary reader that treats charaters as Unicode 8-bit
|
||||
ms.Seek(4, SeekOrigin.Begin); // skip the 4 0xFFs
|
||||
Header = br.ReadByte();
|
||||
Protocol = br.ReadByte();
|
||||
Name = ReadNullTerminatedString(ref br);
|
||||
Map = ReadNullTerminatedString(ref br);
|
||||
Folder = ReadNullTerminatedString(ref br);
|
||||
Game = ReadNullTerminatedString(ref br);
|
||||
ID = br.ReadInt16();
|
||||
Players = br.ReadByte();
|
||||
MaxPlayers = br.ReadByte();
|
||||
Bots = br.ReadByte();
|
||||
ServerType = (ServerTypeFlags)br.ReadByte();
|
||||
Environment = (EnvironmentFlags)br.ReadByte();
|
||||
Visibility = (VisibilityFlags)br.ReadByte();
|
||||
VAC = (VACFlags)br.ReadByte();
|
||||
Version = ReadNullTerminatedString(ref br);
|
||||
ExtraDataFlag = (ExtraDataFlags)br.ReadByte();
|
||||
#region These EDF readers have to be in this order because that's the way they are reported
|
||||
if (ExtraDataFlag.HasFlag(ExtraDataFlags.Port))
|
||||
Port = br.ReadInt16();
|
||||
if (ExtraDataFlag.HasFlag(ExtraDataFlags.SteamID))
|
||||
SteamID = br.ReadUInt64();
|
||||
if (ExtraDataFlag.HasFlag(ExtraDataFlags.Spectator))
|
||||
{
|
||||
SpectatorPort = br.ReadInt16();
|
||||
Spectator = ReadNullTerminatedString(ref br);
|
||||
}
|
||||
if (ExtraDataFlag.HasFlag(ExtraDataFlags.Keywords))
|
||||
Keywords = ReadNullTerminatedString(ref br);
|
||||
if (ExtraDataFlag.HasFlag(ExtraDataFlags.GameID))
|
||||
GameID = br.ReadUInt64();
|
||||
#endregion
|
||||
br.Close();
|
||||
ms.Close();
|
||||
udp.Close();
|
||||
}
|
||||
/// <summary>Reads a null-terminated string into a .NET Framework compatible string.</summary>
|
||||
/// <param name="input">Binary reader to pull the null-terminated string from. Make sure it is correctly positioned in the stream before calling.</param>
|
||||
/// <returns>String of the same encoding as the input BinaryReader.</returns>
|
||||
public static string ReadNullTerminatedString(ref BinaryReader input)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char read = input.ReadChar();
|
||||
while (read != '\x00')
|
||||
{
|
||||
sb.Append(read);
|
||||
read = input.ReadChar();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
// Handles IPv4 and IPv6 notation.
|
||||
public static IPEndPoint CreateIPEndPoint(string endPoint)
|
||||
{
|
||||
string[] ep = endPoint.Split(':');
|
||||
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
|
||||
IPAddress ip;
|
||||
if (ep.Length > 2)
|
||||
{
|
||||
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
|
||||
{
|
||||
throw new FormatException("Invalid ip-adress");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IPAddress.TryParse(ep[0], out ip))
|
||||
{
|
||||
throw new FormatException("Invalid ip-adress");
|
||||
}
|
||||
}
|
||||
int port;
|
||||
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
|
||||
{
|
||||
throw new FormatException("Invalid port");
|
||||
}
|
||||
return new IPEndPoint(ip, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
43
NaturalLauncher/Settings.xaml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<Window x:Class="NaturalLauncher.Settings"
|
||||
Closed="Window_Closed"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:NaturalLauncher"
|
||||
mc:Ignorable="d"
|
||||
Title="Settings" Height="350" Width="587" Background="#FF0D0D0C" MinWidth="568" MinHeight="280" MaxWidth="587" MaxHeight="350">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="95*"/>
|
||||
<ColumnDefinition Width="97*"/>
|
||||
<ColumnDefinition Width="195"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Canvas Margin="10" Background="#FF1E1E1C" Grid.ColumnSpan="3">
|
||||
<Label Content="Options :" Canvas.Left="10" Canvas.Top="9" Height="27" Width="516" Foreground="#FFEEA160" FontWeight="Bold"/>
|
||||
<Label Content="Nine Legend Pack :" Canvas.Left="60" Canvas.Top="253" Height="27" Width="127" Foreground="#FF5ACAFF" FontWeight="Bold" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Label Content="Advanced UserConfig :" Canvas.Left="44" Canvas.Top="310" Height="27" Width="143" Foreground="#FF5ACAFF" FontWeight="Bold" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Label Content="Change HL Folder :" Canvas.Left="48" Canvas.Top="216" Height="27" Width="127" Foreground="#FF5ACAFF" FontWeight="Bold" HorizontalContentAlignment="Center"/>
|
||||
<Button x:Name="NLInstallButton" Content="Install" Canvas.Left="208" Canvas.Top="250" Width="133" Height="33" Click="NLInstallButton_Click" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Button x:Name="NLUnInstallButton" Content="Uninstall" Canvas.Left="367" Canvas.Top="250" Width="133" Height="33" Click="NLUnInstallButton_Click" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Button x:Name="AdvSettingsInstallButton" Content="Install" Canvas.Left="208" Canvas.Top="307" Width="133" Height="33" Click="AdvSettingsInstallButton_Click" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Button x:Name="AdvSettingsUnInstallButton" Content="Uninstall" Canvas.Left="367" Canvas.Top="307" Width="133" Height="33" Click="AdvSettingsUnInstallButton_Click" IsEnabled="False" Visibility="Collapsed"/>
|
||||
<Button x:Name="BrowseHLFolderButton" Content="Browse" Canvas.Left="252" Canvas.Top="215" Width="221" Height="33" Click="BrowseHLFolderButton_Click"/>
|
||||
<Label Content="Change cfg parameter :" Canvas.Left="38" Canvas.Top="82" Height="27" Width="147" Foreground="#FF5ACAFF" FontWeight="Bold" HorizontalContentAlignment="Center"/>
|
||||
<TextBox x:Name="ParamNameTxtbox" Height="27" Canvas.Left="212" TextWrapping="Wrap" Text="Parameter" Canvas.Top="83" Width="121" Foreground="#FF2B2F30" FontWeight="Bold" Background="#BFFFFFFF" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
<TextBox x:Name="ParamValueTxtbox" Height="27" Canvas.Left="392" TextWrapping="Wrap" Text="Value" Canvas.Top="83" Width="81" Foreground="#FF2B2F30" FontWeight="Bold" Background="#BFFFFFFF" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
<Button x:Name="FindParamButton" Content="Find" Canvas.Left="338" Canvas.Top="83" Width="49" Height="27" Background="#19000000" BorderBrush="#FF5ACAFF" Foreground="#FF5ACAFF" Click="FindParameter_Click"/>
|
||||
<Button x:Name="ChangeValueButton" Content="Change" Canvas.Left="479" Canvas.Top="83" Width="49" Height="27" Background="#19000000" BorderBrush="#FF5ACAFF" Foreground="#FF5ACAFF" Click="ChangeParameter_Click"/>
|
||||
<Label Content="HUD Syle :" Canvas.Left="59" Canvas.Top="39" Height="27" Width="105" Foreground="#FF5ACAFF" FontWeight="Bold" HorizontalContentAlignment="Center"/>
|
||||
<RadioButton x:Name="ClassicRadioButton" Content="Classic" Canvas.Left="240" Canvas.Top="45" Foreground="#FF5AFF5A" Checked="ClassicRadioButton_Checked"/>
|
||||
<RadioButton x:Name="MinimalRadioButton" Content="Minimal" Canvas.Left="326" Canvas.Top="45" Foreground="#FF5ACAFF" Checked="MinimalRadioButton_Checked"/>
|
||||
<RadioButton x:Name="NLRadioButton" Content="Nine Legend" Canvas.Left="417" Canvas.Top="45" Foreground="#FFFFA55A" Checked="NLRadioButton_Checked"/>
|
||||
<Label Content="Add files to ignore list :" Canvas.Left="39" Canvas.Top="172" Height="27" Width="145" Foreground="#FF5ACAFF" FontWeight="Bold" HorizontalContentAlignment="Center"/>
|
||||
<Button x:Name="BrowseHLFolderButton_Copy" Content="Add file(s)" Canvas.Left="252" Canvas.Top="169" Width="221" Height="33" Click="AddToIgnoreButton_Click"/>
|
||||
<CheckBox x:Name="KeepAliveChecker" Content="Keep Launcher alive when playing (and discord status)" Canvas.Left="108" Canvas.Top="266" FontWeight="Bold" Foreground="#FF5ACAFF" Width="343" HorizontalContentAlignment="Center" Click="StopAfterLaunch_Click"/>
|
||||
<Label Content="Custom discord status :" Canvas.Left="38" Canvas.Top="128" Height="27" Width="145" Foreground="#FF5ACAFF" FontWeight="Bold" HorizontalContentAlignment="Center"/>
|
||||
<TextBox x:Name="DiscordTxtbox" Height="27" Canvas.Left="212" TextWrapping="Wrap" Text="status" Canvas.Top="127" Width="261" Foreground="#FF2B2F30" FontWeight="Bold" Background="#BFFFFFFF" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
|
||||
<Button x:Name="ChangeDiscordButton" Content="Change" Canvas.Left="479" Canvas.Top="127" Width="49" Height="27" Background="#19000000" BorderBrush="#FF5ACAFF" Foreground="#FF5ACAFF" Click="ChangeDiscord_Click"/>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</Window>
|
259
NaturalLauncher/Settings.xaml.cs
Normal file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour Settings.xaml
|
||||
/// </summary>
|
||||
public partial class Settings : Window
|
||||
{
|
||||
|
||||
public static MainWindow MainWindowReference;
|
||||
public static bool windowfullyopen = false;
|
||||
|
||||
public Settings()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ParamNameTxtbox.SpellCheck.IsEnabled = true;
|
||||
ParamNameTxtbox.SpellCheck.CustomDictionaries.Add(new Uri("pack://application:,,,/Ressources/Commande.lex")); //add the command custom dictonary
|
||||
|
||||
//RefreshNLInstallButtonState(); //nl pack based
|
||||
|
||||
Util.GetAValueInCfg("hud_style",out string HUDStyleparam);
|
||||
switch(HUDStyleparam)
|
||||
{
|
||||
case "0":
|
||||
ClassicRadioButton.IsChecked = true;
|
||||
break;
|
||||
case "1":
|
||||
MinimalRadioButton.IsChecked = true;
|
||||
break;
|
||||
case "2":
|
||||
NLRadioButton.IsChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
XmlBuilder.ReadConfigXml(out string uno, out bool dos, out string discordStatus, out bool keepAlive);
|
||||
Launcher.keepLauncherAlive = keepAlive;
|
||||
DiscordTxtbox.Text = discordStatus;
|
||||
KeepAliveChecker.IsChecked = keepAlive;
|
||||
|
||||
windowfullyopen = true;
|
||||
|
||||
}
|
||||
|
||||
public void SetMainWindowRef(MainWindow MainWindowRef)
|
||||
{
|
||||
MainWindowReference = MainWindowRef;
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, EventArgs e)
|
||||
{
|
||||
MainWindow.sw = null;
|
||||
windowfullyopen = false;
|
||||
}
|
||||
|
||||
private void FindParameter_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Util.GetAValueInCfg(ParamNameTxtbox.Text,out string ParamValue);
|
||||
ParamValueTxtbox.Text = ParamValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
ParamValueTxtbox.Text = "not found";
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeParameter_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(ParamValueTxtbox.Text != "not found")
|
||||
{
|
||||
Util.ChangeAValueInCfg(ParamNameTxtbox.Text, ParamValueTxtbox.Text);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshNLInstallButtonState()
|
||||
{
|
||||
if (Launcher.IsNLPack())
|
||||
{
|
||||
NLInstallButton.IsEnabled = false;
|
||||
NLUnInstallButton.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NLInstallButton.IsEnabled = true;
|
||||
NLUnInstallButton.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void NLInstallButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// TODO Install THE NL PACK, USING NL FOLDERS URL
|
||||
Launcher.SetIsNLPack(true);
|
||||
RefreshNLInstallButtonState();
|
||||
MainWindowReference.CallUpdateGame();
|
||||
MainWindowReference.SettingButton.IsEnabled = false;
|
||||
this.Hide();
|
||||
}
|
||||
|
||||
private void NLUnInstallButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// TODO REMOVE THE NL PACK FILES USING NL FOLDERS URL
|
||||
// THEN REPAIR INSTALLATION
|
||||
Launcher.SetIsNLPack(false);
|
||||
RefreshNLInstallButtonState();
|
||||
MainWindowReference.CallUpdateGame();
|
||||
MainWindowReference.SettingButton.IsEnabled = false;
|
||||
this.Hide();
|
||||
}
|
||||
|
||||
private void AdvSettingsInstallButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// GET THE CONFIG FILES INSIDE THE GAME URL. SHOULDNT NEED A MANIFEST, JUST GET CFGs
|
||||
try
|
||||
{
|
||||
if (System.Windows.Forms.MessageBox.Show("You are about to download a set of configuration files "
|
||||
+ Environment.NewLine + "These files will override your current and existing configuration files if they exists."
|
||||
+ Environment.NewLine + "Please chose if you want to continue.", "", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
|
||||
{
|
||||
using (WebClient webClient = new WebClient()) // yeah I know it's brutal :D
|
||||
{
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/config.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "config.cfg");
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/userconfig.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "userconfig.cfg");
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/alien_.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "alien_.cfg");
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/pistol_.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "pistol_.cfg");
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/reset_.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "reset_.cfg");
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.GameUrl + "/rine_.cfg"), Launcher.NSFolder + System.IO.Path.DirectorySeparatorChar + "rine_.cfg");
|
||||
}
|
||||
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Advanced settings Installed with success");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Advanced settings failed to install");
|
||||
}
|
||||
}
|
||||
|
||||
private void AdvSettingsUnInstallButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// REMOVE THE CFG FILES. ENDWITH(config.cfg) AND ENDWITH(_.cfg). GAME SHOULD RECREATE THE CONFIG FILE
|
||||
try
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(Launcher.NSFolder))
|
||||
{
|
||||
if (file.EndsWith("_.cfg") || file.EndsWith("config.cfg"))
|
||||
File.Delete(file);
|
||||
}
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Advanced settings Removed with success");
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Failed to remove settings");
|
||||
}
|
||||
}
|
||||
|
||||
private void BrowseHLFolderButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// BROWSE AND CHANGE THE FOLDER FILE. DONT FORGET TO UPDATE THE GLOBAL VARIABLE
|
||||
bool IsItNLPack = Launcher.IsNLPack();
|
||||
string folderPath = Util.AskForHLFolder();
|
||||
|
||||
if (folderPath!=null)
|
||||
{
|
||||
XmlBuilder.CreateConfigXml();
|
||||
Launcher.HLFolder = folderPath;
|
||||
Launcher.NSFolder = folderPath + System.IO.Path.DirectorySeparatorChar + "ns";
|
||||
}
|
||||
|
||||
MainWindowReference.CallUpdateGame();
|
||||
}
|
||||
|
||||
private void ClassicRadioButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if(windowfullyopen)
|
||||
{
|
||||
ClassicRadioButton.IsChecked = true;
|
||||
MinimalRadioButton.IsChecked = false;
|
||||
NLRadioButton.IsChecked = false;
|
||||
Util.ChangeAValueInCfg("hud_style", "0", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void MinimalRadioButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (windowfullyopen)
|
||||
{
|
||||
ClassicRadioButton.IsChecked = false;
|
||||
MinimalRadioButton.IsChecked = true;
|
||||
NLRadioButton.IsChecked = false;
|
||||
Util.ChangeAValueInCfg("hud_style", "1", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void NLRadioButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (windowfullyopen)
|
||||
{
|
||||
ClassicRadioButton.IsChecked = false;
|
||||
MinimalRadioButton.IsChecked = false;
|
||||
NLRadioButton.IsChecked = true;
|
||||
Util.ChangeAValueInCfg("hud_style", "2", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddToIgnoreButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Launcher.AddToIgnoreList();
|
||||
}
|
||||
|
||||
private void StopAfterLaunch_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Launcher.keepLauncherAlive = KeepAliveChecker.IsChecked.Value;
|
||||
|
||||
XmlBuilder.CreateConfigXml();
|
||||
}
|
||||
|
||||
private void ChangeDiscord_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Launcher.discordCustomStatus = DiscordTxtbox.Text;
|
||||
Launcher.UpdateDiscord(false);
|
||||
XmlBuilder.CreateConfigXml();
|
||||
}
|
||||
}
|
||||
}
|
665
NaturalLauncher/Util.cs
Normal file
|
@ -0,0 +1,665 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using HtmlAgilityPack;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.IO.Compression;
|
||||
using System.Windows.Resources;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class Util
|
||||
{
|
||||
public static string ComputeMD5(string file)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
|
||||
string hash = "";
|
||||
using (var stream = File.OpenRead(file))
|
||||
{
|
||||
hash = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "");
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static string LocalVersion(string path)
|
||||
{
|
||||
string lv = null;
|
||||
|
||||
if (string.IsNullOrEmpty(path)
|
||||
|| System.IO.Path.GetInvalidPathChars().Intersect(
|
||||
path.ToCharArray()).Count() != 0
|
||||
|| !new System.IO.FileInfo(path).Exists)
|
||||
{
|
||||
lv = null;
|
||||
}
|
||||
else if (new System.IO.FileInfo(path).Exists)
|
||||
{
|
||||
string s = System.IO.File.ReadAllText(path);
|
||||
if (ValidateFile(s)) {
|
||||
lv = s;
|
||||
}
|
||||
else {
|
||||
lv = null;
|
||||
}
|
||||
}
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
public static string CreateLocalVersionFile(string folderPath,
|
||||
string fileName, string version)
|
||||
{
|
||||
if (!new System.IO.DirectoryInfo(folderPath).Exists)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
string path = folderPath + Path.DirectorySeparatorChar + fileName;
|
||||
|
||||
if (new System.IO.FileInfo(path).Exists)
|
||||
{
|
||||
new System.IO.FileInfo(path).Delete();
|
||||
}
|
||||
|
||||
if (!new System.IO.FileInfo(path).Exists)
|
||||
{
|
||||
System.IO.File.WriteAllText(path, version);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
// method used to check internet connectivity
|
||||
public static bool CheckForInternetConnection(string UrlToCheck)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = new WebClient())
|
||||
using (client.OpenRead(UrlToCheck)) // or http://clients3.google.com/generate_204
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ValidateFile(string contents)
|
||||
{
|
||||
bool val = false;
|
||||
if (!string.IsNullOrEmpty(contents))
|
||||
{
|
||||
string pattern = "^([0-9]*\\.){3}[0-9]*$";
|
||||
System.Text.RegularExpressions.Regex re =
|
||||
new System.Text.RegularExpressions.Regex(pattern);
|
||||
val = re.IsMatch(contents);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public static string RemoteVersion(string url)
|
||||
{
|
||||
string rv = "";
|
||||
|
||||
try
|
||||
{
|
||||
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)
|
||||
System.Net.WebRequest.Create(url);
|
||||
System.Net.HttpWebResponse response =
|
||||
(System.Net.HttpWebResponse)req.GetResponse();
|
||||
System.IO.Stream receiveStream = response.GetResponseStream();
|
||||
System.IO.StreamReader readStream =
|
||||
new System.IO.StreamReader(receiveStream, Encoding.UTF8);
|
||||
string s = readStream.ReadToEnd();
|
||||
response.Close();
|
||||
if (ValidateFile(s))
|
||||
{
|
||||
rv = s;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Anything could have happened here but
|
||||
// we don't want to stop the user
|
||||
// from using the application.
|
||||
rv = null;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static string Size(long bytes)
|
||||
{
|
||||
if (bytes > 1000000000)
|
||||
{
|
||||
return ((float)bytes / 1000000000f).ToString("f") + " GB";
|
||||
}
|
||||
|
||||
if (bytes > 1000000)
|
||||
{
|
||||
return ((float)bytes / 1000000f).ToString("f") + " MB";
|
||||
}
|
||||
if (bytes > 1000)
|
||||
{
|
||||
return ((float)bytes / 1000f).ToString("f") + " KB";
|
||||
}
|
||||
return ((float)bytes).ToString("f") + " B";
|
||||
}
|
||||
|
||||
public static string ToLocalPath(string root, string dir)
|
||||
{
|
||||
return dir.Replace(root, "").Replace("\\", "/");
|
||||
}
|
||||
|
||||
public static string GetLongTimeString()
|
||||
{
|
||||
var src = DateTime.Now;
|
||||
string StringToReturn = src.Month + "_" + src.Day + "_" + src.Hour + "_" + src.Minute + "_" + src.Second;
|
||||
return StringToReturn;
|
||||
}
|
||||
|
||||
public static string GetShortTimeString()
|
||||
{
|
||||
var src = DateTime.Now;
|
||||
string StringToReturn = "[ " + src.Hour + " : " + src.Minute + " : " + src.Second + " ] : ";
|
||||
return StringToReturn;
|
||||
}
|
||||
|
||||
public static string GetSteamFolder(bool WantCommon) //just testing if ever needed
|
||||
{
|
||||
string path = "";
|
||||
// HKEY_CURRENT_USER/Software/Valve/Steam
|
||||
try
|
||||
{
|
||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Valve\\Steam"))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
Object o = key.GetValue("SteamPath");
|
||||
if (o != null)
|
||||
{
|
||||
path = o as String;
|
||||
|
||||
if(WantCommon)
|
||||
path = path + "/steamapps/common";
|
||||
|
||||
path = Path.GetFullPath(path);
|
||||
|
||||
Console.WriteLine(path);
|
||||
|
||||
// NEEDS A NUGGET PACKAGE GAMELOOP.VDF TO READ
|
||||
// To get full list of game folders : steamapps\libraryfolders.vdf
|
||||
/*string LibraryFoldersPath = path + Path.DirectorySeparatorChar + "steamapps" + Path.DirectorySeparatorChar + "libraryfolders.vdf";
|
||||
|
||||
// we need a function to extract folder directory
|
||||
dynamic FolderLibrary = VdfConvert.Deserialize(File.ReadAllText(LibraryFoldersPath));
|
||||
var FolderLibraryValues = FolderLibrary.Value;
|
||||
var importantJsonObject = FolderLibrary.ToJson();*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBoxResult AlertBox = MessageBox.Show("Steam Folder not found");
|
||||
path = "";
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
public static string GetHLFolder() //just testing if ever needed
|
||||
{
|
||||
string path = "";
|
||||
// HKEY_CURRENT_USER/Software/Valve/Steam
|
||||
try
|
||||
{
|
||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Valve\\Steam"))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
Object o = key.GetValue("ModInstallPath");
|
||||
if (o != null)
|
||||
{
|
||||
path = o as String;
|
||||
|
||||
path = Path.GetFullPath(path);
|
||||
|
||||
Console.WriteLine(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBoxResult AlertBox = MessageBox.Show("HL Folder not found","Alert", MessageBoxButton.OK , MessageBoxImage.Error);
|
||||
path = "";
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
public static int ReadGathererCount()
|
||||
{
|
||||
var url = Properties.Settings.Default.GatherURL;
|
||||
var web = new HtmlWeb();
|
||||
var doc = web.Load(url);
|
||||
string htmlstring = doc.Text;
|
||||
int Count = 0;
|
||||
// need to retrieve this : <ul id="gatherers">
|
||||
var nodal = doc.DocumentNode.Descendants("ul");
|
||||
|
||||
for(int i = 0; i < nodal.Count(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nodal.ElementAt(i).Id == "gatherers")
|
||||
{
|
||||
Count = nodal.ElementAt(i).SelectNodes("li").Count(); //and count the <li> inside
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
// This function is here to compare the general "standard" ns install with the advanced "NlPack" install version
|
||||
// If the user is using the NLPack then the manifest has to be updated consequently.
|
||||
public static LauncherManifest CleanManifestWithOptions(LauncherManifest GeneralManifest, LauncherManifest NLManifest)
|
||||
{
|
||||
//string value = "";
|
||||
foreach (KeyValuePair<string, string> kv in NLManifest.Files)
|
||||
{
|
||||
if (GeneralManifest.Files.ContainsKey(kv.Key))
|
||||
{
|
||||
// we should delete, not to verify this. Then a second period of the updater check changed with the nl folder and its own manifest.
|
||||
// the following code is in case you want to change the value (commented)
|
||||
|
||||
/*NLManifest.Files.TryGetValue(kv.Key, out value);
|
||||
GeneralManifest.Files[kv.Key] = value; */
|
||||
|
||||
GeneralManifest.Files.Remove(kv.Key);
|
||||
}
|
||||
}
|
||||
|
||||
return GeneralManifest;
|
||||
}
|
||||
|
||||
public static bool RemoteFileExists(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Creating the HttpWebRequest
|
||||
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
|
||||
//Setting the Request method HEAD, you can also use GET too.
|
||||
request.Method = "HEAD";
|
||||
//Getting the Web Response.
|
||||
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
|
||||
//Returns TRUE if the Status code == 200
|
||||
response.Close();
|
||||
return (response.StatusCode == HttpStatusCode.OK);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Any exception will returns false.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> TheDirectory = new List<string>();
|
||||
|
||||
public static List<string> GetDirectoryFilesFromUrl(string url)
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
string html = reader.ReadToEnd();
|
||||
Regex regex = new Regex(GetDirectoryListingRegexForUrl(url));
|
||||
MatchCollection matches = regex.Matches(html);
|
||||
if (matches.Count > 0)
|
||||
{
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
if (match.Success)
|
||||
{
|
||||
TheDirectory.Add(match.Groups["name"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TheDirectory.Remove("Parent Directory");
|
||||
|
||||
return TheDirectory;
|
||||
|
||||
}
|
||||
|
||||
public static string GetDirectoryListingRegexForUrl(string url)
|
||||
{
|
||||
if (url.Equals(url))
|
||||
{
|
||||
return "<a href=\".*\">(?<name>.*)</a>"; //problem with the .exe.config file
|
||||
}
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public static string AskForHLFolder()
|
||||
{
|
||||
string folderPath = "";
|
||||
var dialog = new System.Windows.Forms.OpenFileDialog();
|
||||
|
||||
dialog.InitialDirectory = Util.GetHLFolder();
|
||||
dialog.Filter = "Half life Executable|hl.exe";
|
||||
|
||||
dialog.Title = "Please indicate where is your Half Life steam executable !";
|
||||
|
||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
folderPath = dialog.FileName;
|
||||
folderPath = folderPath.Remove(folderPath.Length + 1 - 8);
|
||||
return folderPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.PlaySoundFX("error");
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("This launcher need your half life directory in order to function. Please relaunch.", "Alert", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
|
||||
folderPath = null;
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
public static LauncherManifest GetIgnoreManifest(bool isVerification)
|
||||
{
|
||||
// we first get the ignore.list used by dev
|
||||
string IgnorePath = Launcher.curDir + Path.DirectorySeparatorChar + "ignore.list";
|
||||
LauncherManifest NewManifest = new LauncherManifest();
|
||||
|
||||
if (File.Exists(IgnorePath) && isVerification) //then we can use the one in the folder. That's ok
|
||||
{
|
||||
string IgnoreString = File.ReadAllText(IgnorePath);
|
||||
NewManifest = JsonConvert.DeserializeObject<LauncherManifest>(IgnoreString);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
using (WebClient webClient = new WebClient()) // yeah I know it's brutal :D
|
||||
{
|
||||
webClient.DownloadFile(new Uri(Properties.Settings.Default.IndexURL + "/ignore.list"), IgnorePath);
|
||||
}
|
||||
|
||||
string IgnoreString = File.ReadAllText(IgnorePath);
|
||||
NewManifest = JsonConvert.DeserializeObject<LauncherManifest>(IgnoreString);
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Could not retrieve a new ignore manifest file, Creating a void one...");
|
||||
NewManifest.Files["/config.cfg"] = "";*/
|
||||
Util.PlaySoundFX("error");
|
||||
MessageBoxResult AlertBox = System.Windows.MessageBox.Show("Launcher couldn't find a correct ignore.list from online source, please verify you internet connection..."
|
||||
, "Alert", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
|
||||
throw new Exception("Launcher couldn't find a correct ignore.list from online source, please verify you internet connection...");
|
||||
}
|
||||
}
|
||||
// then we read the custom one on the disk
|
||||
string CustomIgnorePath = Launcher.curDir + Path.DirectorySeparatorChar + "customignore.list";
|
||||
LauncherManifest CustomignoreManifest = new LauncherManifest();
|
||||
|
||||
if (File.Exists(CustomIgnorePath))
|
||||
{
|
||||
string IgnoreString = File.ReadAllText(CustomIgnorePath);
|
||||
CustomignoreManifest = JsonConvert.DeserializeObject<LauncherManifest>(IgnoreString);
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomignoreManifest.Files["/exemple.xpl"] = "1";
|
||||
|
||||
File.WriteAllText(CustomIgnorePath, JsonConvert.SerializeObject(CustomignoreManifest, Formatting.Indented)); //write the new voidy ignore manifest
|
||||
}
|
||||
|
||||
// then we add both manifest to return the ignore list
|
||||
foreach(KeyValuePair<string, string> kv in CustomignoreManifest.Files)
|
||||
{
|
||||
NewManifest.Files.Add(kv.Key, kv.Value);
|
||||
}
|
||||
|
||||
return NewManifest;
|
||||
}
|
||||
|
||||
public static void CopyDirectory(string SourcePath, string DestinationPath) //not used anymore.
|
||||
{
|
||||
//Now Create all of the directories
|
||||
foreach (string dirPath in Directory.GetDirectories(SourcePath, "*",
|
||||
SearchOption.AllDirectories))
|
||||
Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));
|
||||
|
||||
ConsoleManager.Show();
|
||||
//Copy all the files & Replaces any files with the same name
|
||||
foreach (string newPath in Directory.GetFiles(SourcePath, "*.*",
|
||||
SearchOption.AllDirectories))
|
||||
{
|
||||
/*string newdirr = Path.GetDirectoryName(newPath);
|
||||
if (!newdirr.Contains("sound") || !newPath.Contains("maps") || !newPath.Contains("dlls") || !newPath.Contains("cl_dlls"))
|
||||
{*/
|
||||
Console.WriteLine(Path.GetFileName(newPath) + " being copied...");
|
||||
File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);
|
||||
//}
|
||||
}
|
||||
|
||||
ConsoleManager.Hide();
|
||||
|
||||
}
|
||||
|
||||
public static void ZipDirectory(string SourceDirPath)
|
||||
{
|
||||
ConsoleManager.Show();
|
||||
Console.WriteLine("Ziping directory...");
|
||||
Console.WriteLine("This can take up to 2 minutes, please wait...");
|
||||
ZipFile.CreateFromDirectory(SourceDirPath, SourceDirPath + "_saved.zip", CompressionLevel.Optimal,false);
|
||||
Console.WriteLine("Ziping done !");
|
||||
ConsoleManager.Hide();
|
||||
}
|
||||
|
||||
public static bool GetAValueInCfg(string ValueName, out string Value)
|
||||
{
|
||||
string[] CfgLines = File.ReadAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "config.cfg");
|
||||
string[] UCfgLines = File.ReadAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "userconfig.cfg");
|
||||
bool found = false;
|
||||
Value = "not found";
|
||||
|
||||
// first we look in the config.cfg then we will look in userconfig and keep its value if it exists (as it's the last cfg executed)
|
||||
foreach (string Line in CfgLines)
|
||||
{
|
||||
if(Line.StartsWith(ValueName))
|
||||
{
|
||||
Value = Line.Remove(0, ValueName.Length + 2); //on enleve tout le debut et le premier guillemet
|
||||
Value = Value.Remove(Value.Length - 1, 1); // et le dernier
|
||||
found = true;
|
||||
//initialInt = Convert.ToInt32(initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
// if it's the userconfig, take that instead
|
||||
foreach (string Line in UCfgLines)
|
||||
{
|
||||
if (Line.StartsWith(ValueName))
|
||||
{
|
||||
Value = Line.Remove(0, ValueName.Length + 2); //on enleve tout le debut et le premier guillemet
|
||||
Value = Value.Remove(Value.Length - 1, 1); // et le dernier
|
||||
found = true;
|
||||
//initialInt = Convert.ToInt32(initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
public static void ChangeAValueInCfg(string ValueName,string Value,bool isStrictToConfig = false)
|
||||
{
|
||||
string[] CfgLines = File.ReadAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "config.cfg");
|
||||
string[] UCfgLines = File.ReadAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "userconfig.cfg");
|
||||
bool cfgchange = false;
|
||||
bool ucfgchange = false;
|
||||
bool found = false;
|
||||
int loopindex = 0;
|
||||
// first we look in the config.cfg then we will look in userconfig and keep its value if it exists (as it's the last cfg executed)
|
||||
foreach (string Line in CfgLines)
|
||||
{
|
||||
if (Line.StartsWith(ValueName))
|
||||
{
|
||||
CfgLines[loopindex] = ValueName + " " + "\"" + Value + "\"";
|
||||
found = true;
|
||||
cfgchange = true;
|
||||
}
|
||||
loopindex++;
|
||||
}
|
||||
|
||||
if (isStrictToConfig) //if should only be in config.cfg, let's verify it's not in usercfg
|
||||
{
|
||||
loopindex = 0;
|
||||
foreach (string Line in UCfgLines)
|
||||
{
|
||||
if (Line.StartsWith(ValueName))
|
||||
{
|
||||
UCfgLines[loopindex] = ""; //we remove the doublon
|
||||
ucfgchange = true;
|
||||
}
|
||||
loopindex++;
|
||||
}
|
||||
}
|
||||
if (!isStrictToConfig) //we can check usercfg
|
||||
{
|
||||
loopindex = 0;
|
||||
foreach (string Line in UCfgLines)
|
||||
{
|
||||
if (Line.StartsWith(ValueName))
|
||||
{
|
||||
UCfgLines[loopindex] = ValueName + " " + "\"" + Value + "\"";
|
||||
found = true;
|
||||
ucfgchange = true;
|
||||
}
|
||||
loopindex++;
|
||||
}
|
||||
}
|
||||
if (!found && !isStrictToConfig) //we didnt find it, let's add it to usercfg!
|
||||
{
|
||||
Array.Resize(ref UCfgLines, UCfgLines.Length + 1);
|
||||
UCfgLines[UCfgLines.Length - 1] = ValueName + " " + "\"" + Value + "\"";
|
||||
ucfgchange = true;
|
||||
}
|
||||
|
||||
if (!found && isStrictToConfig) //we didnt find it, let's add it to config cfg !
|
||||
{
|
||||
Array.Resize(ref CfgLines, CfgLines.Length + 1);
|
||||
CfgLines[CfgLines.Length - 1] = ValueName + " " + "\"" + Value + "\"";
|
||||
cfgchange = true;
|
||||
}
|
||||
|
||||
// ecrire le deux fichiers à l'emplacement source !
|
||||
try
|
||||
{
|
||||
if(cfgchange)
|
||||
{
|
||||
File.WriteAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "config.cfg", CfgLines);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
System.Windows.MessageBox.Show("Could not write config.cfg, please verify the file is not read only !", "Read only", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (ucfgchange)
|
||||
{
|
||||
File.WriteAllLines(Launcher.NSFolder + Path.DirectorySeparatorChar + "userconfig.cfg", UCfgLines);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
System.Windows.MessageBox.Show("Could not write userconfig.cfg, please verify the file is not read only !" + Environment.NewLine +
|
||||
"This problem may also be caused by a hud_style setting in your userconfig.cfg file !", "Read only", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void LaunchAgain(string PathToExe)
|
||||
{
|
||||
ProcessStartInfo processInfo = new ProcessStartInfo();
|
||||
processInfo.WorkingDirectory = Path.GetDirectoryName(PathToExe);
|
||||
processInfo.FileName = Path.GetFileName(PathToExe);
|
||||
processInfo.ErrorDialog = true;
|
||||
processInfo.UseShellExecute = false;
|
||||
processInfo.RedirectStandardOutput = true;
|
||||
processInfo.RedirectStandardError = true;
|
||||
Process proc = Process.Start(processInfo);
|
||||
}
|
||||
|
||||
public static void PlaySoundFX(string Type) //now only play when error because whiners
|
||||
{
|
||||
Uri resourceUri = new Uri("Ressources/sdx_error.wav", UriKind.Relative);
|
||||
switch (Type)
|
||||
{
|
||||
case "error":
|
||||
resourceUri = new Uri("Ressources/sdx_error.wav", UriKind.Relative);
|
||||
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
|
||||
|
||||
System.Media.SoundPlayer player = new System.Media.SoundPlayer(streamInfo.Stream);
|
||||
player.Play();
|
||||
break;
|
||||
case "start":
|
||||
resourceUri = new Uri("Ressources/sdx_started.wav", UriKind.Relative);
|
||||
break;
|
||||
case "finish":
|
||||
resourceUri = new Uri("Ressources/sdx_finished.wav", UriKind.Relative);
|
||||
break;
|
||||
default:
|
||||
resourceUri = new Uri("Ressources/sdx_error.wav", UriKind.Relative);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
131
NaturalLauncher/XmlBuilder.cs
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Natural Launcher
|
||||
|
||||
Copyright (C) 2018 Mael "Khelben" Vignaux
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me with any question at the mail : mael.vignaux@elseware-experience.com
|
||||
*/
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace NaturalLauncher
|
||||
{
|
||||
class XmlBuilder
|
||||
{
|
||||
|
||||
public static bool BuildXmlDocument(string ManifestRootPath)
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(ManifestRootPath);
|
||||
var doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
|
||||
StartCreateXML(dir));
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(ManifestRootPath + Path.DirectorySeparatorChar + "Manifest.xml", doc.ToString()); //write the new voidy ignore manifest
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static XElement StartCreateXML(DirectoryInfo dir) // create a full directory xml
|
||||
{
|
||||
var xmlInfo = new XElement("MainDirectory");
|
||||
//get all the files first
|
||||
foreach (var file in dir.GetFiles())
|
||||
{
|
||||
xmlInfo.Add(new XElement("file", new XAttribute("name", file.Name)));
|
||||
}
|
||||
//get subdirectories
|
||||
var subdirectories = dir.GetDirectories().ToList().OrderBy(d => d.Name);
|
||||
foreach (var subDir in subdirectories)
|
||||
{
|
||||
xmlInfo.Add(CreateSubdirectoryXML(subDir));
|
||||
}
|
||||
return xmlInfo;
|
||||
}
|
||||
|
||||
public static XElement CreateSubdirectoryXML(DirectoryInfo dir)
|
||||
{
|
||||
//get directories
|
||||
var xmlInfo = new XElement("folder", new XAttribute("name", dir.Name));
|
||||
//get all the files first
|
||||
foreach (var file in dir.GetFiles())
|
||||
{
|
||||
xmlInfo.Add(new XElement("file", new XAttribute("name", file.Name)));
|
||||
}
|
||||
//get subdirectories
|
||||
var subdirectories = dir.GetDirectories().ToList().OrderBy(d => d.Name);
|
||||
foreach (var subDir in subdirectories)
|
||||
{
|
||||
xmlInfo.Add(CreateSubdirectoryXML(subDir));
|
||||
}
|
||||
return xmlInfo;
|
||||
}
|
||||
|
||||
public static bool ReadConfigXml(out string HLFolder, out bool IsNlPack, out string customDiscordStatus, out bool keepLauncherAlive)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
try
|
||||
{
|
||||
doc.Load(Launcher.curDir + Path.DirectorySeparatorChar + Launcher.configName);
|
||||
XmlNodeList nodelist = doc.SelectNodes("/LauncherConfiguration");
|
||||
HLFolder = doc.SelectSingleNode("//HLFolder").InnerText;
|
||||
IsNlPack = doc.SelectSingleNode("//NLPack").InnerText == "True";
|
||||
customDiscordStatus = doc.SelectSingleNode("//DiscordStatus").InnerText;
|
||||
keepLauncherAlive = doc.SelectSingleNode("//keeplauncherAlive").InnerText == "True";
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
HLFolder = "";
|
||||
IsNlPack = false;
|
||||
customDiscordStatus = "Gather forming";
|
||||
keepLauncherAlive = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static bool CreateConfigXml()
|
||||
{
|
||||
var xmlInfo = new XElement("LauncherConfiguration");
|
||||
xmlInfo.Add(new XElement("HLFolder", Launcher.HLFolder));
|
||||
xmlInfo.Add(new XElement("NLPack", "False"/*Launcher.IsNLPack().ToString()*/)); //doesnt matter anymore, also, can't use this function cause it asks for the config file...
|
||||
xmlInfo.Add(new XElement("DiscordStatus", Launcher.discordCustomStatus));
|
||||
xmlInfo.Add(new XElement("keeplauncherAlive", Launcher.keepLauncherAlive.ToString()));
|
||||
|
||||
var doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), xmlInfo);
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(Launcher.curDir + Path.DirectorySeparatorChar + Launcher.configName, doc.ToString()); //write the new voidy ignore manifest
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
BIN
NaturalLauncher/nsl_icon.ico
Normal file
After Width: | Height: | Size: 27 KiB |
6
NaturalLauncher/packages.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="HtmlAgilityPack" version="1.8.5" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net462" />
|
||||
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net462" />
|
||||
</packages>
|
BIN
NslKey.cer
Normal file
32
README.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# NaturalLauncher
|
||||
|
||||
*Natural selection launcher and updater. Allows for quick update of the natural selection folder.
|
||||
|
||||
|
||||
#TO BUILD FROM SOURCES
|
||||
*If you are building from sources, I imagine you don't want the .exe file to permanantly check for online consistency (public key required) nor self update.
|
||||
*In order to do so, simply go in SelfUpdater.cs and set the variable "isSelfUpdating" to false.
|
||||
*You are basicaly good to go !
|
||||
|
||||
#CHANGE THE ONLINE FILES THE LAUNCHER REFERS TO
|
||||
*If you want you own files online, simply change, in the configuration setting of the natural launcher projet in VS, the IndexURL to your custom URL
|
||||
*as well as the GameUrl to the game URL (sounds logical enough ?)
|
||||
|
||||
#TO COMMIT A NEW NS VERSION / PATCH
|
||||
|
||||
##FROM THE LAUNCHER:
|
||||
*1 - Launch the launcher (tricky sentence)
|
||||
*2 - Verify it has the right half life folder target
|
||||
*3 - Right click in the launcher
|
||||
*4 - Build Manifest
|
||||
|
||||
##FROM THE MANIFESTBUILDER.EXE
|
||||
*1 - Place the manifestbuilder.exe app in the correct folder
|
||||
*2 - Execute it
|
||||
*3 - Enjoy
|
||||
*4 - Really do it
|
||||
|
||||
##THEN
|
||||
*5 - Upload files in the "Game" Folder of the ftp
|
||||
*6 - Upload the manifest in the root folder.
|
||||
*7 - Update the app.version with the new number in root folder
|