大家好这里是皇鱼
在这篇文章中,我将教会各位如何启动一个Minecraft。
本文以C#为例,那么开始。
特别感谢:bmclapi源让我的下载速度提升


启动游戏

启动参数

首先,既然叫Minecraft Java版,我们肯定需要获得一个java。
一般情况下,我们需要找到java目录/bin/java.exe这个程序的目录
然后我们需要附加jvm参数:

   -Xmx2G - 最大内存大小,需要带上单位
   -Xmn1G - 最小内存大小,同上
   -XX:+UseG1GC - 开启G1优化
   (下面的我也没了解过,来自wiki)
   -XX:-UseAdaptiveSizePolicy 自动选择年轻代区大小和相应的Survivor区比例。
   -XX:-OmitStackTraceInFastThrow 省略异常栈信息从而快速抛出。

在版本json的arguments.jvm中也会有一些参数,应当附加上

然后我们需要-D参数,格式为-D=

   -Dos.name="Windows 11" -Dos.version=11.0 当前系统名称及版本。
   -Dminecraft.launcher.brand=hyuLauncher -Dminecraft.launcher.version=1.0.0 启动器版本和名称
   -Dlog4j.configurationFile=./.minecraft/versions/1.21/1.21-log4j.xml 游戏日志配置文件 该项下载链接在版本json文件中的logging.client.file.url中
   -Djava.library.path="./.minecraft/versions/1.21/1.21-natives" 当前系统下游戏运行所需的动态链接库。

然后需要-cp,记得1-1的libraries吗,将里面所有的文件的路径拼接进来,以';'隔开,然后结尾加上版本jar

   -cp xxx.jar;xxxx.jar;.minecraft/versions/1.21/1.21.jar

版本jar可以在版本json的downloads项内找到,或者使用bmclapi提供的接口:

   bmclapi2.bangbang93.com/version/版本号(1.21)/client

接下来需要minecraft参数

   net.minecraft.client.main.Main //以此开头,这是mc主类名
   --username O_Huangyu //用户名
   --version 1.21 //游戏版本
   --gameDir .minecraft/versions/1.21 //游戏目录,如果版本隔离则为版本目录
   --assetsDir .minecraft/assets/objects //资源文件路径
   --assetsIndex 17 //资源索引文件版本
   --uuid 00000000-0000-0000-0000-00000000000 //uuid,离线登录就随便写
   --accessToken 12312414 //登录令牌,离线登录随便写
   --userType Legacy //登录类型 离线登录就Legacy
   --versionType HyuLauncher //版本类型 显示在游戏主界面左下角 一般用于写启动器名称
   可选:
   --width //窗口宽度
   --height //窗口高度
   --server //自动连接服务器ip
   --port //自动连接服务器端口
   --xuid //xuid验证,离线登录不需要

会应版本而异,可以参考版本json中的arguments.game:

   [
      "--username",
      "${auth_player_name}",
      "--version",
      "${version_name}",
      "--gameDir",
      "${game_directory}",
      "--assetsDir",
      "${assets_root}",
      "--assetIndex",
      "${assets_index_name}",
      "--uuid",
      "${auth_uuid}",
      "--accessToken",
      "${auth_access_token}",
      "--clientId",
      "${clientid}",
      "--xuid",
      "${auth_xuid}",
      "--userType",
      "${user_type}",
      "--versionType",
      "${version_type}",
   ]

接下来拼接启动参数并运行
C#代码示例:

    static string getClassPath()
    {
        string indexJson = File.ReadAllText(@".\.minecraft\versions\1.21\1.21.json");
        string librariesStr = GetValueFromJson(indexJson, "libraries");
        JsonArray larr = JsonArray.Parse(librariesStr).AsArray();
        string result = "";
        foreach (var lib in larr)
        {
            string libStr = lib.ToJsonString();
            string path = GetValueFromJson(libStr, "downloads.artifact.path");
            if (!(libStr.Contains("linux") || !(libStr.Contains("osx"))))
            { 
                result += @$"{System.IO.Directory.GetCurrentDirectory()}\.minecraft\libraries\{path};";
            }
        }
        result += @$"{System.IO.Directory.GetCurrentDirectory()}\.minecraft\versions\1.21\1.21.jar";
        return result;
    }

    async static Task<string> downloadVersionJarAndLogConfig()
    {
        string indexJson = File.ReadAllText(@".\.minecraft\versions\1.21\1.21.json");
        List<Task> tasks = new List<Task>();
        tasks.Add(DownloadFileAsync(new HttpClient(), GetValueFromJson(indexJson, "logging.client.file.url"), "./.minecraft/versions/1.21/" + GetValueFromJson(indexJson, "logging.client.file.id")));
//        tasks.Add(DownloadFileAsync(new HttpClient(), "https://bmclapi2.bangbang93.com/version/1.21/client", @$"{System.IO.Directory.GetCurrentDirectory()}\.minecraft\versions\1.21\1.21.jar"));
        await Task.WhenAll(tasks);     
        return $"{System.IO.Directory.GetCurrentDirectory()}\\.minecraft\\versions\\1.21\\{GetValueFromJson(indexJson,"logging.client.file.id")}";

    }

    static void launch(string classPath, string logConfig)
    {

        string command = "\"C:\\Users\\Administrator\\AppData\\Roaming\\.minecraft\\runtime\\java-runtime-delta\\bin\\java.exe\" -Xmx2G -XX:+UseG1GC" +
            " -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Dos.name=\"Windows 11\" -Dos.version=11.0 -Dminecraft.launcher.brand=HyuLauncher -Dminecraft.launcher.version=1.0.0" +
            "-Dlog4j.configuration.File=" + logConfig + "-Djava.library.path=" + Directory.GetCurrentDirectory() + "\\.minecraft\\versions\\1.21\\1.21-natives -cp " + classPath + " " +
            "net.minecraft.client.main.Main --version 1.21 --gameDir " + Directory.GetCurrentDirectory() + "\\.minecraft\\versions\\1.21 --assetsDir " + Directory.GetCurrentDirectory() +
            "\\.minecraft\\assets\\objects --assetsIndex 17 --uuid 00000000-0000-0000-0000-00000000000 --accessToken 1241258925 --userType Legacy --username O_Huangyu --versionType HyuLauncher";
        command.Replace(@"\","/");
        Console.WriteLine(command);
        Process.Start("powershell.exe", "./start.bat");
    }

运行截图:
启动成功

下一篇讲微软登录


参考资料

Minecraft Wiki - https://zh.minecraft.wiki
BMCLAPI - https://bmclapidoc.bangbang93.com
HMCL源代码 - https://github.com/HMCL-dev/HMCL/
PCL2源代码 - https://github.com/Hex-Dragon/PCL2


最后修改:2024-07-27 19:29
本文链接:https://blog.huangyu.win/index.php/archives/21/
版权声明:本文 如何编写一个Minecraft Java版启动器 | Part 1 启动游戏 | 2-1 为 皇鱼 原创。著作权归作者所有,如无特殊声明,本文将依据CC BY-NC-SA 3.0 CN发布,请注意版权。
转载说明:请依据CC BY-NC-SA 3.0 CN进行转载。
最后修改:2024 年 07 月 27 日
如果觉得我的文章对你有用,请留言/点赞