minecraft的资源文件下载的逻辑是什么呢?

纯萌新一枚,自己抓包学到的,先从(渣的一bi的亚马逊)
https://launchermeta.mojang.com/mc/game/version_manifest.json
(新版不带换行555)获取版本,比如

    {
        "id": "1.11.2",
        "type": "release",
        "time": "2017-02-07T13:18:39+00:00",
        "releaseTime": "2016-12-21T09:29:12+00:00"
        "url": "https://launchermeta.mojang.com/mc/game/12f260fc1976f6dd688a211f1a906f956344abdd/1.11.2.json"
    }

然后获取这个版本的json,地址是"url"处的内容
https://launchermeta.mojang.com/mc/game/12f260fc1976f6dd688a211f1a906f956344abdd/1.11.2.json

首先是jar文件,上面的client就是客户端,server就是服务端,下载后重命名为版本号

"downloads": {
    "client": {
        "sha1": "db5aa600f0b0bf508aaf579509b345c4e34087be",
        "size": 9198097,
        "url": "https://launcher.mojang.com/mc/game/1.11.2/client/db5aa600f0b0bf508aaf579509b345c4e34087be/client.jar"
    },
    "server": {
        "sha1": "f00c294a1576e03fddcac777c3cf4c7d404c4ba4",
        "size": 9720835,
        "url": "https://launcher.mojang.com/mc/game/1.11.2/server/f00c294a1576e03fddcac777c3cf4c7d404c4ba4/server.jar"
    }
},

然后是后边的libraries都有下载地址,比如

