启动器全部由本人一人编写完成,作为练手的作品。编写过程磕磕绊绊,大多时间都在查阅各种网上资料。

现在写下这篇文章以供后来者参考。

本启动器预计实现以下内容

启动器预计实现的功能
是否完成 项目名称 功能简介 完成日期
登录器的打开及退出 打开登录器界面及关闭登录器 2018/7/10
登录器GUI布局 登录器用户互动界面规划 2018/7/10
注册功能 在登陆器上注册游戏账号 2018/7/17
宣传图的更新 可以实时获取网站上的最新宣传图数据并更新启动器上的图片
公告栏的更新 可以实时获取网站上的公告数据并更新到启动器上的公告栏
新闻栏的更新 可以实时获取网站上的新闻数据并更新到启动器上的新闻栏
客户端更新功能 比对客户端与服务端的版本号,若不同则进入自动更新
客户端绑定功能 只有该启动器发起的请求可以进入服务器,否则拒绝
商店功能 可以在启动器上浏览服务器的商店
积分兑换 隶属商店功能,使用用户的积分兑换商品
充值功能 隶属商店功能,可以直接充值商店点数
查询功能 查询玩家信息(玩家等级、注册时间、最后登录时间等)
下载功能 提供现行JAVA下载、安装
启动器配置 JAVA路径、内存等参数 2018/7/24
窗口可拖动 按住窗口部位可拖动窗口 2018/7/24
游戏启动 直接启动游戏,并实现可以直接进入服务器功能 2018/8/1
⊕为完成一部分功能

本篇文章侧重于启动器对游戏的启动过程。若有其他问题。可私信我提问。知无不言。


作为一个开发白痴。一开始写到启动功能时,两眼一抹黑。

最开始引用了MCBBS论坛上开源的JMCCC类库

但是在实际使用中碰到了以下问题。

AL lib: (EE) alc_cleanup: 1 device not closed
游戏进程退出,状态码:-1

四处求助无果后,我开始转向另一种方法。在论坛上看到的解析JSON来启动游戏。于是我参考了HMCL启动器生成的启动脚本

其生成脚本如下

@echo off
set appdata=[游戏根目录]\.minecraft
"C:\Program Files\Java\jre1.8.0_181\bin\javaw.exe"-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump-XX:+UseG1GC-XX:-UseAdaptiveSizePolicy-XX:-OmitStackTraceInFastThrow-Xmn128m-Xmx2048m-Djava.library.path=[游戏根目录]\.minecraft\versions\1.12.2\1.12.2-natives-Dfml.ignoreInvalidMinecraftCertificates=true-Dfml.ignorePatchDiscrepancies=true-cp /C:/Users/南柯郡守/Desktop/格式工厂输出/3d/HMCL-2.4.1.6.exe org.jackhuang.hellominecraft.launcher.Launcher-cp=[游戏根目录]\.minecraft\libraries\com\mojang\patchy\1.1\patchy-1.1.jar;
。
。。。。省略一万个支持库路径。。。。
。
[游戏根目录]\.minecraft\libraries\com\mojang\text2speech\1.10.3\text2speech-1.10.3.jar;
[游戏根目录]\.minecraft\versions\1.12.2\1.12.2.jar-mainClass=net.minecraft.client.main.Main--username need--version "HMCL 2.4.1.6"--gameDir [游戏根目录]\.minecraft--assetsDir [游戏根目录]\.minecraft\assets--assetIndex 1.12--uuid e877c56e4fb621e81fd30dbd114a545b--accessToken e877c56e4fb621e81fd30dbd114a545b--userType Legacy--versionType "HMCL 2.4.1.6"--height 480--width 854

于是按照正常思维,我将其中引用了HMCL类库部分语句删去 却发现无法启动 提示

多次尝试无果后再次转变思想,打算抛弃已有类库,尝试自己写一个启动核心。

在论坛发帖求助后(论坛帖)。得知在wiki.vg上有有关启动游戏的资料及看了KMCCC贴中的参考资料后。(该过程耗时3天)

