diff --git a/src/.editorconfig b/.editorconfig similarity index 100% rename from src/.editorconfig rename to .editorconfig diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-blank.xcf b/src/EndlessOnlinePatcher.Desktop/Resources/eo-blank.xcf deleted file mode 100644 index 1dbee59..0000000 Binary files a/src/EndlessOnlinePatcher.Desktop/Resources/eo-blank.xcf and /dev/null differ diff --git a/src/EndlessOnlinePatcher.sln b/src/EndlessOnlinePatcher.sln deleted file mode 100644 index 7e8d6b0..0000000 --- a/src/EndlessOnlinePatcher.sln +++ /dev/null @@ -1,36 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.7.34031.279 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EndlessOnlinePatcher", "EndlessOnlinePatcher\EndlessOnlinePatcher.csproj", "{630A5F38-3B1F-4850-88E5-33E2D3766C82}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EndlessOnlinePatcher.Desktop", "EndlessOnlinePatcher.Desktop\EndlessOnlinePatcher.Desktop.csproj", "{74671C17-2B5A-4E0D-9C38-74F790D659D5}" -EndProject -Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "EndlessOnlinePatcherSetup", "EndlessOnlinePatcherSetup\EndlessOnlinePatcherSetup.vdproj", "{1D9DA1F0-1366-46A9-8C90-720B7DC7303F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {630A5F38-3B1F-4850-88E5-33E2D3766C82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {630A5F38-3B1F-4850-88E5-33E2D3766C82}.Debug|Any CPU.Build.0 = Debug|Any CPU - {630A5F38-3B1F-4850-88E5-33E2D3766C82}.Release|Any CPU.ActiveCfg = Release|Any CPU - {630A5F38-3B1F-4850-88E5-33E2D3766C82}.Release|Any CPU.Build.0 = Release|Any CPU - {74671C17-2B5A-4E0D-9C38-74F790D659D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {74671C17-2B5A-4E0D-9C38-74F790D659D5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {74671C17-2B5A-4E0D-9C38-74F790D659D5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {74671C17-2B5A-4E0D-9C38-74F790D659D5}.Release|Any CPU.Build.0 = Release|Any CPU - {1D9DA1F0-1366-46A9-8C90-720B7DC7303F}.Debug|Any CPU.ActiveCfg = Debug - {1D9DA1F0-1366-46A9-8C90-720B7DC7303F}.Release|Any CPU.ActiveCfg = Release - {1D9DA1F0-1366-46A9-8C90-720B7DC7303F}.Release|Any CPU.Build.0 = Release - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D1579206-4DB9-48C7-BB49-C52FE7903A74} - EndGlobalSection -EndGlobal diff --git a/src/EndlessOnlinePatcher/Core/ClientVersionFetcher.cs b/src/EndlessOnlinePatcher/Core/ClientVersionFetcher.cs deleted file mode 100644 index bd5c7a9..0000000 --- a/src/EndlessOnlinePatcher/Core/ClientVersionFetcher.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Diagnostics; -using System.Text.RegularExpressions; - -namespace EndlessOnlinePatcher.Core; -public partial class ClientVersionFetcher : IClientVersionFetcher -{ - [GeneratedRegex("href=\"(.*EndlessOnline(\\d*)([a-zA-Z])*.zip)\"")] - private static partial Regex EndlessOnlineZipRegex(); - - public FileVersion GetLocal() - { - if (!File.Exists(EndlessOnlineDirectory.GetExe())) - return new FileVersion(0, 0, 0, 0); - - var versionInfo = FileVersionInfo.GetVersionInfo(EndlessOnlineDirectory.GetExe()); - - if (versionInfo == null) - return new FileVersion(0, 0, 0, 0); - - return FileVersion.FromString(versionInfo.FileVersion ?? throw new ArgumentNullException(versionInfo.FileVersion)); - } - - public async Task<(string downloadLink, FileVersion)> GetRemoteAsync() - { - using var httpClient = new HttpClient(); - var endlessHomePage = await httpClient.GetStringAsync("https://www.endless-online.com/client/download.html"); - var regexVersionMatches = EndlessOnlineZipRegex().Match(endlessHomePage); - var downloadLink = regexVersionMatches.Groups[1].Value; - var major = int.Parse(regexVersionMatches.Groups[2].Value[0].ToString()); - var minor = int.Parse(regexVersionMatches.Groups[2].Value[1].ToString()); - var build = int.Parse(regexVersionMatches.Groups[2].Value[2..].ToString()); - - if (regexVersionMatches.Groups.Count > 3 && !string.IsNullOrWhiteSpace(regexVersionMatches.Groups[3].Value)) - { - var patchAlpha = regexVersionMatches.Groups[3].Value[0]; - var patch = patchAlpha switch - { - var p when patchAlpha >= 'a' && patchAlpha <= 'z' => p - 'a', - var p when patchAlpha >= 'A' && patchAlpha <= 'Z' => p - 'A', - _ => throw new ArgumentException("Patch must be alphabetical") - }; - - return (downloadLink, new FileVersion(major, minor, build, patch)); - } - - return (downloadLink, new FileVersion(major, minor, build, 0)); - } -} \ No newline at end of file diff --git a/src/EndlessOnlinePatcher/Core/FileVersion.cs b/src/EndlessOnlinePatcher/Core/FileVersion.cs deleted file mode 100644 index 4b62a8d..0000000 --- a/src/EndlessOnlinePatcher/Core/FileVersion.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace EndlessOnlinePatcher.Core; - -public record FileVersion(int Major = 0, int Minor = 0, int Build = 0, int Revision = 0) -{ - public override string ToString() => $"{Major}.{Minor}.{Build}.{Revision}"; - public static FileVersion FromString(string s) - { - var parts = s.Split('.').Select(int.Parse).ToArray(); - return new FileVersion(parts[0], parts[1], parts[2], parts[3]); - } - - public static bool operator >(FileVersion a, FileVersion b) - => a.Major > b.Major || - a.Major == b.Major && a.Minor > a.Minor || - a.Major == b.Major && a.Minor == b.Minor && a.Build > b.Build || - a.Major == b.Major && a.Minor == b.Minor && a.Build == b.Build && a.Revision > b.Revision; - - public static bool operator <(FileVersion a, FileVersion b) - => a.Major < b.Major || - a.Major == b.Major && a.Minor < a.Minor || - a.Major == b.Major && a.Minor == b.Minor && a.Build < b.Build || - a.Major == b.Major && a.Minor == b.Minor && a.Build == b.Build && a.Revision < b.Revision; -} \ No newline at end of file diff --git a/src/EndlessOnlinePatcher/Core/IClientVersionFetcher.cs b/src/EndlessOnlinePatcher/Core/IClientVersionFetcher.cs deleted file mode 100644 index c08583f..0000000 --- a/src/EndlessOnlinePatcher/Core/IClientVersionFetcher.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EndlessOnlinePatcher.Core; - -public interface IClientVersionFetcher -{ - FileVersion GetLocal(); - Task<(string downloadLink, FileVersion)> GetRemoteAsync(); -} \ No newline at end of file diff --git a/src/EndlessOnlinePatcher/Core/IPatcher.cs b/src/EndlessOnlinePatcher/Core/IPatcher.cs deleted file mode 100644 index 195909f..0000000 --- a/src/EndlessOnlinePatcher/Core/IPatcher.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace EndlessOnlinePatcher.Core; - -internal interface IPatcher -{ - public Task Patch(FileVersion version); -} diff --git a/src/EndlessOnlinePatcher/EndlessOnlinePatcher.csproj b/src/EndlessOnlinePatcher/EndlessOnlinePatcher.csproj deleted file mode 100644 index 6030140..0000000 --- a/src/EndlessOnlinePatcher/EndlessOnlinePatcher.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net8.0 - enable - enable - - - diff --git a/src/EoPatcher.Core/EoPatcher.Core.csproj b/src/EoPatcher.Core/EoPatcher.Core.csproj new file mode 100644 index 0000000..f449b3c --- /dev/null +++ b/src/EoPatcher.Core/EoPatcher.Core.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/src/EndlessOnlinePatcher/Extensions/HttpClientExtensions.cs b/src/EoPatcher.Core/Extensions/HttpClientExtensions.cs similarity index 96% rename from src/EndlessOnlinePatcher/Extensions/HttpClientExtensions.cs rename to src/EoPatcher.Core/Extensions/HttpClientExtensions.cs index e89e460..acc783d 100644 --- a/src/EndlessOnlinePatcher/Extensions/HttpClientExtensions.cs +++ b/src/EoPatcher.Core/Extensions/HttpClientExtensions.cs @@ -1,4 +1,4 @@ -namespace EndlessOnlinePatcher.Extensions; +namespace EoPatcher.Extensions; public static class HttpClientExtensions { public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress? progress = null, CancellationToken cancellationToken = default) diff --git a/src/EndlessOnlinePatcher/Extensions/StreamExtensions.cs b/src/EoPatcher.Core/Extensions/StreamExtensions.cs similarity index 96% rename from src/EndlessOnlinePatcher/Extensions/StreamExtensions.cs rename to src/EoPatcher.Core/Extensions/StreamExtensions.cs index 9a04662..8b3ec82 100644 --- a/src/EndlessOnlinePatcher/Extensions/StreamExtensions.cs +++ b/src/EoPatcher.Core/Extensions/StreamExtensions.cs @@ -1,6 +1,5 @@ -using System; +namespace EoPatcher.Extensions; -namespace EndlessOnlinePatcher.Extensions; public static class StreamExtensions { public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, long contentLength, IProgress? progress = null, CancellationToken cancellationToken = default) diff --git a/src/EndlessOnlinePatcher/Core/Windows.cs b/src/EoPatcher.Core/Interop/Windows.cs similarity index 73% rename from src/EndlessOnlinePatcher/Core/Windows.cs rename to src/EoPatcher.Core/Interop/Windows.cs index 3e4dd57..e6eb38a 100644 --- a/src/EndlessOnlinePatcher/Core/Windows.cs +++ b/src/EoPatcher.Core/Interop/Windows.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; +using EoPatcher.Models; -namespace EndlessOnlinePatcher.Core; +namespace EoPatcher.Interop; public static class Windows { @@ -27,7 +28,7 @@ private static void RunAsDesktopUser(string fileName) // 6. Make a primary token with that token(DuplicateTokenEx) // 7. Start the new process with that primary token(CreateProcessWithTokenW) - var hProcessToken = IntPtr.Zero; + var hProcessToken = nint.Zero; // Enable SeIncreaseQuotaPrivilege in this process. (This won't work if current process is not elevated.) try { @@ -46,7 +47,7 @@ private static void RunAsDesktopUser(string fileName) tkp.Privileges[0].Attributes = 0x00000002; - if (!AdjustTokenPrivileges(hProcessToken, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero)) + if (!AdjustTokenPrivileges(hProcessToken, false, ref tkp, 0, nint.Zero, nint.Zero)) return; } finally @@ -59,12 +60,12 @@ private static void RunAsDesktopUser(string fileName) // replaced with a custom shell. This also won't return what you probably want if Explorer has been terminated and // restarted elevated. var hwnd = GetShellWindow(); - if (hwnd == IntPtr.Zero) + if (hwnd == nint.Zero) return; - var hShellProcess = IntPtr.Zero; - var hShellProcessToken = IntPtr.Zero; - var hPrimaryToken = IntPtr.Zero; + var hShellProcess = nint.Zero; + var hShellProcessToken = nint.Zero; + var hPrimaryToken = nint.Zero; try { // Get the PID of the desktop shell process. @@ -74,7 +75,7 @@ private static void RunAsDesktopUser(string fileName) // Open the desktop shell process in order to query it (get the token) hShellProcess = OpenProcess(ProcessAccessFlags.QueryInformation, false, dwPID); - if (hShellProcess == IntPtr.Zero) + if (hShellProcess == nint.Zero) return; // Get the process token of the desktop shell. @@ -85,13 +86,13 @@ private static void RunAsDesktopUser(string fileName) // Duplicate the shell's process token to get a primary token. // Based on experimentation, this is the minimal set of rights required for CreateProcessWithTokenW (contrary to current documentation). - if (!DuplicateTokenEx(hShellProcessToken, dwTokenRights, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out hPrimaryToken)) + if (!DuplicateTokenEx(hShellProcessToken, dwTokenRights, nint.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out hPrimaryToken)) return; // Start the target process with the new token. var si = new STARTUPINFO(); var pi = new PROCESS_INFORMATION(); - if (!CreateProcessWithTokenW(hPrimaryToken, 0, fileName, "", 0, IntPtr.Zero, Path.GetDirectoryName(fileName)!, ref si, out pi)) + if (!CreateProcessWithTokenW(hPrimaryToken, 0, fileName, "", 0, nint.Zero, Path.GetDirectoryName(fileName)!, ref si, out pi)) return; } finally @@ -107,7 +108,7 @@ private static void RunAsDesktopUser(string fileName) private struct TOKEN_PRIVILEGES { - public UInt32 PrivilegeCount; + public uint PrivilegeCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public LUID_AND_ATTRIBUTES[] Privileges; } @@ -116,7 +117,7 @@ private struct TOKEN_PRIVILEGES private struct LUID_AND_ATTRIBUTES { public LUID Luid; - public UInt32 Attributes; + public uint Attributes; } [StructLayout(LayoutKind.Sequential)] @@ -161,8 +162,8 @@ private enum TOKEN_TYPE [StructLayout(LayoutKind.Sequential)] private struct PROCESS_INFORMATION { - public IntPtr hProcess; - public IntPtr hThread; + public nint hProcess; + public nint hThread; public int dwProcessId; public int dwThreadId; } @@ -170,57 +171,57 @@ private struct PROCESS_INFORMATION [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct STARTUPINFO { - public Int32 cb; + public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; - public Int32 dwX; - public Int32 dwY; - public Int32 dwXSize; - public Int32 dwYSize; - public Int32 dwXCountChars; - public Int32 dwYCountChars; - public Int32 dwFillAttribute; - public Int32 dwFlags; - public Int16 wShowWindow; - public Int16 cbReserved2; - public IntPtr lpReserved2; - public IntPtr hStdInput; - public IntPtr hStdOutput; - public IntPtr hStdError; + public int dwX; + public int dwY; + public int dwXSize; + public int dwYSize; + public int dwXCountChars; + public int dwYCountChars; + public int dwFillAttribute; + public int dwFlags; + public short wShowWindow; + public short cbReserved2; + public nint lpReserved2; + public nint hStdInput; + public nint hStdOutput; + public nint hStdError; } [DllImport("kernel32.dll", ExactSpelling = true)] - private static extern IntPtr GetCurrentProcess(); + private static extern nint GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - private static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); + private static extern bool OpenProcessToken(nint h, int acc, ref nint phtok); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool LookupPrivilegeValue(string host, string name, ref LUID pluid); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TOKEN_PRIVILEGES newst, int len, IntPtr prev, IntPtr relen); + private static extern bool AdjustTokenPrivileges(nint htok, bool disall, ref TOKEN_PRIVILEGES newst, int len, nint prev, nint relen); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool CloseHandle(IntPtr hObject); + private static extern bool CloseHandle(nint hObject); [DllImport("user32.dll")] - private static extern IntPtr GetShellWindow(); + private static extern nint GetShellWindow(); [DllImport("user32.dll", SetLastError = true)] - private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + private static extern uint GetWindowThreadProcessId(nint hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll", SetLastError = true)] - private static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, uint processId); + private static extern nint OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, uint processId); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL impersonationLevel, TOKEN_TYPE tokenType, out IntPtr phNewToken); + private static extern bool DuplicateTokenEx(nint hExistingToken, uint dwDesiredAccess, nint lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL impersonationLevel, TOKEN_TYPE tokenType, out nint phNewToken); [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool CreateProcessWithTokenW(IntPtr hToken, int dwLogonFlags, string lpApplicationName, string lpCommandLine, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); + private static extern bool CreateProcessWithTokenW(nint hToken, int dwLogonFlags, string lpApplicationName, string lpCommandLine, int dwCreationFlags, nint lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); #endregion } diff --git a/src/EndlessOnlinePatcher/Core/EndlessOnlineDirectory.cs b/src/EoPatcher.Core/Models/EndlessOnlineDirectory.cs similarity index 89% rename from src/EndlessOnlinePatcher/Core/EndlessOnlineDirectory.cs rename to src/EoPatcher.Core/Models/EndlessOnlineDirectory.cs index df9b764..a2c9674 100644 --- a/src/EndlessOnlinePatcher/Core/EndlessOnlineDirectory.cs +++ b/src/EoPatcher.Core/Models/EndlessOnlineDirectory.cs @@ -1,4 +1,5 @@ -namespace EndlessOnlinePatcher.Core; +namespace EoPatcher.Models; + public static class EndlessOnlineDirectory { public static DirectoryInfo Get() diff --git a/src/EndlessOnlinePatcher/Core/Patcher.cs b/src/EoPatcher.Core/Services/FileService.cs similarity index 51% rename from src/EndlessOnlinePatcher/Core/Patcher.cs rename to src/EoPatcher.Core/Services/FileService.cs index 8776d52..952bbb8 100644 --- a/src/EndlessOnlinePatcher/Core/Patcher.cs +++ b/src/EoPatcher.Core/Services/FileService.cs @@ -1,40 +1,25 @@ -using EndlessOnlinePatcher.Extensions; +using EoPatcher.Models; using System.Diagnostics; using System.IO.Compression; -using System.Numerics; using System.Text.RegularExpressions; -namespace EndlessOnlinePatcher.Core; +namespace EoPatcher.Core.Services; -public sealed class Patcher : IPatcher, IDisposable +public interface IFileService { - private string _link { get; } + public Task ExtractPatch(Version version); +} +public class FileService : IFileService +{ private Action _setPatchTextCallback; - public Patcher(string downloadLink, Action setPatchTextCallback) + public FileService(Action setPatchTextCallback) { - _link = downloadLink; _setPatchTextCallback = setPatchTextCallback; } - public async Task Patch(FileVersion version) - { - Clean(); - await DownloadPatch(); - await ApplyPatch(version); - } - - private async Task DownloadPatch() - { - var progress = new Progress(x => _setPatchTextCallback($"Downloading... {x}%")); - using var httpClient = new HttpClient(); - using var fileStream = new FileStream("patch.zip", FileMode.Create, FileAccess.Write); - await httpClient.DownloadAsync(_link, fileStream, progress); - fileStream.Close(); - } - - private async Task ApplyPatch(FileVersion version) + public async Task ExtractPatch(Version version) { var localDirectory = EndlessOnlineDirectory.Get().FullName; var patchFolder = $"patch-{version}/"; @@ -70,28 +55,5 @@ private async Task ApplyPatch(FileVersion version) } private static string GetDirectoryFrom(string filePath) - { - var regex = new Regex("(.*)\\\\"); - return regex.Match(filePath).Value; - } - - private static void Clean() - { - var patchDirectories = Directory.EnumerateDirectories("./").Where(x => x.Contains("patch")); - foreach (var directory in patchDirectories) - { - Directory.Delete(directory, true); - } - - var patchZips = Directory.EnumerateFiles("./", "*.zip"); - foreach (var zip in patchZips) - { - File.Delete(zip); - } - } - - public void Dispose() - { - Clean(); - } + => new Regex("(.*)\\\\").Match(filePath).Value; } \ No newline at end of file diff --git a/src/EoPatcher.Core/Services/HttpService.cs b/src/EoPatcher.Core/Services/HttpService.cs new file mode 100644 index 0000000..ede7024 --- /dev/null +++ b/src/EoPatcher.Core/Services/HttpService.cs @@ -0,0 +1,64 @@ +using EoPatcher.Extensions; +using OneOf; +using OneOf.Types; +using System.Diagnostics; +using System.Text.RegularExpressions; + +namespace EoPatcher.Core.Services; + +public interface IHttpService +{ + public Task>> DownloadLatestPatchAsync(Version version); +} + +public partial class HttpService : IHttpService +{ + private readonly Action _setPatchTextCallback; + + public HttpService(Action setPatchTextCallback) + { + _setPatchTextCallback = setPatchTextCallback; + } + + private async Task>> GetLatestDownloadLinkAsync() + { + using var httpClient = new HttpClient(); + var clientUrl = "https://www.endless-online.com/client/download.html"; + try + { + var endlessHomePage = await httpClient.GetStringAsync(clientUrl); + var regexVersionMatches = new Regex("href=\"(.*EndlessOnline(\\d*)([a-zA-Z])*.zip)\"").Match(endlessHomePage); + var downloadLink = regexVersionMatches.Groups[1].Value; + return downloadLink; + } + catch (Exception ex) + { + Debug.WriteLine($"Could not get the latest download link: {ex.Message}"); + return new Error($"Could not get the latest download link from {clientUrl}"); + } + } + + public async Task>> DownloadLatestPatchAsync(Version version) + { + var link = await GetLatestDownloadLinkAsync(); + if (link.IsT1) + { + return link.AsT1; + } + + try + { + var progress = new Progress(x => _setPatchTextCallback($"Downloading... {x}%")); + using var httpClient = new HttpClient(); + using var fileStream = new FileStream("patch.zip", FileMode.Create, FileAccess.Write); + await httpClient.DownloadAsync(link.AsT0, fileStream, progress); + fileStream.Close(); + return new Success(); + } + catch (Exception e) + { + Debug.WriteLine($"Could not download latest patch from {link.AsT0}: {e.Message}"); + return new Error($"Could not download latest patch from {link.AsT0}"); + } + } +} \ No newline at end of file diff --git a/src/EoPatcher.Core/Services/PatchOrchestrator.cs b/src/EoPatcher.Core/Services/PatchOrchestrator.cs new file mode 100644 index 0000000..e8bea92 --- /dev/null +++ b/src/EoPatcher.Core/Services/PatchOrchestrator.cs @@ -0,0 +1,57 @@ +using EoPatcher.Core.Services; +using EoPatcher.Services.VersionFetchers; +using OneOf; +using OneOf.Types; + +namespace EoPatcher.Services; + +internal interface IPatchOrchestrator +{ + public Task>> Patch(Version version); +} + +public sealed class PatchOrchestrator : IPatchOrchestrator, IDisposable +{ + private IHttpService _httpService; + private IFileService _fileService; + private ILocalVersionRepository _localVersionRepository; + + public PatchOrchestrator(Action setPatchTextCallback) + { + _httpService = new HttpService(setPatchTextCallback); + _fileService = new FileService(setPatchTextCallback); + _localVersionRepository = new LocalVersionRepository(); + } + + public async Task>> Patch(Version version) + { + Clean(); + var downloadResult = await _httpService.DownloadLatestPatchAsync(version); + if (downloadResult.IsT1) + return downloadResult.AsT1; + + await _fileService.ExtractPatch(version); + _localVersionRepository.Save(version); + return new Success(); + } + + public void Dispose() + { + Clean(); + } + + private static void Clean() + { + var patchDirectories = Directory.EnumerateDirectories("./").Where(x => x.Contains("patch")); + foreach (var directory in patchDirectories) + { + Directory.Delete(directory, true); + } + + var patchZips = Directory.EnumerateFiles("./", "*.zip"); + foreach (var zip in patchZips) + { + File.Delete(zip); + } + } +} \ No newline at end of file diff --git a/src/EoPatcher.Core/Services/VersionFetchers/LocalClientVersionRepository.cs b/src/EoPatcher.Core/Services/VersionFetchers/LocalClientVersionRepository.cs new file mode 100644 index 0000000..95c9d2a --- /dev/null +++ b/src/EoPatcher.Core/Services/VersionFetchers/LocalClientVersionRepository.cs @@ -0,0 +1,24 @@ +namespace EoPatcher.Services.VersionFetchers; + +public interface ILocalVersionRepository +{ + Version Get(); + void Save(Version verson); +} + +public class LocalVersionRepository : ILocalVersionRepository +{ + public Version Get() + { + if (File.Exists("version.txt") is false) + return new Version(0, 0, 0); + + var storedVersion = File.ReadAllText("version.txt"); + return new Version(storedVersion); + } + + public void Save(Version version) + { + File.WriteAllText("version.txt", $"{version.Major}.{version.Minor}.{version.Build}"); + } +} diff --git a/src/EoPatcher.Core/Services/VersionFetchers/ServerVersionFetcher.cs b/src/EoPatcher.Core/Services/VersionFetchers/ServerVersionFetcher.cs new file mode 100644 index 0000000..27e104e --- /dev/null +++ b/src/EoPatcher.Core/Services/VersionFetchers/ServerVersionFetcher.cs @@ -0,0 +1,58 @@ +using Moffat.EndlessOnline.SDK.Data; +using OneOf; +using OneOf.Types; +using System.Diagnostics; +using System.Net.Sockets; + +namespace EoPatcher.Services.VersionFetchers; + +public interface IServerVersionFetcher +{ + OneOf> Get(); +} + +public partial class ServerVersionFetcher : IServerVersionFetcher +{ + public OneOf> Get() + { + var serverAddress = "game.endless-online.com"; + var serverPort = 8078; + var client = new TcpClient(); + Debug.WriteLine($"Connecting to {serverAddress}..."); + try + { + client.Connect(serverAddress, serverPort); + Debug.WriteLine("Connected!"); + + byte[] buf = [0xFF, 0xFF, 0x1E, 0x12, 0xFE, 0x1, 0x5, 0x2, 0x72, 0xB, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30]; + + var sizeBytes = NumberEncoder.EncodeNumber(buf.Length); + + byte[] payload = [sizeBytes[0], sizeBytes[1]]; + payload = payload.Concat(buf).ToArray(); + + Debug.WriteLine("Sending version payload..."); + client.Client.Send(payload); + + sizeBytes = new byte[2]; + var lengthBytes = client.Client.Receive(sizeBytes); + + var size = NumberEncoder.DecodeNumber(sizeBytes); + + buf = new byte[size]; + + client.Client.Receive(buf); + + var major = NumberEncoder.DecodeNumber([buf[3]]); + var minor = NumberEncoder.DecodeNumber([buf[4]]); + var build = NumberEncoder.DecodeNumber([buf[5]]); + + return new Version(major, minor, build); + } + catch (Exception e) + { + Debug.WriteLine($"Exception thrown at connecting to {serverAddress}:{serverPort}: {e.Message}"); + return new Error($"Could not connect to {serverAddress}:{serverPort}"); + } + } +} \ No newline at end of file diff --git a/src/EndlessOnlinePatcherSetup/EndlessOnlinePatcherSetup.vdproj b/src/EoPatcher.Setup/EoPatcher.Setup.vdproj similarity index 99% rename from src/EndlessOnlinePatcherSetup/EndlessOnlinePatcherSetup.vdproj rename to src/EoPatcher.Setup/EoPatcher.Setup.vdproj index a4aeefc..912d4c3 100644 --- a/src/EndlessOnlinePatcherSetup/EndlessOnlinePatcherSetup.vdproj +++ b/src/EoPatcher.Setup/EoPatcher.Setup.vdproj @@ -3,7 +3,7 @@ "VSVersion" = "3:800" "ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" "IsWebType" = "8:FALSE" -"ProjectName" = "8:EndlessOnlinePatcherSetup" +"ProjectName" = "8:EoPatcher.Setup" "LanguageId" = "3:1033" "CodePage" = "3:1252" "UILanguageId" = "3:1033" @@ -210,12 +210,12 @@ "Manufacturer" = "8:Endless Online" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" - "Title" = "8:" + "Title" = "8:Endless Online Patcher Installer" "Subject" = "8:" "ARPCONTACT" = "8:Dan Oak" "Keywords" = "8:" "ARPCOMMENTS" = "8:Patching application for Endless Online" - "ARPURLINFOABOUT" = "8:" + "ARPURLINFOABOUT" = "8:https://github.com/MrDanOak/EndlessOnlinePatcher" "ARPPRODUCTICON" = "8:" "ARPIconIndex" = "3:0" "SearchPath" = "8:" diff --git a/src/EndlessOnlinePatcher.Desktop/EndlessOnlinePatcher.Desktop.csproj b/src/EoPatcher.UI/EoPatcher.UI.csproj similarity index 82% rename from src/EndlessOnlinePatcher.Desktop/EndlessOnlinePatcher.Desktop.csproj rename to src/EoPatcher.UI/EoPatcher.UI.csproj index e527cc0..cdca2b0 100644 --- a/src/EndlessOnlinePatcher.Desktop/EndlessOnlinePatcher.Desktop.csproj +++ b/src/EoPatcher.UI/EoPatcher.UI.csproj @@ -12,10 +12,10 @@ OakTech Endless Online Patcher eo-patcher-icon.png - 0.0.0.5 - 0.0.0.5 + 0.0.0.6 + 0.0.0.6 eopatcher - EndlessOnlinePatcher.Desktop.Program + EoPatcher.UI.Program @@ -23,7 +23,7 @@ - + diff --git a/src/EndlessOnlinePatcher.Desktop/Main.Designer.cs b/src/EoPatcher.UI/Main.Designer.cs similarity index 89% rename from src/EndlessOnlinePatcher.Desktop/Main.Designer.cs rename to src/EoPatcher.UI/Main.Designer.cs index 487e285..ea8b2e7 100644 --- a/src/EndlessOnlinePatcher.Desktop/Main.Designer.cs +++ b/src/EoPatcher.UI/Main.Designer.cs @@ -1,4 +1,4 @@ -namespace EndlessOnlinePatcher.Desktop; +namespace EoPatcher.UI; partial class Main { @@ -28,14 +28,16 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); - label1 = new Label(); + lblTitle = new Label(); lblMessage = new Label(); pbxLogout = new PictureBox(); pbxPatch = new PictureBox(); pbxLaunch = new PictureBox(); pbxExit = new PictureBox(); pbxSkip = new PictureBox(); + lblMessageHover = new ToolTip(components); ((System.ComponentModel.ISupportInitialize)pbxLogout).BeginInit(); ((System.ComponentModel.ISupportInitialize)pbxPatch).BeginInit(); ((System.ComponentModel.ISupportInitialize)pbxLaunch).BeginInit(); @@ -43,19 +45,19 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)pbxSkip).BeginInit(); SuspendLayout(); // - // label1 + // lblTitle // - label1.AutoSize = true; - label1.BackColor = Color.Transparent; - label1.ForeColor = Color.LemonChiffon; - label1.Location = new Point(13, 13); - label1.Name = "label1"; - label1.Size = new Size(127, 15); - label1.TabIndex = 1; - label1.Text = "Endless Online Patcher"; - label1.MouseDown += Main_MouseDown; - label1.MouseMove += Main_MouseMove; - label1.MouseUp += Main_MouseUp; + lblTitle.AutoSize = true; + lblTitle.BackColor = Color.Transparent; + lblTitle.ForeColor = Color.LemonChiffon; + lblTitle.Location = new Point(13, 13); + lblTitle.Name = "lblTitle"; + lblTitle.Size = new Size(127, 15); + lblTitle.TabIndex = 1; + lblTitle.Text = "Endless Online Patcher"; + lblTitle.MouseDown += Main_MouseDown; + lblTitle.MouseMove += Main_MouseMove; + lblTitle.MouseUp += Main_MouseUp; // // lblMessage // @@ -161,7 +163,7 @@ private void InitializeComponent() Controls.Add(pbxPatch); Controls.Add(pbxLogout); Controls.Add(lblMessage); - Controls.Add(label1); + Controls.Add(lblTitle); FormBorderStyle = FormBorderStyle.None; Icon = (Icon)resources.GetObject("$this.Icon"); MaximumSize = new Size(290, 125); @@ -184,11 +186,12 @@ private void InitializeComponent() } #endregion - private Label label1; + private Label lblTitle; private Label lblMessage; private PictureBox pbxLogout; private PictureBox pbxPatch; private PictureBox pbxLaunch; private PictureBox pbxExit; private PictureBox pbxSkip; + private ToolTip lblMessageHover; } diff --git a/src/EndlessOnlinePatcher.Desktop/Main.cs b/src/EoPatcher.UI/Main.cs similarity index 56% rename from src/EndlessOnlinePatcher.Desktop/Main.cs rename to src/EoPatcher.UI/Main.cs index 2f559cd..d2eaed3 100644 --- a/src/EndlessOnlinePatcher.Desktop/Main.cs +++ b/src/EoPatcher.UI/Main.cs @@ -1,43 +1,65 @@ -using EndlessOnlinePatcher.Core; -using EndlessOnlinePatcher.Desktop.Properties; +using EoPatcher.Services; +using EoPatcher.Services.VersionFetchers; +using OneOf; +using OneOf.Types; +using System.Diagnostics; using System.Media; +using System.Reflection; -namespace EndlessOnlinePatcher.Desktop; +namespace EoPatcher.UI; public partial class Main : Form { - private FileVersion? _remoteVersion = default; - private FileVersion? _localVersion = default; private bool _patching = false; private bool _dragging; private Point _mouseDownLocation; - private string _downloadLink = ""; - private readonly IClientVersionFetcher _clientVersionFetcher; - private readonly SoundPlayer _sndClickDown = new(Resources.click_down); - private readonly SoundPlayer _sndClickUp = new(Resources.click_up); + private Version _serverVersion; + private readonly SoundPlayer _sndClickDown = new(Properties.Resources.click_down); + private readonly SoundPlayer _sndClickUp = new(Properties.Resources.click_up); + + private readonly ILocalVersionRepository _localVersionRepository = new LocalVersionRepository(); + private readonly IServerVersionFetcher _serverVersionFetcher = new ServerVersionFetcher(); public Main() { InitializeComponent(); - _clientVersionFetcher = new ClientVersionFetcher(); } - private async void Main_Shown(object sender, EventArgs e) - { - _localVersion = _clientVersionFetcher.GetLocal(); - (_downloadLink, _remoteVersion) = await _clientVersionFetcher.GetRemoteAsync(); - if (_localVersion == _remoteVersion) - { - lblMessage.Text = "You are already up to date with the latest version"; - pbxLaunch.Visible = true; - } - else - { - lblMessage.Text = $"A new version of the client is available{Environment.NewLine}(v{_localVersion} -> v{_remoteVersion})"; - pbxPatch.Visible = true; - pbxSkip.Visible = true; - } - pbxExit.Visible = true; + private void Main_Shown(object sender, EventArgs e) + { + string version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion ?? "0.0.0.0"; + lblTitle.Text = $"Endless Online Patcher v{version}"; + + SetPatchText("Getting local version..."); + var localVersion = _localVersionRepository.Get(); + SetPatchText("Getting remote version..."); + + _serverVersionFetcher + .Get() + .Switch(v => + { + _serverVersion = v; + if (localVersion == v) + { + SetPatchText($"You are already up to date with the latest version v{localVersion}"); + pbxLaunch.Visible = true; + } + else + { + SetPatchText($"A new version of the client is available{Environment.NewLine}(v{localVersion} -> v{_serverVersion})"); + pbxPatch.Visible = true; + pbxSkip.Visible = true; + } + pbxExit.Visible = true; + }, + e => + { + SetPatchText(e.Value); + pbxExit.Visible = true; + pbxPatch.Visible = false; + pbxSkip.Visible = false; + pbxLaunch.Visible = true; + }); } private void Main_MouseDown(object sender, MouseEventArgs e) @@ -64,12 +86,12 @@ private void Main_MouseMove(object sender, MouseEventArgs e) private void pbxLogout_MouseEnter(object sender, EventArgs e) { - pbxLogout.Image = Resources.eo_logout_hover; + pbxLogout.Image = Properties.Resources.eo_logout_hover; } private void pbxLogout_MouseLeave(object sender, EventArgs e) { - pbxLogout.Image = Resources.eo_logout; + pbxLogout.Image = Properties.Resources.eo_logout; } private void pbxLogout_Click(object sender, EventArgs e) @@ -80,28 +102,28 @@ private void pbxLogout_Click(object sender, EventArgs e) private void pbxPatch_MouseEnter(object sender, EventArgs e) { if (_patching) return; - pbxPatch.Image = Resources.eo_patch_hover; + pbxPatch.Image = Properties.Resources.eo_patch_hover; } private void pbxPatch_MouseLeave(object sender, EventArgs e) { if (_patching) return; - pbxPatch.Image = Resources.eo_patch; + pbxPatch.Image = Properties.Resources.eo_patch; } private void pbxLaunch_MouseEnter(object sender, EventArgs e) { - pbxLaunch.Image = Resources.eo_launch_hover; + pbxLaunch.Image = Properties.Resources.eo_launch_hover; } private void pbxLaunch_MouseLeave(object sender, EventArgs e) { - pbxLaunch.Image = Resources.eo_launch; + pbxLaunch.Image = Properties.Resources.eo_launch; } private async void pbxLaunch_Click(object sender, EventArgs e) { - await Core.Windows.StartEO(); + await Interop.Windows.StartEO(); Close(); } @@ -112,22 +134,22 @@ private void pbxExit_Click(object sender, EventArgs e) private void pbxExit_MouseEnter(object sender, EventArgs e) { - pbxExit.Image = Resources.eo_exit_hover; + pbxExit.Image = Properties.Resources.eo_exit_hover; } private void pbxExit_MouseLeave(object sender, EventArgs e) { - pbxExit.Image = Resources.eo_exit; + pbxExit.Image = Properties.Resources.eo_exit; } private void pbxSkip_MouseEnter(object sender, EventArgs e) { - pbxSkip.Image = Resources.skip_hover; + pbxSkip.Image = Properties.Resources.skip_hover; } private void pbxSkip_MouseLeave(object sender, EventArgs e) { - pbxSkip.Image = Resources.skip; + pbxSkip.Image = Properties.Resources.skip; } delegate void SetPatchTextCallback(string text); @@ -142,6 +164,7 @@ private void SetPatchText(string text) } lblMessage.Text = text; + lblMessageHover.SetToolTip(lblMessage, text); } private async void pbxPatch_MouseClick(object sender, MouseEventArgs e) @@ -150,11 +173,13 @@ private async void pbxPatch_MouseClick(object sender, MouseEventArgs e) _patching = true; pbxSkip.Visible = false; - pbxPatch.Image = Resources.eo_patching; + pbxPatch.Image = Properties.Resources.eo_patching; - using var patcher = new Patcher(_downloadLink, SetPatchText); + using var patcher = new PatchOrchestrator(SetPatchText); - await patcher.Patch(_remoteVersion!); + var result = await patcher.Patch(_serverVersion); + if (result.IsT1) + SetPatchText(result.AsT1.Value); _patching = false; pbxPatch.Visible = false; diff --git a/src/EndlessOnlinePatcher.Desktop/Main.resx b/src/EoPatcher.UI/Main.resx similarity index 99% rename from src/EndlessOnlinePatcher.Desktop/Main.resx rename to src/EoPatcher.UI/Main.resx index 0220827..8731fdd 100644 --- a/src/EndlessOnlinePatcher.Desktop/Main.resx +++ b/src/EoPatcher.UI/Main.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + diff --git a/src/EndlessOnlinePatcher.Desktop/Program.cs b/src/EoPatcher.UI/Program.cs similarity index 91% rename from src/EndlessOnlinePatcher.Desktop/Program.cs rename to src/EoPatcher.UI/Program.cs index f78346c..aa2d763 100644 --- a/src/EndlessOnlinePatcher.Desktop/Program.cs +++ b/src/EoPatcher.UI/Program.cs @@ -1,4 +1,4 @@ -namespace EndlessOnlinePatcher.Desktop; +namespace EoPatcher.UI; internal static class Program { diff --git a/src/EndlessOnlinePatcher.Desktop/Properties/PublishProfiles/FrameworkDependant.pubxml b/src/EoPatcher.UI/Properties/PublishProfiles/FrameworkDependant.pubxml similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Properties/PublishProfiles/FrameworkDependant.pubxml rename to src/EoPatcher.UI/Properties/PublishProfiles/FrameworkDependant.pubxml diff --git a/src/EndlessOnlinePatcher.Desktop/Properties/PublishProfiles/SelfContained.pubxml b/src/EoPatcher.UI/Properties/PublishProfiles/SelfContained.pubxml similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Properties/PublishProfiles/SelfContained.pubxml rename to src/EoPatcher.UI/Properties/PublishProfiles/SelfContained.pubxml diff --git a/src/EndlessOnlinePatcher.Desktop/Properties/Resources.Designer.cs b/src/EoPatcher.UI/Properties/Resources.Designer.cs similarity index 97% rename from src/EndlessOnlinePatcher.Desktop/Properties/Resources.Designer.cs rename to src/EoPatcher.UI/Properties/Resources.Designer.cs index 7cce6ca..954d71d 100644 --- a/src/EndlessOnlinePatcher.Desktop/Properties/Resources.Designer.cs +++ b/src/EoPatcher.UI/Properties/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace EndlessOnlinePatcher.Desktop.Properties { +namespace EoPatcher.UI.Properties { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EndlessOnlinePatcher.Desktop.Properties.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EoPatcher.UI.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/EndlessOnlinePatcher.Desktop/Properties/Resources.resx b/src/EoPatcher.UI/Properties/Resources.resx similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Properties/Resources.resx rename to src/EoPatcher.UI/Properties/Resources.resx diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-blank.png b/src/EoPatcher.UI/Resources/eo-blank.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-blank.png rename to src/EoPatcher.UI/Resources/eo-blank.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-exit-hover.png b/src/EoPatcher.UI/Resources/eo-exit-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-exit-hover.png rename to src/EoPatcher.UI/Resources/eo-exit-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-exit.png b/src/EoPatcher.UI/Resources/eo-exit.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-exit.png rename to src/EoPatcher.UI/Resources/eo-exit.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-launch-hover.png b/src/EoPatcher.UI/Resources/eo-launch-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-launch-hover.png rename to src/EoPatcher.UI/Resources/eo-launch-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-launch.png b/src/EoPatcher.UI/Resources/eo-launch.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-launch.png rename to src/EoPatcher.UI/Resources/eo-launch.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-logout-hover.png b/src/EoPatcher.UI/Resources/eo-logout-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-logout-hover.png rename to src/EoPatcher.UI/Resources/eo-logout-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-logout.png b/src/EoPatcher.UI/Resources/eo-logout.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-logout.png rename to src/EoPatcher.UI/Resources/eo-logout.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-ok-hover.png b/src/EoPatcher.UI/Resources/eo-ok-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-ok-hover.png rename to src/EoPatcher.UI/Resources/eo-ok-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-ok.png b/src/EoPatcher.UI/Resources/eo-ok.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-ok.png rename to src/EoPatcher.UI/Resources/eo-ok.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-patch-hover.png b/src/EoPatcher.UI/Resources/eo-patch-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-patch-hover.png rename to src/EoPatcher.UI/Resources/eo-patch-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-patch.png b/src/EoPatcher.UI/Resources/eo-patch.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-patch.png rename to src/EoPatcher.UI/Resources/eo-patch.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-patching.png b/src/EoPatcher.UI/Resources/eo-patching.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-patching.png rename to src/EoPatcher.UI/Resources/eo-patching.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/eo-popup.png b/src/EoPatcher.UI/Resources/eo-popup.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/eo-popup.png rename to src/EoPatcher.UI/Resources/eo-popup.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/sfx002.wav b/src/EoPatcher.UI/Resources/sfx002.wav similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/sfx002.wav rename to src/EoPatcher.UI/Resources/sfx002.wav diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/sfx003.wav b/src/EoPatcher.UI/Resources/sfx003.wav similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/sfx003.wav rename to src/EoPatcher.UI/Resources/sfx003.wav diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/skip-hover.png b/src/EoPatcher.UI/Resources/skip-hover.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/skip-hover.png rename to src/EoPatcher.UI/Resources/skip-hover.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/skip.bmp b/src/EoPatcher.UI/Resources/skip.bmp similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/skip.bmp rename to src/EoPatcher.UI/Resources/skip.bmp diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/skip.png b/src/EoPatcher.UI/Resources/skip.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/skip.png rename to src/EoPatcher.UI/Resources/skip.png diff --git a/src/EndlessOnlinePatcher.Desktop/Resources/text-window.png b/src/EoPatcher.UI/Resources/text-window.png similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/Resources/text-window.png rename to src/EoPatcher.UI/Resources/text-window.png diff --git a/src/EndlessOnlinePatcher.Desktop/app.manifest b/src/EoPatcher.UI/app.manifest similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/app.manifest rename to src/EoPatcher.UI/app.manifest diff --git a/src/EndlessOnlinePatcher.Desktop/eo-patcher-icon.ico b/src/EoPatcher.UI/eo-patcher-icon.ico similarity index 100% rename from src/EndlessOnlinePatcher.Desktop/eo-patcher-icon.ico rename to src/EoPatcher.UI/eo-patcher-icon.ico diff --git a/src/EoPatcher.sln b/src/EoPatcher.sln new file mode 100644 index 0000000..451104a --- /dev/null +++ b/src/EoPatcher.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34322.80 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EoPatcher.Core", "EoPatcher.Core\EoPatcher.Core.csproj", "{AC9170EF-8400-4C14-92D1-825834A0B5F4}" +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "EoPatcher.Setup", "EoPatcher.Setup\EoPatcher.Setup.vdproj", "{6628B546-FE0D-449F-A172-71B197D16212}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EoPatcher.UI", "EoPatcher.UI\EoPatcher.UI.csproj", "{1A5F4910-5F89-42EC-B747-998778A6BAEB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC9170EF-8400-4C14-92D1-825834A0B5F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC9170EF-8400-4C14-92D1-825834A0B5F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC9170EF-8400-4C14-92D1-825834A0B5F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC9170EF-8400-4C14-92D1-825834A0B5F4}.Release|Any CPU.Build.0 = Release|Any CPU + {6628B546-FE0D-449F-A172-71B197D16212}.Debug|Any CPU.ActiveCfg = Debug + {6628B546-FE0D-449F-A172-71B197D16212}.Debug|Any CPU.Build.0 = Debug + {6628B546-FE0D-449F-A172-71B197D16212}.Release|Any CPU.ActiveCfg = Release + {6628B546-FE0D-449F-A172-71B197D16212}.Release|Any CPU.Build.0 = Release + {1A5F4910-5F89-42EC-B747-998778A6BAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A5F4910-5F89-42EC-B747-998778A6BAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A5F4910-5F89-42EC-B747-998778A6BAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A5F4910-5F89-42EC-B747-998778A6BAEB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F92BCF5F-2E31-4B5C-BD00-D8F00E87F8AC} + EndGlobalSection +EndGlobal