「在生存模式取得指令方塊」:修訂間差異

出自華麥百科
 
(未顯示由 1 位使用者於中間所作的 3 次修訂)
行 22: 行 22:


== 原理 ==
== 原理 ==
原先 Minecraft 遊戲運行時只會有一個 Main Thread 依序的處理遊戲所有事件,但使用特殊的手段可以額外創造出獨立於 Main Thread 以外的另一個 線程
Minecraft 遊戲運行時只會有一個 Main Thread 依序的處理遊戲所有事件,但使用特殊的手段可以額外創造出獨立於 Main Thread 以外的另一個 執行緒


 有了兩個獨立的遊戲 線程 後就能產生 async observer lines 依靠觀察者方塊不斷對著特定的方塊輸出大量的方塊更新,由於現在遊戲同時有兩個 線程 同時運行,這樣就會造成 Race Conditions 的情況發生,使的特定方塊內部數據發生覆蓋而改變方塊的種類。
 有了兩個獨立的遊戲 執行緒 後就能產生 async observer lines 依靠觀察者方塊不斷對著特定的方塊輸出大量的方塊更新,由於現在遊戲同時有兩個 執行緒 同時運行,這樣就會造成 Race Conditions 的情況發生,使的特定方塊內部數據發生覆蓋而改變方塊的種類
 
=== 額外執行緒產生 ===
當玩家放置或破壞染色玻璃時,遊戲會開始從染色玻璃位置開始向下檢查直到碰到烽火臺為止,碰到烽火臺後遊戲開始 getBlockState  檢查方塊狀態,而檢查的過程中如果該區塊沒有載入則又會觸發 load a chunk 從硬碟中讀取該區塊的資料。
 
依靠染色玻璃這種特性,如果讓染色玻璃額外獨立出一個執行緒,那每次在 getBlockState 時觸發 load a chunk 從硬碟中讀取資料,這樣同時 Main Thread 與染色玻璃這兩個執行緒同步動作時,就會有兩份資料互相衝突導致最後的方塊種類發生改變。
 
但這就有一個問題玩家放置或破壞染色玻璃時就已經載入區塊了如何處去觸發 load a chunk ?
 
=== 控制Hash Map ===
在遊戲中儲存以載入區塊的方式是使用  Long2ObjectOpenHashmap 來紀錄每一個區塊索引值,當遊戲內載入的區塊超過 Hash Map 能容納的數量的 3/4 時
 
遊戲將會重新 rehash 並把容量增加到目前載入區塊量的 2n+1,相對的如果容量小於 3/16 時則會 rehash 到當前區塊數量的一半。
 
當遊戲觸發 rehash 時且同時觸發另一個執行緒的 getBlockState 這時候會開始尋找該區塊的索引值,但是前面觸發的 rehash 會導致索引值尋找失敗
 
最後得到的結果是,這個區塊沒有載入所以觸發了 load a chunk 

於 2024年9月9日 (一) 05:35 的最新修訂

使用 Minecraft 本身存在的遊戲漏洞,取得原本不可能在生存模式下獲取的方塊。

想要成功獲取指令方塊必須熟知以下幾項技術:

歷史[編輯 | 編輯原始碼]

2016 年 Panda4994RedstoneSpire 玩家首次發現 instant tile ticks 技術但沒有選擇將原理公開

2019 年 coolmann42 玩家重新發現 instant tile ticks 技術,透過地圖生成出的水源觸發更新抑制就可以將 instant tile ticks 觸發。

2020 年由 coolmann42Xcom6000EarthcomputercortexinvokespecialKerbKmanMatthewBolanMyren EarioPrgmTroublepunchster2skyrisingsylkos 等人開始了一個為期2年的研究 falling block 替換技術,直到 2022 年才將研究結果公開,首次可在生存模式下獲取非法方塊。

原理[編輯 | 編輯原始碼]

Minecraft 遊戲運行時只會有一個 Main Thread 依序的處理遊戲所有事件,但使用特殊的手段可以額外創造出獨立於 Main Thread 以外的另一個執行緒

有了兩個獨立的遊戲執行緒後就能產生 async observer lines 依靠觀察者方塊不斷對著特定的方塊輸出大量的方塊更新,由於現在遊戲同時有兩個執行緒同時運行,這樣就會造成 Race Conditions 的情況發生,使的特定方塊內部數據發生覆蓋而改變方塊的種類。

額外執行緒產生[編輯 | 編輯原始碼]

當玩家放置或破壞染色玻璃時,遊戲會開始從染色玻璃位置開始向下檢查直到碰到烽火臺為止,碰到烽火臺後遊戲開始 getBlockState 檢查方塊狀態,而檢查的過程中如果該區塊沒有載入則又會觸發 load a chunk 從硬碟中讀取該區塊的資料。

依靠染色玻璃這種特性,如果讓染色玻璃額外獨立出一個執行緒,那每次在 getBlockState 時觸發 load a chunk 從硬碟中讀取資料,這樣同時 Main Thread 與染色玻璃這兩個執行緒同步動作時,就會有兩份資料互相衝突導致最後的方塊種類發生改變。

但這就有一個問題玩家放置或破壞染色玻璃時就已經載入區塊了如何處去觸發 load a chunk ?

控制Hash Map[編輯 | 編輯原始碼]

在遊戲中儲存以載入區塊的方式是使用 Long2ObjectOpenHashmap 來紀錄每一個區塊索引值,當遊戲內載入的區塊超過 Hash Map 能容納的數量的 3/4 時

遊戲將會重新 rehash 並把容量增加到目前載入區塊量的 2n+1,相對的如果容量小於 3/16 時則會 rehash 到當前區塊數量的一半。

當遊戲觸發 rehash 時且同時觸發另一個執行緒的 getBlockState 這時候會開始尋找該區塊的索引值,但是前面觸發的 rehash 會導致索引值尋找失敗

最後得到的結果是,這個區塊沒有載入所以觸發了 load a chunk 。