小白我觉得这个不适合我,所以又回到了解析JSON文件上。

我先是按照HMCL的脚本格式自己解析了JSON

JSON解析过程源码如下

package minecraft.launcher;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.UUID;public class GamebatWriter {String integrationArgs;String completePath;String fmlAgreement = " -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true";String mainClassPath;String versionArg;public static String main(String args[]) throws IOException {String Content = null;GamebatWriter o =new GamebatWriter();o.FileHandle();Content = o.integrationContent();return (Content);}public void FileHandle() throws IOException {File file = new File(".\\.minecraft\\versions\\"+Mainframe.GameVersion+"\\"+Mainframe.GameVersion+".json");BufferedReader tempreader = new BufferedReader(new FileReader(file));String[] path;String allpath = "";String prepath = "";String name1 = "";String name2 = "";String tempcontent;String finalpath = "";int count = 0;completePath = "";while ((tempcontent = tempreader.readLine()) != null) {//循环处理每一个文件的路径if(tempcontent.contains("\"name\"" ) && tempcontent.length()>38) {//取出包含"name"的内容allpath = "";prepath = "";tempcontent = tempcontent.substring(21, tempcontent.length()-2);//System.out.println(tempcontent);prepath=tempcontent.substring(0,tempcontent.lastIndexOf(":"));path = prepath.split("[\\.:]");//分割得到的内容,做成路径int n;for(n=0;n<path.length;n++) {allpath=allpath+"\\"+path[n];if(path.length-n == 1) {name1=path[n];}}name2 = tempcontent.substring(tempcontent.lastIndexOf(":")+1);finalpath =allpath+"\\"+tempcontent.substring(tempcontent.lastIndexOf(":")+1)+"\\"+name1+"-"+name2+".jar";System.out.println(finalpath);//检查最后的得到的路径File chickfile = new File(".\\.minecraft\\libraries"+finalpath);String AbsolutePath ;if(chickfile.exists()) {//检查即将加载的支持库是否存在AbsolutePath = chickfile.getAbsolutePath();System.out.println(AbsolutePath);completePath=completePath + AbsolutePath + ";";//若存在就把该支持库的绝对路径加入命令行中}else {count++;//记录有多少个支持库不存在}}else if(tempcontent.contains("\"mainClass\"" )) {mainClassPath = tempcontent.substring(18,tempcontent.length()-2);System.out.println("mainClassPath = "+mainClassPath);//此处是误区,我在分析HMCL的脚本时误将 -mainClassPath= 当作启动参数,导致后面各种无法启动}}  System.out.println(completePath);System.out.println("有" + count + "个支持库未找到。");versionSentence();//获取版本.jarUUIDMake();//因为非正版启动,所以随机生成一份UUID即可tempreader.close();//关闭读取流,以免过多占用内存completePath = completePath.substring(0,completePath.length()-1);//去掉最末尾的斜杠}public void versionSentence() {File versionJar = new File(".\\.minecraft\\versions\\"+Mainframe.GameVersion+"\\"+Mainframe.GameVersion+".jar");if(versionJar.exists()) {versionArg = versionJar.getAbsolutePath();}}String foreUUID;public void UUIDMake() {foreUUID = UUID.randomUUID().toString();foreUUID = foreUUID.replace("-", "");}String assetsPath = Mainframe.GameAbsolutePath + "\\assets";public String integrationContent(){integrationArgs="\"" + Mainframe.JavaFinalDir + "\" -Xmn" + Mainframe.MinMemory + "m -Xmx" + Mainframe.MaxMemory+ "m -Djava.library.path=" + Mainframe.NativesDir + fmlAgreement + " -cp \"" + completePath + ";" + versionArg+ "\" " + mainClassPath +" --username " + Mainframe.PlayerName + " --version \"THEMEDALAUNCHER\" --gameDir "+ Mainframe.GameAbsolutePath + " --assetsDir " + assetsPath + " --assetIndex 1.12"+ " --uuid " + foreUUID + " --accessToken " + foreUUID +" --userType Legacy --versionType \"THEMEDALAUNCHER\"" + " --height " + Mainframe.FrameSizey + " --width " + Mainframe.FrameSizex;/*以上为完整的启动参数,其中部分内容无需改动*将会在下面的JSON解析中讲到*/System.out.println(integrationArgs);System.out.println(Mainframe.GameVersion);integrationArgs = integrationArgs.replace(".\\", "");return (integrationArgs);}
}

代码有些部分比较冗杂。还望见谅

以上内容绝大部分通过解析JSON获得,部分内容因非必要与版本同步,所以采用内置存储。

接下来我会以 1.12.2.json 为例讲一下我是如何解析JSON的。

将JSON文件以记事本方式打开,可见以下内容。 我将需要解析部分单独标注

{"assetIndex": {//参数中的assetIndex数据从这里的"id"下取出"id": "1.12","sha1": "e75e9535754c6f2158b0b18b35660f45c4495d78","size": 169257,"url": "https://launchermeta.mojang.com/mc/assets/1.12/e75e9535754c6f2158b0b18b35660f45c4495d78/1.12.json","totalSize": 127722338},"assets": "1.12",//参数中的asset数据从这里直接取出"downloads": {"client": {"sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf","size": 10180113,"url": "https://launcher.mojang.com/mc/game/1.12.2/client/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"},"server": {"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f","size": 30222121,"url": "https://launcher.mojang.com/mc/game/1.12.2/server/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar"}},"id": "1.12.2",//参数中的游戏版本可以由此取出。不过--version现在并不重要。随意内容均可"libraries": [//以下为需要载入的支持库。支持库在参数中以 -cp  开头载入。注意,要将所有支持库路径写出后将所有路径用双引号括住每个路径之间用一个分号(;)隔开{"name": "com.mojang:patchy:1.1",//这里是支持库的路径及名称
//该支持库路径为\.minecraft\libraries\com\mojang\patchy\1.1\patchy-1.1.jar"downloads": {//这里是该支持库的下载地址、大小、哈希值、及路径"artifact": {"size": 15817,"sha1": "aef610b34a1be37fa851825f12372b78424d8903","path": "com/mojang/patchy/1.1/patchy-1.1.jar",//路径可以直接取该值,我也才发现这一行,但我不打算改源码了"url": "https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar"}}},。
。
。
。
。。。。。省略一万个支持库路径。。。。。
。
。
。
。
。
。"mainClass": "net.minecraft.client.main.Main",//客户端的main类 必须载入 载入时直接在库后面空格 再加上该value即可//以下内容在原文件中为一行,这里为了方便讲解,我将它拆成多行来讲解。"minecraftArguments": "--username ${auth_player_name}//玩家昵称。--version ${version_name}//版本号,不过并不是需要和版本同步的,随意内容均可--gameDir ${game_directory}//游戏路径,精确到\.minecraft--assetsDir ${assets_root}//assets的路径,精确到\.minecraft\assets--assetIndex ${assets_index_name}//由该文件第一行位置取到--uuid ${auth_uuid}//非正版登录可随机一个UUID JAVA有随机UUID的API--accessToken ${auth_access_token}//同上UUID--userType ${user_type}//不明确 一般填Legacy--versionType ${version_type}",//该版本号也是非必要。不过会在游戏刚启动后的左下角显示。"minimumLauncherVersion": 18,//最低启动器版本号。无用"releaseTime": "2017-09-18T08:39:46+00:00","time": "2018-06-25T15:37:20+00:00","type": "release"
}

解析出来的JSON应该如下

"C:\Program Files\Java\jre1.8.0_181\bin\javaw.exe"-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump-XX:+UseG1GC-XX:-UseAdaptiveSizePolicy-XX:-OmitStackTraceInFastThrow-Xmn128m-Xmx2048m-Djava.library.path=[游戏根目录]\.minecraft\versions\1.12.2\1.12.2-natives-Dfml.ignoreInvalidMinecraftCertificates=true-Dfml.ignorePatchDiscrepancies=true-cp /C:/Users/南柯郡守/Desktop/格式工厂输出/3d/HMCL-2.4.1.6.exe org.jackhuang.hellominecraft.launcher.Launcher-cp "[游戏根目录]\.minecraft\libraries\com\mojang\patchy\1.1\patchy-1.1.jar;
。
。。。。省略一万个支持库路径。。。。
。
[游戏根目录]\.minecraft\libraries\com\mojang\text2speech\1.10.3\text2speech-1.10.3.jar;
[游戏根目录]\.minecraft\versions\1.12.2\1.12.2.jar"net.minecraft.client.main.Main--username need--version "HMCL 2.4.1.6"--gameDir [游戏根目录]\.minecraft--assetsDir [游戏根目录]\.minecraft\assets--assetIndex 1.12--uuid e877c56e4fb621e81fd30dbd114a545b--accessToken e877c56e4fb621e81fd30dbd114a545b--userType Legacy--versionType "HMCL 2.4.1.6"--height 480--width 854

与HMCL生成脚本不同的是

1. -cp 后用的不是 等号 而是双引号

2. 在客户端main类的前端没有 -mainClasspath=

最重要的一点是以上所有参数之间使用空格隔开并且没有换行。

在写完解析JSON后,尝试使用JAVA自带的RUNTIME启动cmd运行以上参数

public void run() {String nice = null;try {nice = GamebatWriter.main(null);} catch (IOException e1) {System.out.println(e1.getMessage());e1.printStackTrace();}System.out.println("nice = " + nice);String cmd = "cmd /c " + nice;try {p = Runtime.getRuntime().exec(cmd);isGameRunning = true;System.out.println("游戏已启动");} catch (IOException e1) {System.out.println(e1.getMessage());e1.printStackTrace();} }

但是并没有成功。

多方查阅资料后,在某篇文章中看到了 需要在 "cmd /c "后加上"start \"\" "

改正后该句代码为

String cmd = "cmd /c start \"\" " + nice;

即可正常启动。

以上为启动器的启动功能解析及JSON解析。


接下来因为启动器在启动游戏后要与服务端取得通信以完成用该启动器启动游戏的玩家无需再输入密码就可以直接进入服务器的功能

需要启动器在启动游戏后依然可以操作

但是因为本人技术所限,所以无法做到process不阻塞主进程。

在尝试编写自定义监听器未果后。我又开动小脑筋改了方向。

既然启动游戏前的界面被阻塞了。那我就再创建另外一个界面不就好了

于是在启动游戏后--获取缓冲流之前的代码区间里 ,

我先是隐藏了启动前的窗口,然后再创建了一个新的窗口用于与服务器端通信。解决了游戏启动后进程卡死的情况。

#以上方法行不通所有进程依旧会被阻塞#


接下来要实现的任务——找到启动游戏后直连服务器的参数

[Themeda启动器]用Java编写的Minecraft启动器相关推荐

  1. hmcl电脑java我的世界启动器_hello minecraft下载

    hello minecraft launcher是一款我的世界玩家必备的游戏启动器,特别是现在了纯净版mc的玩家不能进去游戏就是缺少这个hello minecraft启动器,本工具支持最新的1.8版本 ...

  2. skinme找不到java_我的世界hello minecraft启动器下载

    我的世界下载完成之后需要安装JAVA环境,如果没有启动器的朋友还需要下载一个启动器,今天游戏园小编为大家带来了我的世界启动器的下载,这个启动器叫做hello minecraft,这款启动器支持的功能也 ...

  3. python也能开发minecraft启动器

    最近我在csdn上看见了 __小小的程序员__ 博主的文章,发现python可以开发minecraft启动器? 好牛皮!我试了一下!果真可以,所有版本(包括最新1.19和最新快照)都可以.别忘了pip ...

  4. 我的世界java版boat启动器_我的世界boat启动器mio版

    游戏介绍 我的世界boat启动器mio版是一款由玩家自制的我的世界启动器.我的世界boat启动器mio澪版游戏本体使得玩家享受到最经典我的世界游戏的同时,还能够在其中加入各种模组来游玩体验,喜欢的小伙 ...

  5. |python|用tkinter做minecraft启动器 第一章:python配置

    哈啰啊,这是发的第一篇文章,做的不好,多多关照 好进入正题今天是配置python,先看后期的图片 好,我们首先得下载python(链接加载有点慢) python下载 | 传送门 | 然后点这个(红框框 ...

  6. minecraft启动器_如何使用外部编辑器编辑Minecraft地图

    minecraft启动器 In a previous tutorial we took WorldEdit for a spin, a fantastic in-game editor that le ...

  7. java编写代码用什么_如何学习用Java编写代码:为什么要学习以及从哪里开始

    java编写代码用什么 by John Selawsky 约翰·塞劳斯基(John Selawsky) 如何学习用Java编写代码:为什么要学习以及从哪里开始 (How to learn to cod ...

  8. java培训教程分享:Java编写软件代码自动提示功能

    本期的java培训教程分享主要是介绍的java编写软件代码的一个自动提示功能,很多零基础和初学java的同学们对这一块还不是很了解,Eclipse for android 实现代码自动提示智能提示功能 ...

  9. 【项目展示】一个有点难度的猜数字小游戏(Java编写)

    (声明:本文部分图片来自网络,如有侵权请联系,将第一时间删除或更换图片) 本文目录 1.前言 2.规格说明 3.源代码 4.运行结果 5.感想 1.前言 我在自己的博客里上传了一些本科时编过.最近又改 ...

最新文章

  1. 机器学习拓展知识(数学/统计/算法)
  2. 系统更新链接服务器超时,Win10系统更新后Dr.com连接认证服务器一直超时如何解决?...
  3. java中子类可否抛出两个父类抛出的异常的子类_父类的多个构造方法各自抛出不同的异常,子类的构造方法应该抛出哪个/些异常?...
  4. 1039. 到底买不买(20)-PAT乙级真题
  5. CF 917A The Monster 【括号匹配】
  6. 爬虫必备的防止反爬虫策略
  7. 基于LabVIEW的音频信号采集分析系统
  8. 服务器正常运行温度,服务器cpu的温度在什么范围内是属于正常温度
  9. ubuntu离线中文语音识别
  10. (28)部署强命名程序集到GAC
  11. 以下7种硬件测试的种类,不知道的赶紧收藏了!
  12. word怎样让表格不跨页【实测成功】
  13. 论文阅读:Contextual Translation Embedding for Visual Relationship Detection and SGG(PAMI2020)
  14. python坐标转化极坐标方程公式_数学 球坐标(Spherical) - 闪电教程JSRUN
  15. 计算机硬盘显示恢复出厂设置,如何对磁盘进行分?
  16. 史上最全讲解:JAVA中的Map与Thread
  17. python 矩阵特征值_用python求矩阵特征值的方法?
  18. tryhackme圣诞挑战2021-Advent of Cyber 3-day2-越权漏洞,修改cookie
  19. 服务器304响应,网络---关于HTTP 304状态码的理解-Go语言中文社区
  20. 关于汽车CAN总线的介绍

热门文章

  1. 深度学习--超参数(持续更新)
  2. 小程序开发API之获取系统信息wx.getSystemInfo()、wx.getSystemInfoSync()
  3. 致远SPM解决方案之安全管理
  4. Scala语言学习:Scala是什么?
  5. 吴国忠先生谈郑曼青太极拳之思路
  6. DOS命令CD D:\ 不管用,怎么进入D盘
  7. The Design of design
  8. Android studio 解决运行按钮灰色/禁用状态
  9. 论文框架和目录一样吗_看黑板,划重点!速来get论文写作10技巧
  10. 编写python 函数,实现冒泡排序算法。