本帖最后由 hemp 于 2019-1-30 20:20 编辑 
Minecraft启动器是我们在熟悉不过的东西了。有了它,才能启动Minecraft。可以说他是一个重要而又默默无闻的角色了。那么在我们点下启动按钮的那一刻,它在背后都做了些什么?在这个帖子里我们来探寻启动Minecraft的原理。
一、这是?MC
“.minecraft”这个目录是mc玩家都很熟悉的,我们来看看它里面都放了什么
 
 
 
 
 
 
 
 
 
 
复制代码这个貌似跟版本名保持相同,我们先不理他,看下一个。
复制代码这个.....通过名字猜的话,好像是mc参数?会不会跟启动有关呢?我们之后继续研究!
复制代码主类?99%跟启动有关!!
复制代码assets,里面还有个链接,我们打开看看。
 
 
 
 
复制代码估计legacy.json这个文件就是这两行json所表示的。打开看看
 
 
复制代码这个目前还没我们分析出含义,也许换一个版本会有发现。
这个应该是minecraft的所需要的库了,乍一看差不多,仔细看还有区别。
复制代码先看看这种的。name的值可能有人觉得眼熟
复制代码他的规则是:组织:名称:版本
下载地址也是按照一定规则定义的:
仓库地址/<组织名把'.'替换成'/'>/名称/版本/名称-版本.jar
SHA1,size应该是用来校验的。
我们来看看另一种:
复制代码
这个就是大名鼎鼎的native资源
我们常听说解压native,那么到底是解压的什么呢?解压它有什么用呢?我们之后研究。
复制代码这个应该是相关文件的下载有客户端,服务端,windows_server,logging(有关日志输出的东西),我们需要下载的是client.jar,他就是游戏的核心文件!!
复制代码type:这个是表示其类型,比如正式版,快照版等....
time:时间?
releaseTime:发布时间
minimumLauncherVersion:最低启动器版本
hidden:隐藏?(个人猜测是在版本列表不显示)
version.json大概就是这些内容,这个是重要的文件,我们通过他,就可以下载整个minecraft客户端,是不是很神奇??
三、assets文件夹探索
 
 
 
 
 
 
 
 
 
 
复制代码我们看看这是什么?
 
 
 
 
 
 
 
 
复制代码我们再看看上文说的version.json复制代码注意path对应是值,这个就是我们应该放到的位置。那为什么还要自己去拼路径?那时因为有可能出现不提供path的情况,这时候我们就要拼接出来路径。
Minecraft启动器是我们在熟悉不过的东西了。有了它,才能启动Minecraft。可以说他是一个重要而又默默无闻的角色了。那么在我们点下启动按钮的那一刻,它在背后都做了些什么?在这个帖子里我们来探寻启动Minecraft的原理。
一、这是?MC
“.minecraft”这个目录是mc玩家都很熟悉的,我们来看看它里面都放了什么
 
有assets,libraries,version......他们都是干什么用的呢?在这里先简单介绍下。
assets:保存了一些游戏的资源文件(语言,声音之类的)
libraries:保存了一些游戏所需的库文件
logs:保存了游戏的运行日志
resourcepacks:这个大家很熟悉,放资源包的地方
saves:保存了游戏的存档
versions:保存了游戏的一些核心文件
launcher_profiles.json:这个是官方启动器用于记录登录信息的文件
options.txt:这个文件里保存了游戏的设置信息
servers.dat:这里面保存了服务器列表信息(NBT格式)
usercache.json:这里面保存了角色名与UUID的映射信息
说了这么多,哪个是需要我们来研究的呢?刚才说到versions文件夹里保存了游戏核心文件,我们就先研究下这个文件夹吧。
二、versions文件夹初探
 
这不就是启动器版本列表里的吗?好神奇!点开一个看看!
 
里面东西还是很简单的哈,看看那个json里面写了什么
 
看起来有点乱诶。这是因为notpad的换行是\r\n的,而这个文件里却是\n.我们换一个文本编辑器试试!
 
看起来好多了,我们来看看里面的内容吧!
二、version.json初探
- "id": "1.7.2"
- "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets} --uuid ${auth_uuid} --accessToken ${auth_access_token}"
- "mainClass": "net.minecraft.client.main.Main",
-   "assetIndex": {
 
-     "totalSize": 153475165,
 
-     "id": "legacy",
 
-     "url": "https://launchermeta.mojang.com/v1/packages/770572e819335b6c0a053f8378ad88eda189fc14/legacy.json",
 
-     "sha1": "770572e819335b6c0a053f8378ad88eda189fc14",
 
-     "size": 109634
 
- },
 
这个文件估计就是描述assets的清单了,我们打开.minecraft/assets/indexes文件夹看看
 
-  "id": "legacy",
 
- "url": "https://launchermeta.mojang.com/v1/packages/770572e819335b6c0a053f8378ad88eda189fc14/legacy.json",
 
虽然没有换行,但是不难看出,跟上面的链接打开的内容是一样的,大致可以猜出,启动器从那个链接下载文件,然后命名为${id}.json放到“.minecraft/assets/indexes”文件夹。
- "assets": "legacy",
这个应该是minecraft的所需要的库了,乍一看差不多,仔细看还有区别。
- {
 
-       "name": "com.mojang:netty:1.6",
 
-       "downloads": {
 
-         "artifact": {
 
-           "path": "com/mojang/netty/1.6/netty-1.6.jar",
 
-           "url": "https://libraries.minecraft.net/com/mojang/netty/1.6/netty-1.6.jar",
 
-           "sha1": "4b75825a06139752bd800d9e29c5fd55b8b1b1e4",
 
-           "size": 7877
 
-         }
 
-       }
 
- },
- compile group: 'io.netty:netty:3.10.6.Final'
 