"id": "1.11.2",
"libraries": [
    {
        "name": "com.mojang:netty:1.6",
        "downloads": {
            "artifact": {
                "size": 7877,
                "sha1": "4b75825a06139752bd800d9e29c5fd55b8b1b1e4",
                "path": "com/mojang/netty/1.6/netty-1.6.jar",
                "url": "https://libraries.minecraft.net/com/mojang/netty/1.6/netty-1.6.jar"
            }
        }
    },

但是到assets这步就犯难了,

"assetIndex": {
    "id": "1.11",
    "sha1": "ea7f56173691250e9805db5e3dda2d65b951ede3",
    "size": 157395,
    "url": "https://launchermeta.mojang.com/mc/assets/1.11/ea7f56173691250e9805db5e3dda2d65b951ede3/1.11.json",
    "totalSize": 124627552
 },

这个json的内容是需要存在assets文件夹下的所有的文件
这全都是类似于

  "minecraft/sounds/mob/tray/death2.ogg": {
  "hash": "d48940aeab2d4068bd157e6810406c882503a813",
  "size": 18817
   },

这些assets文件怎么下载呢?
另外,在后边有些library文件是这样的,

        "rules": [
            {
                "action": "allow"
            },
            {
                "action": "disallow",
                "os": {
                    "name": "osx"
                }
            }
        ],

在"name"和"download"之间多了一些内容,这些如何处理呢?
最后两个libraries的name前面还有

        "extract": {
            "exclude": [
                "META-INF/"
            ]
        },

这个是做什么的呢?
另外就是首次启动时的处理依赖是下载natives吗?我看HMCL是在首次启动时还下东西欸,这些natives是从那些地方获取的呢?

你可以读读各个开源启动器源码啊_(:з」∠)_

@bangbang93
1:懒死了
2:不会(极好的)
3:为什么bmclapi不能下amazon s3目录格式的资源文件?

@bangbang93 求打赏3个威望值,
并问:BMCL是C井写的吗

@YouYax 能按照官方aws的方式下载啊
是C#的没错

@bangbang93
不过MCLauncherBN和2.3版本之前的HMCL等就无法下载,现在不是改用mojang.com和minecraft.net了吗?
AWS是指https://s3.amazonaws.com/Minecraft.Download/

@bangbang93
我翻了BMCL V1,V2,V4的源代,但是好像没有V3

YouYax 说:

@bangbang93
不过MCLauncherBN和2.3版本之前的HMCL等就无法下载,现在不是改用mojang.com和minecraft.net了吗?
AWS是指https://s3.amazonaws.com/Minecraft.Download/

https://s3.amazonaws.com/Minecraft.Download/ 里的资源文件已经弃用了

@bangbang93 建议能做个下载服务端的API

@bangbang93 嗯,看到了。除了官服还有其他的吗?

诈个尸,回来更新一下
最开始获取到的version_manifest.json当Temp处理
这个文件最开始的

"latest": {
    "snapshot": "1.12-pre5",
    "release":"1.11.2"
},

能够获得最新的快照或预览版本(snapshot)和发布版本(release),如果是down最新版的话直接找1.11.2的字符串,以此类推。
下面的内容(源文件根本不带换行。。。)

    {
        "id": "版本号",
        "type": "快照/预览还是发布",
        "time": "表示我也不知道是什么时间反正不靠谱就对了",
        "releaseTime": "此版本发布时间"
        "url": "该版本json的下载地址"
    }

json的地址就是同目录.minecraft/versions/版本/版本.json,看这个json开始

"assetIndex": {
    "id": "1.11",
    "sha1": "ea7f56173691250e9805db5e3dda2d65b951ede3",
    "size": 157395,
    "url": "https://launchermeta.mojang.com/mc/assets/1.11/ea7f56173691250e9805db5e3dda2d65b951ede3/1.11.json",
    "totalSize": 124627552
},

这个就是Assets文件的索引,需要先把索引放到.minecraft/assets/indexes/版本.json
里面的的都是类似

"minecraft/sounds/mob/husk/step4.ogg": {
  "hash": "70a1c99c314a134027988106a3b61b15389d5f2f",
  "size": 9398

的内容,开头的 “objects”: { 是存放的文件夹名,最好读取文件而不是写死,以免给自己挖坑,位置是.minecraft/assets/objects
第一个文件路径名不用管,解压时候用,但是也可以推算出url。hash的值就很重要了,先解析json并截取hash的前两位,建立 .minecraft/assets/objects/hash前两位 的一个文件夹,再用他的hash为名保存。地址是http://resources.download.minecraft.net/hash前两位/完整hash
保存位置是.minecraft/assets/objects/hash前两位/完整hash
比如step4.ogg,下载地址是
http://resources.download.minecraft.net/70/70a1c99c314a134027988106a3b61b15389d5f2f
保存位置是
.minecraft/assets/objects/70/70a1c99c314a134027988106a3b61b15389d5f2f
所有文件以此类推
后面的size是Byte的大小,最好check一下,防止(呵呵)
接下来是

"assets": "1.11",
"downloads": {
    "client": {
        "sha1": "db5aa600f0b0bf508aaf579509b345c4e34087be",
        "size": 9198097,
        "url": "https://launcher.mojang.com/mc/game/1.11.2/client/db5aa600f0b0bf508aaf579509b345c4e34087be/client.jar"
    },
    "server": {
        "sha1": "f00c294a1576e03fddcac777c3cf4c7d404c4ba4",
        "size": 9720835,
        "url": "https://launcher.mojang.com/mc/game/1.11.2/server/f00c294a1576e03fddcac777c3cf4c7d404c4ba4/server.jar"
    }

第一个assets只要是按同一文件下载肯定没错,不用管。download下client就是客户端,server就是服务端,服务端就这唯一一个文件(2333),客户端下载地址就是url处的内容,但是保存地址是.minecraft/versions/版本/版本.jar,所以需要注意

"id": "1.11.2",
"libraries": [
    {
        "name": "com.mojang:netty:1.6",
        "downloads": {
            "artifact": {
                "size": 7877,
                "sha1": "4b75825a06139752bd800d9e29c5fd55b8b1b1e4",
                "path": "com/mojang/netty/1.6/netty-1.6.jar",
                "url": "https://libraries.minecraft.net/com/mojang/netty/1.6/netty-1.6.jar"
            }
        }
    },

这个就是libraries文件的下载了,相对比较明了,每个都有下载地址,保存位置是.minecraft/libraies/$path ,比如
com.mojang:netty:1.6的保存位置就是.minecraft/libraies/com/mojang/netty/1.6/netty-1.6.jar 做起来还是比较easy,有sha1验证。有些libraries有一些条件,比如

    {
        "name": "org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-20140822",
        "rules": [
            {
                "action": "allow",
                "os": {
                    "name": "osx"
                }
            }
        ],
        "downloads": {
            "artifact": {
                "size": 1045632,
                "sha1": "7707204c9ffa5d91662de95f0a224e2f721b22af",
                "path": "org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar",
                "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar"
            }
        }
    },

比如这个就是只能让OSX系统下载运行,判断时rules应该优先于downloads,还有这样的

    {
        "extract": {
            "exclude": [
                "META-INF/"
            ]
        },
        "name": "net.java.jinput:jinput-platform:2.0.5",
        "natives": {
            "linux": "natives-linux",
            "osx": "natives-osx",
            "windows": "natives-windows"
        },
        "downloads": {
            "classifiers": {
                "natives-linux": {
                    "size": 10362,
                    "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795",
                    "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"
                },
                "natives-osx": {
                    "size": 12186,
                    "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232",
                    "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"
                },
                "natives-windows": {
                    "size": 155179,
                    "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16",
                    "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"
                }
            }
        }
    }
],

不同的系统名对应不同的内容,所以判断natives可以单出来,然后寻找字符段。
最后,文件就可以全部完整下载出来了。其余的就是启动器的事了

@administrators @bangbang93 应该没错吧,如有错误,请不吝指教

  • 14
    帖子
  • 5265
    浏览