最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

[Minecraft]你的皮膚是怎么顯示出來的?皮膚加載與渲染詳解

2021-07-16 10:20 作者:Nickid2018  | 我要投稿

在MC中,只要是擁有正版的玩家在正版服務器中都能顯示自己獨特的皮膚。那么,這些皮膚是怎么加載與渲染的呢,這篇專欄將會對皮膚機制進行詳解。

目錄

  1. 加載皮膚

    1. GameProfile/游戲檔案

    2. Yggdrasil API

  2. 應用皮膚

    1. ClientboundPlayerInfoPacket

    2. 渲染

  3. 如何自定義你的皮膚

    1. 正版更換皮膚原理

    2. 代理Yggdrasil服務

    3. 使用URL定位你的皮膚

一.加載皮膚

1.GameProfile/游戲資料

在MC中,每個玩家都有GameProfile。這個游戲資料的內部存儲了玩家的名稱、UUID和皮膚信息,位于authlib庫中它的定義如下:

在PropertyMap中包含了我們的皮膚數據。皮膚數據是這個表中的一個Property,它是這樣定義的:

在value中保存的就是我們的皮膚數據,是一個JSON。這個JSON是這樣的:

可以看到,皮膚最后是引用到了一個URL上,這個URL通常是來源于http://textures.minecraft.net/textures/<哈希碼值>

在了解這些后,我們看看GameProfile是如何被序列化的。

GameProfile也可以轉變?yōu)镴SON,它的JSON看起來像這樣(也把PropertyMap的數據寫入了)

玩家可以通過GameProfile得到皮膚的信息,那么MC是如何獲得玩家的游戲數據的呢。接下來就是獲得GameProfile的方法:Yggdrasil API

2.Yggdrsail API

MC采用了一套特殊的API用于玩家賬戶的驗證和獲取數據,這就是Yggdrasil API,位于authlib庫中。這篇專欄主要討論它加載皮膚的部分。

在玩家加入世界后,數據是不完全的,只含有玩家名稱和UUID。這時系統(tǒng)就會調用fillGameProfile填充玩家的數據,補全成為上文那樣。

Yggdrasil API在進行GameProfile數據填充時會向https://sessionserver.mojang.com/profile/<玩家UUID>發(fā)送一個GET請求,附加參數unsigned代表需不需要進行簽名。在通常情況下,requireSecure都為true,也就是會請求簽名。GET請求的結果是一個JSON文本,內容就是上文提到的GameProfile的序列化JSON。通過這個JSON,系統(tǒng)就能解析出玩家的資料。

獲取皮膚使用了另一個方法:getTextures,它能通過玩家的資料提取出皮膚材質信息:

從這段代碼中,我們可以看到皮膚的成功加載由下面幾個條件:

1)這個皮膚數據必須是有簽名的,否則不進行解析

2)找到文件簽名后,就用Yggdrasil API的公鑰進行解密。這個公鑰在MC的文件中,位于/yggdrasil_session_pubkey.der。解密之后的文本應該與value相同,否則驗證失敗

3)進行解析,提取出URL。如果URL不屬于白名單上的域名(這些在白名單的域名有".minecraft.net"和".mojang.com"),那么也不會通過驗證

在三重驗證之后,就得到了一個皮膚的映射,可以讓客戶端下載并使用。

但是,填充GameProfile是服務端的操作,而getTexture是客戶端操作,客戶端要怎么獲取填充好的GameProfile呢?

二.應用皮膚

1.ClientboundPlayerInfoPacket

緊接著上文,客戶端需要服務端的已經填充好的GameProfile,那么服務端就要發(fā)送一個數據包向客戶端通知客戶端獲得數據,這個數據包就是ClientboundPlayerInfoPacket。

這個數據包一共有5種模式:ADD_PLAYER(玩家加入),UPDATE_GAME_MODE(改變游戲模式),UPDATE_LATENCYUPDATE_DISPLAY_NAME(顯示名稱改變),REMOVE_PLAYER(玩家移除)。有關于GameProfile的傳輸是在ADD_PLAYER內部的。

在玩家加入服務器后,服務器會把所有玩家(包括自身)的GameProfile通過ADD_PLAYER模式發(fā)送到客戶端。

在這個數據包傳到客戶端后,客戶端的監(jiān)聽器將處理這個數據包:

GameProfile的數據會在這時傳入PlayerInfo中,之后渲染系統(tǒng)會訪問這個對象獲取皮膚信息。先看看渲染系統(tǒng)是怎么編寫的。

2.渲染

玩家的渲染在PlayerRenderer中,它通過AbstractClientPlayer的方法獲取皮膚數據,下面是一個例子:

那么AbstractClientPlayer是哪里來的呢?答案還是在客戶端數據包監(jiān)聽器內部。