下载地址也是按照一定规则定义的:
仓库地址/<组织名把'.'替换成'/'>/名称/版本/名称-版本.jar
SHA1,size应该是用来校验的。
我们来看看另一种:
- {
 
-       "name": "net.java.jinput:jinput-platform:2.0.5",
 
-       "downloads": {
 
-         "classifiers": {
 
-           "natives-linux": {
 
-             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar",
 
-             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar",
 
-             "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795",
 
-             "size": 10362
 
-           },
 
-           "natives-osx": {
 
-             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar",
 
-             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar",
 
-             "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232",
 
-             "size": 12186
 
-           },
 
-           "natives-windows": {
 
-             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar",
 
-             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar",
 
-             "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16",
 
-             "size": 155179
 
-           }
 
-         }
 
-       },
 
-       "extract": {
 
-         "exclude": [
 
-           "META-INF/"
 
-         ]
 
-       },
 
-       "natives": {
 
-         "linux": "natives-linux",
 
-         "osx": "natives-osx",
 
-         "windows": "natives-windows"
 
-       }
 
- }
这个就是大名鼎鼎的native资源
Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。
我们常听说解压native,那么到底是解压的什么呢?解压它有什么用呢?我们之后研究。
- "downloads": {
 
-     "client": {
 
-       "url": "https://launcher.mojang.com/v1/objects/0c8689f904922af71c7144dcfb81bce976cadd49/client.jar",
 
-       "sha1": "0c8689f904922af71c7144dcfb81bce976cadd49",
 
-       "size": 5117607
 
-     },
 
-     "server": {
 
-       "url": "https://launcher.mojang.com/v1/objects/3716cac82982e7c2eb09f83028b555e9ea606002/server.jar",
 
-       "sha1": "3716cac82982e7c2eb09f83028b555e9ea606002",
 
-       "size": 9163955
 
-     },
 
-     "windows_server": {
 
-       "url": "https://launcher.mojang.com/v1/objects/07ae7cdcff6199735eb0f40da5d5c0763558a678/windows_server.exe",
 
-       "sha1": "07ae7cdcff6199735eb0f40da5d5c0763558a678",
 
-       "size": 9559731
 
-     }
 
-   },
 
-   "logging": {
 
-     "client": {
 
-       "file": {
 
-         "id": "client-1.7.xml",
 
-         "url": "https://launcher.mojang.com/v1/objects/6605d632a2399010c0085d3e4da58974d62ccdfe/client-1.7.xml",
 
-         "sha1": "6605d632a2399010c0085d3e4da58974d62ccdfe",
 
-         "size": 871
 
-       },
 
-       "argument": "-Dlog4j.configurationFile\u003d${path}",
 
-       "type": "log4j2-xml"
 
-     }
 
- },
-  "type": "release",
 
-   "time": "2013-10-25T21:00:00+08:00",
 
-   "releaseTime": "2013-10-25T21:00:00+08:00",
 
-   "minimumLauncherVersion": 9,
 
- "hidden": false
time:时间?
releaseTime:发布时间
minimumLauncherVersion:最低启动器版本
hidden:隐藏?(个人猜测是在版本列表不显示)
version.json大概就是这些内容,这个是重要的文件,我们通过他,就可以下载整个minecraft客户端,是不是很神奇??
三、assets文件夹探索
 
可能你们会比这个多点,但是肯定有objects,indexex这两个文件夹。
先看看indexes文件夹
 
em....大家应该比较眼熟,因为介绍version.json的时候提到过这个。那么我们就仔细看看里面的内容吧!!!
(为了看起来顺眼,我把它粘到编辑器里)
 
结构还是不复杂的,有两个对象:objects和virtual
展开objects
 
里面有很多对象,展开一个对象后,我们可以看到上图的样子。他们的键(key)是资源名,值(value)是该资源有关的hash,size等。
还有个virtual呢!!
刚才我们看到assets目录有个virtual文件夹,我们看看这里面有什么。
 
这里面有语言文件、各种音效文件,这应该是mc的一部分资源。
- READ_ME_I_AM_VERY_IMPORTANT.txt
 
这是Dinnerbone留给我们的一封信,意思说:这个目录结构马上要弃用了。那么新的目录结构呢?我们看看1.12的assets_index。
 
em.....没什么区别啊,不过virtual:true没了。我们再看看objects文件夹
 
随便点开一个
 
文件夹名应该是开头两个字母,而他们的名是他们的hash值(大家可以自己试试是md5还是sha)
assets文件夹里面大概是这些内容了,我们知道了他的目录结构,在以后我们实现文件补全时,会用到这个!!
四、libraries的探索
上文说到,这里面保存了mc运行所需的库,他们的目录结构很简单。可以概括为:
- 组织名('.'替换成路径分隔符)/名称/版本/名称-版本.jar
- {
 
-       "name": "org.apache.logging.log4j:log4j-api:2.0-beta9",
 
-       "downloads": {
 
-         "artifact": {
 
-           "path": "org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar",
 
-           "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar",
 
-           "sha1": "1dd66e68cccd907880229f9e2de1314bd13ff785",
 
-           "size": 108161
 
-         }
 
-       }
 
- },
总结:
我们了解了mc的目录结构,知道了mc的所有文件都是按照一定规则分布的。同时也有意外的发现(启动参数,主类)。下一篇我们会探究如何启动mc!
懵逼   懵逼    懵逼
请将超过两百行的那些代码用 spoiler 标签收缩起来,影响阅读
FZG2000 发表于 2019-1-30 15:21
懵逼 懵逼 懵逼
Um......我已经尽力去解释了
看了第二遍了。。。还是看不懂