From 9da952ece37e85ec8afab63365b3378a85e5322b Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Sat, 6 Jan 2024 19:43:51 +0600 Subject: [PATCH] added project files --- .gitignore | 22 ++ .../Launcher.LaunchGame.cs | 97 +++++++ minecraft-launcher-client/Launcher.cs | 254 ++++++++++++++++++ minecraft-launcher-client/LauncherConfig.cs | 56 ++++ minecraft-launcher-client/Network.cs | 91 +++++++ minecraft-launcher-client/gui/exit.gui | 29 ++ minecraft-launcher-client/gui/login.gui | 29 ++ minecraft-launcher-client/gui/settings.gui | 29 ++ .../gui/test_label.colormap | 0 .../gui/test_label.textmap | 3 + minecraft-launcher-client/gui/window.dtsod | 16 ++ .../launcher-client.csproj | 20 ++ minecraft-launcher-client/launcher.ico | Bin 0 -> 38078 bytes minecraft-launcher-client/publish.sh | 10 + minecraft-launcher-server/Manifests.cs | 69 +++++ minecraft-launcher-server/Server.cs | 118 ++++++++ .../launcher-server.csproj | 16 ++ minecraft-launcher-server/launcher.ico | Bin 0 -> 38078 bytes .../minecraft-launcher-server.dtsod.default | 2 + .../minecraft-launcher-server.service | 11 + minecraft-launcher-server/publish.sh | 10 + minecraft-launcher.sln | 31 +++ 22 files changed, 913 insertions(+) create mode 100644 .gitignore create mode 100644 minecraft-launcher-client/Launcher.LaunchGame.cs create mode 100644 minecraft-launcher-client/Launcher.cs create mode 100644 minecraft-launcher-client/LauncherConfig.cs create mode 100644 minecraft-launcher-client/Network.cs create mode 100644 minecraft-launcher-client/gui/exit.gui create mode 100644 minecraft-launcher-client/gui/login.gui create mode 100644 minecraft-launcher-client/gui/settings.gui create mode 100644 minecraft-launcher-client/gui/test_label.colormap create mode 100644 minecraft-launcher-client/gui/test_label.textmap create mode 100644 minecraft-launcher-client/gui/window.dtsod create mode 100644 minecraft-launcher-client/launcher-client.csproj create mode 100644 minecraft-launcher-client/launcher.ico create mode 100644 minecraft-launcher-client/publish.sh create mode 100644 minecraft-launcher-server/Manifests.cs create mode 100644 minecraft-launcher-server/Server.cs create mode 100644 minecraft-launcher-server/launcher-server.csproj create mode 100644 minecraft-launcher-server/launcher.ico create mode 100644 minecraft-launcher-server/minecraft-launcher-server.dtsod.default create mode 100644 minecraft-launcher-server/minecraft-launcher-server.service create mode 100644 minecraft-launcher-server/publish.sh create mode 100644 minecraft-launcher.sln diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62faaac --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Build results +[Bb]in/ +.bin/ +[Dd]ebug/ +[Rr]elease/ +[Rr]eleases/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ +[Pp]ublish/ + +# IDE files +.vs/ +.vscode/ +.vshistory/ +.idea/ +.editorconfig +*.user + +#backups +.old*/ \ No newline at end of file diff --git a/minecraft-launcher-client/Launcher.LaunchGame.cs b/minecraft-launcher-client/Launcher.LaunchGame.cs new file mode 100644 index 0000000..9f8243b --- /dev/null +++ b/minecraft-launcher-client/Launcher.LaunchGame.cs @@ -0,0 +1,97 @@ +namespace launcher_client; + +internal static partial class Launcher +{ + static string ConstructGameLaunchArgs(string username, string uuid, int maxmemory, int width, int height, + string gameDir) + => "-XX:+UnlockExperimentalVMOptions " + + "-XX:+UseG1GC " + + "-XX:G1NewSizePercent=20 " + + "-XX:G1ReservePercent=20 " + + "-XX:MaxGCPauseMillis=50 " + + "-XX:G1HeapRegionSize=32M " + + "-XX:+DisableExplicitGC " + + "-XX:+AlwaysPreTouch " + + "-XX:+ParallelRefProcEnabled " + + "-Xms512M " + + $"-Xmx{maxmemory}M " + + "-Dfile.encoding=UTF-8 " + + "-Dfml.ignoreInvalidMinecraftCertificates=true " + + "-Dfml.ignorePatchDiscrepancies=true " + + "-Djava.net.useSystemProxies=true " + + "-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump " + + "\"-Dos.name=Windows 10\" " + + "-Dos.version=10.0 " + + @"-Djava.library.path=versions\1.12.2-forge-14.23.5.2860\natives " + + "-Dminecraft.launcher.brand=java-minecraft-launcher " + + "-Dminecraft.launcher.version=1.6.84-j " + + @"-Dminecraft.client.jar=versions\1.12.2-forge-14.23.5.2860\1.12.2-forge-14.23.5.2860.jar " + + "-cp " + + @"libraries\com\turikhay\ca-fixer\1.0\ca-fixer-1.0.jar;" + + @"libraries\net\minecraftforge\forge\1.12.2-14.23.5.2860\forge-1.12.2-14.23.5.2860.jar;" + + @"libraries\org\ow2\asm\asm-debug-all\5.2\asm-debug-all-5.2.jar;" + + @"libraries\net\minecraft\launchwrapper\1.12\launchwrapper-1.12.jar;" + + @"libraries\org\jline\jline\3.5.1\jline-3.5.1.jar;" + + @"libraries\com\typesafe\akka\akka-actor_2.11\2.3.3\akka-actor_2.11-2.3.3.jar;" + + @"libraries\com\typesafe\config\1.2.1\config-1.2.1.jar;" + + @"libraries\org\scala-lang\scala-actors-migration_2.11\1.1.0\scala-actors-migration_2.11-1.1.0.jar;" + + @"libraries\org\scala-lang\scala-compiler\2.11.1\scala-compiler-2.11.1.jar;" + + @"libraries\org\scala-lang\plugins\scala-continuations-library_2.11\1.0.2_mc\scala-continuations-library_2.11-1.0.2_mc.jar;" + + @"libraries\org\scala-lang\plugins\scala-continuations-plugin_2.11.1\1.0.2_mc\scala-continuations-plugin_2.11.1-1.0.2_mc.jar;" + + @"libraries\org\scala-lang\scala-library\2.11.1\scala-library-2.11.1.jar;" + + @"libraries\org\scala-lang\scala-parser-combinators_2.11\1.0.1\scala-parser-combinators_2.11-1.0.1.jar;" + + @"libraries\org\scala-lang\scala-reflect\2.11.1\scala-reflect-2.11.1.jar;" + + @"libraries\org\scala-lang\scala-swing_2.11\1.0.1\scala-swing_2.11-1.0.1.jar;" + + @"libraries\org\scala-lang\scala-xml_2.11\1.0.2\scala-xml_2.11-1.0.2.jar;" + + @"libraries\lzma\lzma\0.0.1\lzma-0.0.1.jar;" + + @"libraries\java3d\vecmath\1.5.2\vecmath-1.5.2.jar;" + + @"libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;" + + @"libraries\org\apache\maven\maven-artifact\3.5.3\maven-artifact-3.5.3.jar;" + + @"libraries\net\sf\jopt-simple\jopt-simple\5.0.3\jopt-simple-5.0.3.jar;" + + @"libraries\org\apache\logging\log4j\log4j-api\2.15.0\log4j-api-2.15.0.jar;" + + @"libraries\org\apache\logging\log4j\log4j-core\2.15.0\log4j-core-2.15.0.jar;" + + @"libraries\ru\tlauncher\patchy\1.0.0\patchy-1.0.0.jar;" + + @"libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar;" + + @"libraries\net\java\dev\jna\jna\4.4.0\jna-4.4.0.jar;" + + @"libraries\net\java\dev\jna\platform\3.4.0\platform-3.4.0.jar;" + + @"libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;" + + @"libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;" + + @"libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;" + + @"libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;" + + @"libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;" + + @"libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;" + + @"libraries\io\netty\netty-all\4.1.9.Final\netty-all-4.1.9.Final.jar;" + + @"libraries\com\google\guava\guava\21.0\guava-21.0.jar;" + + @"libraries\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;" + + @"libraries\commons-io\commons-io\2.5\commons-io-2.5.jar;" + + @"libraries\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;" + + @"libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;" + + @"libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;" + + @"libraries\com\google\code\gson\gson\2.8.0\gson-2.8.0.jar;" + + @"libraries\by\ely\authlib\3.11.49.2\authlib-3.11.49.2.jar;" + + @"libraries\com\mojang\realms\1.10.22\realms-1.10.22.jar;" + + @"libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;" + + @"libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;" + + @"libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;" + + @"libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;" + + @"libraries\it\unimi\dsi\fastutil\7.1.0\fastutil-7.1.0.jar;" + + @"libraries\org\apache\logging\log4j\log4j-api\2.8.1\log4j-api-2.8.1.jar;" + + @"libraries\org\apache\logging\log4j\log4j-core\2.8.1\log4j-core-2.8.1.jar;" + + @"libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar;" + + @"libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar;" + + @"libraries\com\mojang\text2speech\1.10.3\text2speech-1.10.3.jar;" + + @"versions\1.12.2-forge-14.23.5.2860\1.12.2-forge-14.23.5.2860.jar " + + "-Xss2M net.minecraft.launchwrapper.Launch " + + $"--username {username} " + + "--version 1.12.2-forge-14.23.5.2860 " + + $"--gameDir {gameDir} " + + "--assetsDir assets " + + "--assetIndex 1.12 " + + $"--uuid {uuid} " + + "--accessToken null " + + "--userType mojang " + + "--tweakClass net.minecraftforge.fml.common.launcher.FMLTweaker " + + "--versionType Forge " + + $"--width {width} " + + $"--height {height}"; +} \ No newline at end of file diff --git a/minecraft-launcher-client/Launcher.cs b/minecraft-launcher-client/Launcher.cs new file mode 100644 index 0000000..b35e571 --- /dev/null +++ b/minecraft-launcher-client/Launcher.cs @@ -0,0 +1,254 @@ +using System; +using System.Diagnostics; +using System.Dynamic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using DTLib.Console; +using DTLib.Extensions; +using DTLib.Logging; +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"); + public static ILogger Logger = new CompositeLogger( + _fileLogger, + new ConsoleLogger()); + public static LauncherConfig Config = null!; + public static bool debug, offline, updated; + private static dynamic tabs = new ExpandoObject(); + + private static void Main(string[] args) + { + try + { + Console.Title = "anarx_2"; + Console.OutputEncoding = Encoding.UTF8; + Console.InputEncoding = Encoding.UTF8; + Console.CursorVisible = false; + +#if DEBUG + debug = true; +#else + if (args.Contains("debug")) debug = true; +#endif + if (args.Contains("offline")) offline = true; + if (args.Contains("updated")) updated = true; + Config = !File.Exists(LauncherConfig.ConfigFilePath) + ? LauncherConfig.CreateDefault() + : LauncherConfig.LoadFromFile(); + + Logger.DebugLogEnabled = debug; + Logger.LogInfo("Main", "launcher is starting"); + + if(File.Exists("minecraft-launcher.exe_old")) + File.Delete("minecraft-launcher.exe_old"); + + // обновление лаунчера + if (!updated && !offline) + { + ConnectToLauncherServer(); + mainSocket.SendPackage("requesting launcher update"); + 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 && " + + "minecraft-launcher.exe updated"); + return; + } + + // если уже обновлён + tabs.Login = EmbeddedResources.ReadText("launcher_client.gui.login.gui"); + tabs.Settings = EmbeddedResources.ReadText("launcher_client.gui.settings.gui"); + tabs.Exit = EmbeddedResources.ReadText("launcher_client.gui.exit.gui"); + tabs.Log = ""; + tabs.Current = ""; + string username = ""; + if (!Config.Username.IsNullOrEmpty()) + { + tabs.Login = tabs.Login.Remove(833, Config.Username.Length).Insert(833, Config.Username); + username = Config.Username; + } + + RenderTab(tabs.Login); + + while (true) try + // ReSharper disable once BadChildStatementIndent + { + var pressedKey = Console.ReadKey(true); // Считывание ввода + switch (pressedKey.Key) + { + case ConsoleKey.F1: + RenderTab(tabs.Login); + break; + case ConsoleKey.N: + if (tabs.Current == tabs.Login) + { + tabs.Login = tabs.Login + .Remove(751, 20).Insert(751, "┏━━━━━━━━━━━━━━━━━━┓") + .Remove(831, 20).Insert(831, "┃ ┃") + .Remove(911, 20).Insert(911, "┗━━━━━━━━━━━━━━━━━━┛"); + RenderTab(tabs.Login); + var _username = ReadString(33, 10, 15); + tabs.Login = tabs.Login + .Remove(751, 20).Insert(751, "┌──────────────────┐") + .Remove(831, 20).Insert(831, "│ │") + .Remove(911, 20).Insert(911, "└──────────────────┘"); + RenderTab(tabs.Login); + if (_username.Length < 5) + throw new Exception("username length should be > 4 and < 17"); + Config.Username = _username; + Config.Save(); + username = _username; + tabs.Login = tabs.Login.Remove(833, _username.Length).Insert(833, _username); + RenderTab(tabs.Login); + } + break; + case ConsoleKey.L: + if (tabs.Current == tabs.Login) + { + RenderTab(tabs.Current); + if (username.Length < 2) throw new Exception("username is too short"); + + // обновление клиента + if (!offline) + { + ConnectToLauncherServer(); + UpdateGame(); + } + + // запуск майнкрафта + 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); + gameProcess.WaitForExit(); + Logger.LogInfo("Main", "minecraft closed"); + } + break; + case ConsoleKey.F2: + tabs.Log = File.ReadAllText(_fileLogger.LogfileName); + RenderTab(tabs.Log, 9999); + break; + case ConsoleKey.F3: + RenderTab(tabs.Settings); + break; + case ConsoleKey.F4: + RenderTab(tabs.Exit); + break; + case ConsoleKey.Enter: + if (tabs.Current == tabs.Exit) + { + Console.Clear(); + // Console.BufferHeight = 9999; + return; + } + break; + case ConsoleKey.F5: + if (tabs.Current == tabs.Log) goto case ConsoleKey.F2; + RenderTab(tabs.Current); + Console.CursorVisible = false; + break; + } + } + catch (Exception ex) + { + Logger.LogError("Main", ex); + } + } + catch (Exception ex) + { + Logger.LogError("Main", ex); + ColoredConsole.Write("gray", "press any key to close..."); + Console.ReadKey(); + } + Console.CursorVisible = true; + } + + private static void RenderTab(string tab, ushort bufferHeight = 30) + { + tabs.Current = tab; + Console.Clear(); + Console.SetWindowSize(80, 30); + // Console.SetBufferSize(80, bufferHeight); + ColoredConsole.Write("w", tab); + } + + private static string ReadString(ushort x, ushort y, ushort maxlength) + { + var output = ""; + tabs.Current = tabs.Current.Remove(y * 80 + x, maxlength).Insert(y * 80 + x, " ".Multiply(maxlength)); + while (true) + { + var pressedKey = Console.ReadKey(false); + switch (pressedKey.Key) + { + case ConsoleKey.Enter: + return output; + case ConsoleKey.Backspace: + if (output.Length > 0) + { + output = output.Remove(output.Length - 1); + RenderTab(tabs.Current); + Console.SetCursorPosition(x, y); + ColoredConsole.Write("c", output); + } + + break; + case ConsoleKey.Escape: + tabs.Current = tabs.Current.Remove(y * 80 + x, maxlength) + .Insert(y * 80 + x, " ".Multiply(maxlength)); + RenderTab(tabs.Current); + return ""; + //case ConsoleKey.Spacebar: + case ConsoleKey.UpArrow: + case ConsoleKey.DownArrow: + case ConsoleKey.LeftArrow: + case ConsoleKey.RightArrow: + break; + default: + if (output.Length <= maxlength) + { + string keyC = pressedKey.KeyChar.ToString(); + string thisChar = pressedKey.Modifiers.HasFlag(ConsoleModifiers.Shift) ? keyC.ToUpper() : keyC; + output += thisChar; + } + + RenderTab(tabs.Current); + Console.SetCursorPosition(x, y); + ColoredConsole.Write("c", output); + break; + } + } + } + + //minecraft player uuid explanation + //https://gist.github.com/CatDany/0e71ca7cd9b42a254e49/ + //java uuid generation in c# + //https://stackoverflow.com/questions/18021808/uuid-interop-with-c-sharp-code + public static string NameUUIDFromString(string input) + => NameUUIDFromBytes(Encoding.UTF8.GetBytes(input)); + + public static string NameUUIDFromBytes(byte[] input) + { + byte[] hash = MD5.HashData(input); + hash[6] &= 0x0f; + hash[6] |= 0x30; + hash[8] &= 0x3f; + hash[8] |= 0x80; + string hex = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); + return hex.Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-"); + } +} \ No newline at end of file diff --git a/minecraft-launcher-client/LauncherConfig.cs b/minecraft-launcher-client/LauncherConfig.cs new file mode 100644 index 0000000..0663817 --- /dev/null +++ b/minecraft-launcher-client/LauncherConfig.cs @@ -0,0 +1,56 @@ +using DTLib.Dtsod; +using DTLib.Filesystem; + +namespace launcher_client; + +public class LauncherConfig +{ + public static IOPath ConfigFilePath = "minecraft-launcher.dtsod"; + + public int GameMemory = 3000; + public int GameWindowHeight = 500; + public int GameWindowWidth = 900; + public IOPath JavaPath = "jre/bin/java.exe"; + public string ServerAddress = "127.0.0.1"; + public int ServerPort = 25000; + public string Username = ""; + + private LauncherConfig(){} + + private LauncherConfig(DtsodV23 dtsod) + { + GameMemory = dtsod["gameMemory"]; + GameWindowHeight = dtsod["gameWindowHeight"]; + GameWindowWidth = dtsod["gameWindowWidth"]; + JavaPath = dtsod["javaPath"]; + ServerAddress = dtsod["serverAddress"]; + ServerPort = dtsod["serverPort"]; + Username = dtsod["username"]; + } + + public static LauncherConfig LoadFromFile() => new(new DtsodV23(File.ReadAllText(ConfigFilePath))); + + public DtsodV23 ToDtsod() => + new() + { + { "gameMemory", GameMemory }, + { "gameWindowHeight", GameWindowHeight }, + { "gameWindowWidth", GameWindowWidth }, + { "javaPath", JavaPath.Str }, + { "serverAddress", ServerAddress }, + { "serverPort", ServerPort }, + { "username", Username }, + }; + + public void Save() + { + File.WriteAllText(ConfigFilePath, ToDtsod().ToString()); + } + + public static LauncherConfig CreateDefault() + { + var c = new LauncherConfig(); + c.Save(); + return c; + } +} \ No newline at end of file diff --git a/minecraft-launcher-client/Network.cs b/minecraft-launcher-client/Network.cs new file mode 100644 index 0000000..8f4d686 --- /dev/null +++ b/minecraft-launcher-client/Network.cs @@ -0,0 +1,91 @@ +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(Network), "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(Network), $"connecting to server {Config.ServerAddress}:{Config.ServerPort}"); + var ip = Dns.GetHostAddresses(Config.ServerAddress)[0]; + mainSocket.Connect(new IPEndPoint(ip, Config.ServerPort)); + Logger.LogInfo(nameof(Network), $"connected to server {ip}"); + break; + } + catch (SocketException ex) + { + Logger.LogError(nameof(Network), 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(Network), 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); + } + } + } + + public static void UpdateGame() + { + //обновление файлов клиента + Logger.LogInfo(nameof(Network), "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(nameof(Network), "client updated"); + } +} \ No newline at end of file diff --git a/minecraft-launcher-client/gui/exit.gui b/minecraft-launcher-client/gui/exit.gui new file mode 100644 index 0000000..d8232ad --- /dev/null +++ b/minecraft-launcher-client/gui/exit.gui @@ -0,0 +1,29 @@ +┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ [F1] login ┃ [F2] log ┃ [F3] settings ┃ [F4] EXIT ┃ [F5] refresh ┃ +┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ +┃ ┃ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ ┃ +┃ ┃ ┃ ┃ ┃ ┃ +┃ ┃ ┃ press [ENTER] to exit ┃ ┃ ┃ +┃ ┃ ┃ ┃ ┃ ┃ +┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┃ ┃ +┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ \ No newline at end of file diff --git a/minecraft-launcher-client/gui/login.gui b/minecraft-launcher-client/gui/login.gui new file mode 100644 index 0000000..6345030 --- /dev/null +++ b/minecraft-launcher-client/gui/login.gui @@ -0,0 +1,29 @@ +┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ [F1] LOGIN ┃ [F2] log ┃ [F3] settings ┃ [F4] exit ┃ [F5] refresh ┃ +┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┌──────────────────┐ ┃ +┃ [N] nickname:│ │ ┃ +┃ └──────────────────┘ ┃ +┃ ┃ +┃ ┏━━━━━━━━━━━━━━━━┓ ┃ +┃ ┃ [L] login ┃ ┃ +┃ ┗━━━━━━━━━━━━━━━━┛ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ \ No newline at end of file diff --git a/minecraft-launcher-client/gui/settings.gui b/minecraft-launcher-client/gui/settings.gui new file mode 100644 index 0000000..90b06e7 --- /dev/null +++ b/minecraft-launcher-client/gui/settings.gui @@ -0,0 +1,29 @@ +┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ [F1] login ┃ [F2] log ┃ [F3] SETTINGS ┃ [F4] exit ┃ [F5] refresh ┃ +┣━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┫ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ я ещё не добавил настройки ┃ +┃ ┃ +┃ приходите позже ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ■ ■ ■ ■ ┃ +┃ ■ ■ ■ ■ ┃ +┃ ■ ■ ■ ■ ■ ■ ■ ┃ +┃ ■ ■ ■ ■ ■ ■ ■ ┃ +┃ ■ ■ ■ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┃ ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ \ No newline at end of file diff --git a/minecraft-launcher-client/gui/test_label.colormap b/minecraft-launcher-client/gui/test_label.colormap new file mode 100644 index 0000000..e69de29 diff --git a/minecraft-launcher-client/gui/test_label.textmap b/minecraft-launcher-client/gui/test_label.textmap new file mode 100644 index 0000000..9d1c046 --- /dev/null +++ b/minecraft-launcher-client/gui/test_label.textmap @@ -0,0 +1,3 @@ +┏━━━━━━━━━┓ +┃ ejejeje ┃ +┗━━━━━━━━━┛ diff --git a/minecraft-launcher-client/gui/window.dtsod b/minecraft-launcher-client/gui/window.dtsod new file mode 100644 index 0000000..6585c34 --- /dev/null +++ b/minecraft-launcher-client/gui/window.dtsod @@ -0,0 +1,16 @@ +window: +{ + type: "container"; + anchor: [0us, 0us]; + width: 90us; + height: 30us; + children: + { + test_label: + { + type: "label"; + anchor: [0us, 0us]; + resdir: "gui"; + }; + }; +}; \ No newline at end of file diff --git a/minecraft-launcher-client/launcher-client.csproj b/minecraft-launcher-client/launcher-client.csproj new file mode 100644 index 0000000..157c210 --- /dev/null +++ b/minecraft-launcher-client/launcher-client.csproj @@ -0,0 +1,20 @@ + + + net8.0 + disable + enable + Exe + launcher_client + minecraft-launcher + launcher.ico + + + + + + + + + + + \ No newline at end of file diff --git a/minecraft-launcher-client/launcher.ico b/minecraft-launcher-client/launcher.ico new file mode 100644 index 0000000000000000000000000000000000000000..9b68a7e4aac098f2736cfa661b27c15bc62a4494 GIT binary patch literal 38078 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 T{`vP$2L8#wKNrN`8H_~ literal 0 HcmV?d00001 diff --git a/minecraft-launcher-client/publish.sh b/minecraft-launcher-client/publish.sh new file mode 100644 index 0000000..e024786 --- /dev/null +++ b/minecraft-launcher-client/publish.sh @@ -0,0 +1,10 @@ +dotnet publish -c release -o bin/publish \ + --self-contained \ + --use-current-runtime \ + -p:PublishSingleFile=true \ + -p:PublishTrimmed=true \ + -p:TrimMode=partial \ + -p:EnableCompressionInSingleFile=true \ + -p:OptimizationPreference=Size \ + -p:InvariantGlobalization=true \ + -p:DebugType=none diff --git a/minecraft-launcher-server/Manifests.cs b/minecraft-launcher-server/Manifests.cs new file mode 100644 index 0000000..47fbfa5 --- /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 fileInDir in Directory.GetAllFiles(dir)) + { + var fileRelative = fileInDir.RemoveBase(dir); + manifestBuilder.Append(fileRelative); + manifestBuilder.Append(": \""); + byte[] hash = hasher.HashFile(Path.Concat(fileInDir)); + 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 new file mode 100644 index 0000000..83f047d --- /dev/null +++ b/minecraft-launcher-server/Server.cs @@ -0,0 +1,118 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using DTLib.Dtsod; +using DTLib.Extensions; +using DTLib.Filesystem; +using DTLib.Logging; +using DTLib.Network; + +namespace launcher_server; + +static class Server +{ + private static ILogger logger = new CompositeLogger( + new FileLogger("logs","launcher-server"), + new ConsoleLogger()); + static readonly Socket mainSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + static DtsodV23 config = null!; + public static readonly IOPath shared_dir = "public"; + + + static void Main(string[] args) + { + try + { + Console.Title = "minecraft_launcher_server"; + Console.InputEncoding = Encoding.Unicode; + Console.OutputEncoding = Encoding.Unicode; + + config = new DtsodV23(File.ReadAllText("minecraft-launcher-server.dtsod")); + + logger.LogInfo("Main", $"local address: {config["local_ip"]}"); + logger.LogInfo("Main", $"public address: {Functions.GetPublicIP()}"); + logger.LogInfo("Main", $"port: {config["local_port"]}"); + mainSocket.Bind(new IPEndPoint(IPAddress.Parse(config["local_ip"]), config["local_port"])); + mainSocket.Listen(1000); + Manifests.CreateAllManifests(); + logger.LogInfo("Main", "server started succesfully"); + // запуск отдельного потока для каждого юзера + logger.LogInfo("Main", "waiting for users"); + while (true) + { + var userSocket = mainSocket.Accept(); + var userThread = new Thread(obj => HandleUser((Socket)obj!)); + userThread.Start(userSocket); + } + } + catch (Exception ex) + { + logger.LogError("Main", ex); + mainSocket.Close(); + } + logger.LogInfo("Main", ""); + } + + // запускается для каждого юзера в отдельном потоке + static void HandleUser(Socket handlerSocket) + { + logger.LogInfo(nameof(HandleUser), "user connecting... "); + try + { + // тут запрос пароля заменён запросом заглушки + handlerSocket.SendPackage("requesting user name"); + string connectionString = handlerSocket.GetPackage().BytesToString(); + FSP fsp = new(handlerSocket); + + // запрос от апдейтера + if (connectionString == "minecraft-launcher") + { + logger.LogInfo(nameof(HandleUser), "incoming connection from minecraft-launcher"); + handlerSocket.SendPackage("minecraft-launcher OK"); + // обработка запросов + while (true) + { + if (handlerSocket.Available >= 2) + { + string request = handlerSocket.GetPackage().BytesToString(); + switch (request) + { + case "requesting launcher update": + logger.LogInfo(nameof(HandleUser), "updater requested launcher update"); + // ReSharper disable once InconsistentlySynchronizedField + fsp.UploadFile(Path.Concat(shared_dir, "minecraft-launcher.exe")); + break; + case "requesting file download": + var file = handlerSocket.GetPackage().BytesToString(); + logger.LogInfo(nameof(HandleUser), $"updater requested file {file}"); + // ReSharper disable once InconsistentlySynchronizedField + fsp.UploadFile(Path.Concat(shared_dir, file)); + break; + default: + throw new Exception("unknown request: " + request); + } + } + else Thread.Sleep(50); + } + } + // неизвестный юзер + + logger.LogWarn(nameof(HandleUser),$"invalid connection string: '{connectionString}'"); + handlerSocket.SendPackage("invalid connection string"); + } + catch (Exception ex) + { + logger.LogWarn(nameof(HandleUser), ex); + } + finally + { + if (handlerSocket.Connected) handlerSocket.Shutdown(SocketShutdown.Both); + handlerSocket.Close(); + logger.LogInfo(nameof(HandleUser), "user disconnected"); + } + } + + +} \ No newline at end of file diff --git a/minecraft-launcher-server/launcher-server.csproj b/minecraft-launcher-server/launcher-server.csproj new file mode 100644 index 0000000..2428d2c --- /dev/null +++ b/minecraft-launcher-server/launcher-server.csproj @@ -0,0 +1,16 @@ + + + net8.0 + disable + enable + Exe + launcher_server + minecraft-launcher-server + launcher.ico + + + + + + + \ No newline at end of file diff --git a/minecraft-launcher-server/launcher.ico b/minecraft-launcher-server/launcher.ico new file mode 100644 index 0000000000000000000000000000000000000000..9b68a7e4aac098f2736cfa661b27c15bc62a4494 GIT binary patch literal 38078 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 T{`vP$2L8#wKNrN`8H_~ literal 0 HcmV?d00001 diff --git a/minecraft-launcher-server/minecraft-launcher-server.dtsod.default b/minecraft-launcher-server/minecraft-launcher-server.dtsod.default new file mode 100644 index 0000000..7ed1467 --- /dev/null +++ b/minecraft-launcher-server/minecraft-launcher-server.dtsod.default @@ -0,0 +1,2 @@ +local_ip: "127.0.0.1"; +local_port: 25000; diff --git a/minecraft-launcher-server/minecraft-launcher-server.service b/minecraft-launcher-server/minecraft-launcher-server.service new file mode 100644 index 0000000..4732bfc --- /dev/null +++ b/minecraft-launcher-server/minecraft-launcher-server.service @@ -0,0 +1,11 @@ +# put this file in /etc/systemd/system/ +[Unit] +Description=minecraft launcher backend in c# + +[Service] +WorkingDirectory=/opt/minecraft-launcher/minecraft-launcher-server/bin/publish +ExecStart=/opt/minecraft-launcher/minecraft-launcher-server/bin/publish/minecraft-launcher-server +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/minecraft-launcher-server/publish.sh b/minecraft-launcher-server/publish.sh new file mode 100644 index 0000000..e024786 --- /dev/null +++ b/minecraft-launcher-server/publish.sh @@ -0,0 +1,10 @@ +dotnet publish -c release -o bin/publish \ + --self-contained \ + --use-current-runtime \ + -p:PublishSingleFile=true \ + -p:PublishTrimmed=true \ + -p:TrimMode=partial \ + -p:EnableCompressionInSingleFile=true \ + -p:OptimizationPreference=Size \ + -p:InvariantGlobalization=true \ + -p:DebugType=none diff --git a/minecraft-launcher.sln b/minecraft-launcher.sln new file mode 100644 index 0000000..2597576 --- /dev/null +++ b/minecraft-launcher.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32104.313 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launcher-client", "minecraft-launcher-client\launcher-client.csproj", "{49ADEFCE-DA46-4229-997C-3D43DD600627}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launcher-server", "minecraft-launcher-server\launcher-server.csproj", "{1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {49ADEFCE-DA46-4229-997C-3D43DD600627}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {49ADEFCE-DA46-4229-997C-3D43DD600627}.Debug|Any CPU.Build.0 = Debug|Any CPU + {49ADEFCE-DA46-4229-997C-3D43DD600627}.Release|Any CPU.ActiveCfg = Release|Any CPU + {49ADEFCE-DA46-4229-997C-3D43DD600627}.Release|Any CPU.Build.0 = Release|Any CPU + {1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DC6892C-5DC8-4C1C-94C1-CE695BD2DBC2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5D358070-7ABE-4BD6-9A87-6A5BE8CB6BC9} + EndGlobalSection +EndGlobal