麻花awa
本帖最后由 hemp 于 2019-1-30 20:20 编辑
   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初探

  1. "id": "1.7.2"
复制代码
这个貌似跟版本名保持相同,我们先不理他,看下一个。

  1. "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets} --uuid ${auth_uuid} --accessToken ${auth_access_token}"
复制代码
这个.....通过名字猜的话,好像是mc参数?会不会跟启动有关呢?我们之后继续研究!

  1.   "mainClass": "net.minecraft.client.main.Main",
复制代码
主类?99%跟启动有关!!

  1.   "assetIndex": {
  2.     "totalSize": 153475165,
  3.     "id": "legacy",
  4.     "url": "https://launchermeta.mojang.com/v1/packages/770572e819335b6c0a053f8378ad88eda189fc14/legacy.json",
  5.     "sha1": "770572e819335b6c0a053f8378ad88eda189fc14",
  6.     "size": 109634
  7.   },
复制代码
assets,里面还有个链接,我们打开看看。


这个文件估计就是描述assets的清单了,我们打开.minecraft/assets/indexes文件夹看看


  1. "id": "legacy",
  2.     "url": "https://launchermeta.mojang.com/v1/packages/770572e819335b6c0a053f8378ad88eda189fc14/legacy.json",
复制代码
估计legacy.json这个文件就是这两行json所表示的。打开看看


虽然没有换行,但是不难看出,跟上面的链接打开的内容是一样的,大致可以猜出,启动器从那个链接下载文件,然后命名为${id}.json放到“.minecraft/assets/indexes”文件夹。


  1. "assets": "legacy",
复制代码
这个目前还没我们分析出含义,也许换一个版本会有发现。



这个应该是minecraft的所需要的库了,乍一看差不多,仔细看还有区别。
  1. {
  2.       "name": "com.mojang:netty:1.6",
  3.       "downloads": {
  4.         "artifact": {
  5.           "path": "com/mojang/netty/1.6/netty-1.6.jar",
  6.           "url": "https://libraries.minecraft.net/com/mojang/netty/1.6/netty-1.6.jar",
  7.           "sha1": "4b75825a06139752bd800d9e29c5fd55b8b1b1e4",
  8.           "size": 7877
  9.         }
  10.       }
  11.     },
复制代码
先看看这种的。name的值可能有人觉得眼熟

  1. compile group: 'io.netty:netty:3.10.6.Final'
复制代码
他的规则是:组织:名称:版本
下载地址也是按照一定规则定义的:
仓库地址/<组织名把'.'替换成'/'>/名称/版本/名称-版本.jar
SHA1,size应该是用来校验的。

我们来看看另一种:
  1. {
  2.       "name": "net.java.jinput:jinput-platform:2.0.5",
  3.       "downloads": {
  4.         "classifiers": {
  5.           "natives-linux": {
  6.             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar",
  7.             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar",
  8.             "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795",
  9.             "size": 10362
  10.           },
  11.           "natives-osx": {
  12.             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar",
  13.             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar",
  14.             "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232",
  15.             "size": 12186
  16.           },
  17.           "natives-windows": {
  18.             "path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar",
  19.             "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar",
  20.             "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16",
  21.             "size": 155179
  22.           }
  23.         }
  24.       },
  25.       "extract": {
  26.         "exclude": [
  27.           "META-INF/"
  28.         ]
  29.       },
  30.       "natives": {
  31.         "linux": "natives-linux",
  32.         "osx": "natives-osx",
  33.         "windows": "natives-windows"
  34.       }
  35.     }
复制代码


这个就是大名鼎鼎的native资源
Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。

我们常听说解压native,那么到底是解压的什么呢?解压它有什么用呢?我们之后研究。

  1. "downloads": {
  2.     "client": {
  3.       "url": "https://launcher.mojang.com/v1/objects/0c8689f904922af71c7144dcfb81bce976cadd49/client.jar",
  4.       "sha1": "0c8689f904922af71c7144dcfb81bce976cadd49",
  5.       "size": 5117607
  6.     },
  7.     "server": {
  8.       "url": "https://launcher.mojang.com/v1/objects/3716cac82982e7c2eb09f83028b555e9ea606002/server.jar",
  9.       "sha1": "3716cac82982e7c2eb09f83028b555e9ea606002",
  10.       "size": 9163955
  11.     },
  12.     "windows_server": {
  13.       "url": "https://launcher.mojang.com/v1/objects/07ae7cdcff6199735eb0f40da5d5c0763558a678/windows_server.exe",
  14.       "sha1": "07ae7cdcff6199735eb0f40da5d5c0763558a678",
  15.       "size": 9559731
  16.     }
  17.   },
  18.   "logging": {
  19.     "client": {
  20.       "file": {
  21.         "id": "client-1.7.xml",
  22.         "url": "https://launcher.mojang.com/v1/objects/6605d632a2399010c0085d3e4da58974d62ccdfe/client-1.7.xml",
  23.         "sha1": "6605d632a2399010c0085d3e4da58974d62ccdfe",
  24.         "size": 871
  25.       },
  26.       "argument": "-Dlog4j.configurationFile\u003d${path}",
  27.       "type": "log4j2-xml"
  28.     }
  29.   },
复制代码
这个应该是相关文件的下载有客户端,服务端,windows_server,logging(有关日志输出的东西),我们需要下载的是client.jar,他就是游戏的核心文件!!
  1. "type": "release",
  2.   "time": "2013-10-25T21:00:00+08:00",
  3.   "releaseTime": "2013-10-25T21:00:00+08:00",
  4.   "minimumLauncherVersion": 9,
  5.   "hidden": false
复制代码
type:这个是表示其类型,比如正式版,快照版等....
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的一部分资源。
  1. READ_ME_I_AM_VERY_IMPORTANT.txt
复制代码
我们看看这是什么?
这是Dinnerbone留给我们的一封信,意思说:这个目录结构马上要弃用了。那么新的目录结构呢?我们看看1.12的assets_index。
em.....没什么区别啊,不过virtual:true没了。我们再看看objects文件夹
随便点开一个
文件夹名应该是开头两个字母,而他们的名是他们的hash值(大家可以自己试试是md5还是sha)


assets文件夹里面大概是这些内容了,我们知道了他的目录结构,在以后我们实现文件补全时,会用到这个!!

四、libraries的探索
上文说到,这里面保存了mc运行所需的库,他们的目录结构很简单。可以概括为:
  1. 组织名('.'替换成路径分隔符)/名称/版本/名称-版本.jar
复制代码
我们再看看上文说的version.json
  1. {
  2.       "name": "org.apache.logging.log4j:log4j-api:2.0-beta9",
  3.       "downloads": {
  4.         "artifact": {
  5.           "path": "org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar",
  6.           "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar",
  7.           "sha1": "1dd66e68cccd907880229f9e2de1314bd13ff785",
  8.           "size": 108161
  9.         }
  10.       }
  11.     },
复制代码
注意path对应是值,这个就是我们应该放到的位置。那为什么还要自己去拼路径?那时因为有可能出现不提供path的情况,这时候我们就要拼接出来路径。

总结:
我们了解了mc的目录结构,知道了mc的所有文件都是按照一定规则分布的。同时也有意外的发现(启动参数,主类)。下一篇我们会探究如何启动mc!



FZG2000
懵逼   懵逼    懵逼

langyo
请将超过两百行的那些代码用 spoiler 标签收缩起来,影响阅读

麻花awa
FZG2000 发表于 2019-1-30 15:21
懵逼   懵逼    懵逼

Um......我已经尽力去解释了

阿~航
看了第二遍了。。。还是看不懂