在進入服務器時,服務器會把所有玩家GameProfile發(fā)送到客戶端。而當其他玩家進入本玩家可視范圍內時,服務端會再發(fā)送一個ClientboundAddPlayerPacket用于通知。通過這個數據包,客戶端可以添加這個玩家對象。

PlayerInfo在這時就傳入到了RemotePlayer(AbstractClientPlayer的子類)中。當渲染器渲染玩家時,調用getSkinTextureLocation,進而調用PlayerInfo的getSkinLocation。如果沒有下載皮膚材質,調用皮膚下載器,使用GameProfile中的URL地址下載到皮膚。

如果皮膚材質加載失敗了,那么系統(tǒng)會自動使用Steve/Alex皮膚。使用這兩個默認皮膚不是隨機的,它有關于玩家UUID的哈希碼值。

至此,你的皮膚就展示在你的屏幕上了!

三.如何自定義你的皮膚

1.正版更換皮膚原理

官方啟動器和很多第三方啟動器都支持更換皮膚,它們是通過API進行換膚操作。

官方啟動器的換膚界面

這個API的基礎網址是https://api.mojang.com/user/profile/<玩家UUID>/skin,支持三種操作:上傳皮膚,改變皮膚,重置皮膚。注意:修改皮膚只能在已登錄條件下執(zhí)行,因為這些操作都需要提供accessToken(訪問令牌)

1)上傳皮膚

請求為PUT,Headers需要包含“Authorization”一項,值為“Bearer <訪問令牌>

負載數據有兩項:

????"model"-值為slim或者為空字符串,slim代表Alex模型,空字符串代表Steve模型

????"file"-負載數據為圖片

2)改變皮膚

請求為POST,Headers要求與第一項相同

在URL上負載數據“model”和“url”,分別為模型和材質地址。材質地址只能屬于第一節(jié)所述的幾個網站,否則不會成功換膚

返回值正常為空負載

3)重置皮膚

請求為DELETE,Headers要求與第一項相同,無負載

2.代理Yggdrasil服務

對于沒有正版賬號的玩家來說,無法更換皮膚,但是如果將Yggdrasil服務換成自己的,不就能用自己的皮膚了嗎?這就是“皮膚站”和“外置登錄”的來源。

HMCL上的外置登錄

實現(xiàn)這個功能,就必須在啟動MC時加入一個Java Agent進行代碼修改,現(xiàn)在大家使用的注入器就是authlib-injector,它能修改Yggdrasil API的底層代碼,使Yggdrasil服務定位到皮膚站的API上,這樣就完成了代理。

(注:這種操作也讓登錄定位到了新的API上,所以MC系統(tǒng)會把你識別為“正版玩家”)

3.使用URL定位你的皮膚

根據Yggdrasil API的原理,可以看到我們可以只修改來源于服務端的GameProfile中的textures屬性數據同時撤銷客戶端的Yggdrasil API的三重檢查來達到重新定位皮膚的目的。

可是怎么修改呢?

首先是服務端,服務端在online-modefalse時會自動調用ServerLoginPacketListenerImpl#createFakeProfile生成一個“假的”游戲資料,,UUID的生成與名稱有關:

這個對象中不包含textures屬性。我們可以在這里插入代碼使它加上數據,這樣傳送到客戶端的數據就包含了skin屬性。(注意,此處不要生成signature,因為沒有私鑰生成不了)

另一部分是客戶端,我們只需要撤銷掉三重檢查就可以達到目的了。由于Mixin無法修改authlib庫內部的類,所以我們可以采用繼承+代理這個類更換掉Minecraft類中的對象。

這樣,就可以自定義你的皮膚了?。▽εL一樣管用,只是多加了一點代碼而已)

代碼來源:1.18_experiment-snapshot-1,Mojang Mapping,使用Yarn Mapping的類名及方法名可能不同,但是邏輯一樣

代碼反混淆器及反編譯器:MCDynamicExchanger beta8,bug正在修復

Mojang API的用法:https://c4k3.github.io/wiki.vg/Mojang_API.html

[Minecraft]你的皮膚是怎么顯示出來的?皮膚加載與渲染詳解的評論 (共 條)

分享到微博請遵守國家法律
文安县| 和顺县| 白水县| 农安县| 北流市| 夏河县| 天峻县| 武胜县| 东明县| 凌云县| 赫章县| 广水市| 通江县| 龙岩市| 中西区| 马关县| 福清市| 彰化县| 黑山县| 华阴市| 黑龙江省| 阿坝| 龙川县| 宾阳县| 泌阳县| 安远县| 西吉县| 淮南市| 长顺县| 南京市| 措勤县| 林西县| 鹤峰县| 宁都县| 进贤县| 乡城县| 焉耆| 巨野县| 沁阳市| 太仓市| 博爱县|