From f30b7e1e4d4e7c7fb0b524e004fedef436f22301 Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Sat, 6 Jan 2024 00:58:27 +0600 Subject: [PATCH] moved manifests code to this solution --- minecraft-launcher-client/Launcher.cs | 106 ++++++++----------------- minecraft-launcher-client/Network.cs | 76 ++++++++++++++++++ minecraft-launcher-server/Manifests.cs | 69 ++++++++++++++++ minecraft-launcher-server/Server.cs | 29 +------ 4 files changed, 182 insertions(+), 98 deletions(-) create mode 100644 minecraft-launcher-client/Network.cs create mode 100644 minecraft-launcher-server/Manifests.cs diff --git a/minecraft-launcher-client/Launcher.cs b/minecraft-launcher-client/Launcher.cs index 87ff070..47ee2f3 100644 --- a/minecraft-launcher-client/Launcher.cs +++ b/minecraft-launcher-client/Launcher.cs @@ -2,11 +2,8 @@ using System.Diagnostics; using System.Dynamic; using System.Linq; -using System.Net; -using System.Net.Sockets; using System.Security.Cryptography; using System.Text; -using System.Threading; using DTLib.Console; using DTLib.Dtsod; using DTLib.Extensions; @@ -15,20 +12,18 @@ using DTLib.Network; using DTLib.Filesystem; using Directory = DTLib.Filesystem.Directory; using File = DTLib.Filesystem.File; - +using static launcher_client.Network; namespace launcher_client; internal static partial class Launcher { private static FileLogger _fileLogger = new("launcher-logs", "launcher-client"); - private static ILogger logger = new CompositeLogger( + public static ILogger Logger = new CompositeLogger( _fileLogger, new ConsoleLogger()); - private static Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + public static LauncherConfig Config = null!; public static bool debug, offline, updated; - private static FSP FSP = new(mainSocket); private static dynamic tabs = new ExpandoObject(); - private static LauncherConfig config = null!; private static void Main(string[] args) { @@ -46,12 +41,12 @@ internal static partial class Launcher #endif if (args.Contains("offline")) offline = true; if (args.Contains("updated")) updated = true; - config = !File.Exists(LauncherConfig.ConfigFilePath) + Config = !File.Exists(LauncherConfig.ConfigFilePath) ? LauncherConfig.CreateDefault() : LauncherConfig.LoadFromFile(); - logger.DebugLogEnabled = debug; - logger.LogInfo("Main", "launcher is starting"); + Logger.DebugLogEnabled = debug; + Logger.LogInfo("Main", "launcher is starting"); if(File.Exists("minecraft-launcher.exe_old")) File.Delete("minecraft-launcher.exe_old"); @@ -61,8 +56,8 @@ internal static partial class Launcher { ConnectToLauncherServer(); mainSocket.SendPackage("requesting launcher update"); - FSP.DownloadFile("minecraft-launcher.exe_new"); - logger.LogInfo("Main", "minecraft-launcher.exe_new downloaded"); + Fsp.DownloadFile("minecraft-launcher.exe_new"); + Logger.LogInfo("Main", "minecraft-launcher.exe_new downloaded"); System.IO.File.Move("minecraft-launcher.exe", "minecraft-launcher.exe_old"); Process.Start("cmd","/c " + "move minecraft-launcher.exe_new minecraft-launcher.exe && " + @@ -77,10 +72,10 @@ internal static partial class Launcher tabs.Log = ""; tabs.Current = ""; string username = ""; - if (!config.Username.IsNullOrEmpty()) + if (!Config.Username.IsNullOrEmpty()) { - tabs.Login = tabs.Login.Remove(833, config.Username.Length).Insert(833, config.Username); - username = config.Username; + tabs.Login = tabs.Login.Remove(833, Config.Username.Length).Insert(833, Config.Username); + username = Config.Username; } RenderTab(tabs.Login); @@ -110,8 +105,8 @@ internal static partial class Launcher RenderTab(tabs.Login); if (_username.Length < 5) throw new Exception("username length should be > 4 and < 17"); - config.Username = _username; - config.Save(); + Config.Username = _username; + Config.Save(); username = _username; tabs.Login = tabs.Login.Remove(833, _username.Length).Insert(833, _username); RenderTab(tabs.Login); @@ -128,29 +123,30 @@ internal static partial class Launcher { ConnectToLauncherServer(); //обновление файлов клиента - logger.LogInfo("Main", "updating client..."); - FSP.DownloadByManifest("download_if_not_exist", Directory.GetCurrent()); - FSP.DownloadByManifest("sync_always", Directory.GetCurrent(), true); - foreach (string dir in new DtsodV23(FSP - .DownloadFileToMemory(Path.Concat("sync_and_remove","dirlist.dtsod")) - .BytesToString())["dirs"]) - FSP.DownloadByManifest(Path.Concat("sync_and_remove", dir), - Directory.GetCurrent() + '\\' + dir, true, true); - logger.LogInfo("Main", "client updated"); + Logger.LogInfo("Main", "updating client..."); + DownloadByManifest("download_if_not_exist", Directory.GetCurrent()); + DownloadByManifest("sync_always", Directory.GetCurrent(), true); + var dirlistDtsod = new DtsodV23(Fsp + .DownloadFileToMemory(Path.Concat("sync_and_remove","dirlist.dtsod")) + .BytesToString()); + foreach (string dir in dirlistDtsod["dirs"]) + DownloadByManifest(Path.Concat("sync_and_remove", dir), + Path.Concat(Directory.GetCurrent(), dir), true, true); + Logger.LogInfo("Main", "client updated"); } // запуск майнкрафта - logger.LogInfo("Main", "launching minecraft"); - string gameOptions = ConstructGameLaunchArgs(config.Username, - NameUUIDFromString("OfflinePlayer:" + config.Username), - config.GameMemory, - config.GameWindowWidth, - config.GameWindowHeight, + Logger.LogInfo("Main", "launching minecraft"); + string gameOptions = ConstructGameLaunchArgs(Config.Username, + NameUUIDFromString("OfflinePlayer:" + Config.Username), + Config.GameMemory, + Config.GameWindowWidth, + Config.GameWindowHeight, Directory.GetCurrent()); - logger.LogDebug("LaunchGame", gameOptions); - var gameProcess = Process.Start(config.JavaPath.Str, gameOptions); + Logger.LogDebug("LaunchGame", gameOptions); + var gameProcess = Process.Start(Config.JavaPath.Str, gameOptions); gameProcess.WaitForExit(); - logger.LogInfo("Main", "minecraft closed"); + Logger.LogInfo("Main", "minecraft closed"); } break; case ConsoleKey.F2: @@ -180,51 +176,17 @@ internal static partial class Launcher } catch (Exception ex) { - logger.LogError("Main", ex); + Logger.LogError("Main", ex); } } catch (Exception ex) { - logger.LogError("Main", ex); + Logger.LogError("Main", ex); ColoredConsole.Write("gray", "press any key to close..."); Console.ReadKey(); } } - // подключение серверу - private static void ConnectToLauncherServer() - { - if (mainSocket.Connected) - { - logger.LogInfo(nameof(ConnectToLauncherServer), "socket is connected already. disconnecting..."); - mainSocket.Shutdown(SocketShutdown.Both); - mainSocket.Close(); - mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - FSP = new FSP(mainSocket); - } - - while (true) - try - { - logger.LogInfo(nameof(ConnectToLauncherServer), $"connecting to server {config.ServerAddress}:{config.ServerPort}"); - var ip = Dns.GetHostAddresses(config.ServerAddress)[0]; - mainSocket.Connect(new IPEndPoint(ip, config.ServerPort)); - logger.LogInfo(nameof(ConnectToLauncherServer), $"connected to server {ip}"); - break; - } - catch (SocketException ex) - { - logger.LogError(nameof(ConnectToLauncherServer), ex); - Thread.Sleep(2000); - } - - mainSocket.ReceiveTimeout = 2500; - mainSocket.SendTimeout = 2500; - mainSocket.GetAnswer("requesting user name"); - mainSocket.SendPackage("minecraft-launcher"); - mainSocket.GetAnswer("minecraft-launcher OK"); - } - private static void RenderTab(string tab, ushort bufferHeight = 30) { tabs.Current = tab; diff --git a/minecraft-launcher-client/Network.cs b/minecraft-launcher-client/Network.cs new file mode 100644 index 0000000..55a15b7 --- /dev/null +++ b/minecraft-launcher-client/Network.cs @@ -0,0 +1,76 @@ +using System.Net; +using System.Net.Sockets; +using System.Threading; +using DTLib; +using DTLib.Dtsod; +using DTLib.Extensions; +using DTLib.Filesystem; +using DTLib.Logging; +using DTLib.Network; +using static launcher_client.Launcher; + +namespace launcher_client; + +public class Network +{ + public static Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + public static FSP Fsp = new(mainSocket); + + // подключение серверу + public static void ConnectToLauncherServer() + { + if (mainSocket.Connected) + { + Logger.LogInfo(nameof(ConnectToLauncherServer), "socket is connected already. disconnecting..."); + mainSocket.Shutdown(SocketShutdown.Both); + mainSocket.Close(); + mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + Fsp = new(mainSocket); + } + + while (true) + try + { + Logger.LogInfo(nameof(ConnectToLauncherServer), $"connecting to server {Config.ServerAddress}:{Config.ServerPort}"); + var ip = Dns.GetHostAddresses(Config.ServerAddress)[0]; + mainSocket.Connect(new IPEndPoint(ip, Config.ServerPort)); + Logger.LogInfo(nameof(ConnectToLauncherServer), $"connected to server {ip}"); + break; + } + catch (SocketException ex) + { + Logger.LogError(nameof(ConnectToLauncherServer), ex); + Thread.Sleep(2000); + } + + mainSocket.ReceiveTimeout = 2500; + mainSocket.SendTimeout = 2500; + mainSocket.GetAnswer("requesting user name"); + mainSocket.SendPackage("minecraft-launcher"); + mainSocket.GetAnswer("minecraft-launcher OK"); + } + + public static void DownloadByManifest(IOPath dirOnServer, IOPath dirOnClient, bool overwrite = false, bool delete_excess = false) + { + var manifestPath = Path.Concat(dirOnServer, "manifest.dtsod"); + Logger.LogDebug(nameof(DownloadByManifest), manifestPath); + string manifestContent = Fsp.DownloadFileToMemory(manifestPath).BytesToString(); + var manifest = new DtsodV23(manifestContent); + var hasher = new Hasher(); + foreach (var fileOnServerData in manifest) + { + IOPath fileOnClient = Path.Concat(dirOnClient, fileOnServerData.Key); + if (!File.Exists(fileOnClient) || (overwrite && hasher.HashFile(fileOnClient).HashToString() != fileOnServerData.Value)) + Fsp.DownloadFile(Path.Concat(dirOnServer, fileOnServerData.Key), fileOnClient); + } + // удаление лишних файлов + if (delete_excess) + { + foreach (var file in Directory.GetAllFiles(dirOnClient)) + { + if (!manifest.ContainsKey(file.RemoveBase(dirOnClient).Str.Replace('\\','/'))) + File.Delete(file); + } + } + } +} \ No newline at end of file diff --git a/minecraft-launcher-server/Manifests.cs b/minecraft-launcher-server/Manifests.cs new file mode 100644 index 0000000..afef8af --- /dev/null +++ b/minecraft-launcher-server/Manifests.cs @@ -0,0 +1,69 @@ +using System.Linq; +using System.Text; +using DTLib; +using DTLib.Extensions; +using DTLib.Filesystem; +using static launcher_server.Server; + +namespace launcher_server; + +public static class Manifests +{ + static object manifestLocker = new(); + + public static void CreateManifest(IOPath dir) + { + if(!Directory.Exists(dir)) + { + Directory.Create(dir); + return; + } + + StringBuilder manifestBuilder = new(); + Hasher hasher = new(); + var manifestPath = Path.Concat(dir, "manifest.dtsod"); + if (Directory.GetFiles(dir).Contains(manifestPath)) + File.Delete(manifestPath); + foreach (var _file in Directory.GetAllFiles(dir)) + { + var file = _file.Remove(0, dir.Length); + manifestBuilder.Append(file); + manifestBuilder.Append(": \""); + byte[] hash = hasher.HashFile(Path.Concat(dir, file)); + manifestBuilder.Append(hash.HashToString()); + manifestBuilder.Append("\";\n"); + } + File.WriteAllText(manifestPath, manifestBuilder.ToString().Replace('\\','/')); + } + + public static void CreateAllManifests() + { + lock (manifestLocker) + { + var sync_and_remove_dir = Path.Concat(shared_dir, "sync_and_remove"); + CreateManifest(Path.Concat(shared_dir, "download_if_not_exist")); + CreateManifest(Path.Concat(shared_dir, "sync_always")); + if (!Directory.Exists(sync_and_remove_dir)) + Directory.Create(sync_and_remove_dir); + else foreach (var dir in Directory.GetDirectories(sync_and_remove_dir)) + CreateManifest(dir); + StringBuilder dirlist_content_builder = new("dirs: [\n"); + + var dirs = Directory.GetDirectories(sync_and_remove_dir); + for (var i = 0; i < dirs.Length-1; i++) + { + dirlist_content_builder + .Append("\t\"") + .Append(dirs[i].RemoveBase(sync_and_remove_dir).Str.Replace('\\','/')) + .Append("\",\n"); + } + dirlist_content_builder + .Append("\t\"") + .Append(dirs[dirs.Length-1].RemoveBase(sync_and_remove_dir).Str.Replace('\\','/')) + .Append("\"\n"); + + dirlist_content_builder.Append("];"); + File.WriteAllText(Path.Concat(sync_and_remove_dir, "dirlist.dtsod"), dirlist_content_builder.ToString()); + } + } +} \ No newline at end of file diff --git a/minecraft-launcher-server/Server.cs b/minecraft-launcher-server/Server.cs index cfda015..83f047d 100644 --- a/minecraft-launcher-server/Server.cs +++ b/minecraft-launcher-server/Server.cs @@ -18,9 +18,8 @@ static class Server new ConsoleLogger()); static readonly Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); static DtsodV23 config = null!; - private static readonly IOPath shared_dir = "public"; + public static readonly IOPath shared_dir = "public"; - static object manifestLocker = new(); static void Main(string[] args) { @@ -37,7 +36,7 @@ static class Server logger.LogInfo("Main", $"port: {config["local_port"]}"); mainSocket.Bind(new IPEndPoint(IPAddress.Parse(config["local_ip"]), config["local_port"])); mainSocket.Listen(1000); - CreateManifests(); + Manifests.CreateAllManifests(); logger.LogInfo("Main", "server started succesfully"); // запуск отдельного потока для каждого юзера logger.LogInfo("Main", "waiting for users"); @@ -115,27 +114,5 @@ static class Server } } - static void CreateManifests() - { - lock (manifestLocker) - { - var sync_and_remove_dir = Path.Concat(shared_dir, "sync_and_remove"); - FSP.CreateManifest(Path.Concat(shared_dir, "download_if_not_exist")); - FSP.CreateManifest(Path.Concat(shared_dir, "sync_always")); - if (!Directory.Exists(sync_and_remove_dir)) - Directory.Create(sync_and_remove_dir); - else foreach (var dir in Directory.GetDirectories(sync_and_remove_dir)) - FSP.CreateManifest(dir); - string dirlist_content = "dirs: [ ];"; - if(Directory.GetDirectories(sync_and_remove_dir).Length > 0) - { - dirlist_content = "dirs: [\"" - + Directory.GetDirectories(sync_and_remove_dir) - .MergeToString("\", \"") - .Replace(sync_and_remove_dir.Str, "") - + "\"];"; - } - File.WriteAllText(Path.Concat(sync_and_remove_dir, "dirlist.dtsod"), dirlist_content); - } - } + } \ No newline at end of file