D2S是用GO編寫的二進制解析器,用於解析.d2s文件。這是遊戲Diablo II用於保存有關某個字符的所有信息的二進制格式。
該軟件包是為Diablo II的私人服務器構建的,稱為Slash Diablo,為服務器上的所有字符構建了軍械庫。任何人都可以在任何給定時間點看到有關特定角色的所有內容。這是一些例子。
$ go get github.com/nokka/d2s package main
import (
"fmt"
"log"
"os"
"github.com/nokka/d2s"
)
func main () {
path := "nokka.d2s"
file , err := os . Open ( path )
if err != nil {
log . Fatal ( "Error while opening .d2s file" , err )
}
defer file . Close ()
char , err := d2s . Parse ( file )
if err != nil {
log . Fatal ( err )
}
// Prints character name and class.
fmt . Println ( char . Header . Name )
fmt . Println ( char . Header . Class )
}標頭是765 byte長結構,其中包含大多數字符元數據。
| 抵消 | 位元組 | 描述 |
|---|---|---|
| 0 | 4 | 標識符 |
| 4 | 4 | 版本ID |
| 8 | 4 | 文件大小 |
| 12 | 4 | 校驗和 |
| 16 | 4 | 活躍武器 |
| 20 | 16 | 角色名稱 |
| 36 | 1 | 角色狀態 |
| 37 | 1 | 角色進展 |
| 38 | 2 | 未知 |
| 40 | 1 | 角色類 |
| 41 | 2 | 未知 |
| 43 | 1 | 角色級別 |
| 44 | 4 | 未知 |
| 48 | 4 | 上一次比賽 |
| 52 | 4 | 未知 |
| 56 | 64 | 分配的技能 |
| 120 | 4 | 左鼠標按鈕技能ID |
| 124 | 4 | 右鼠標按鈕技能ID |
| 128 | 4 | 左交換鼠標按鈕技能ID |
| 132 | 4 | 右交換鼠標按鈕技能ID |
| 136 | 32 | 字符菜單外觀 |
| 168 | 3 | 困難 |
| 171 | 4 | 地圖ID |
| 175 | 2 | 未知 |
| 177 | 2 | 僱傭軍死亡 |
| 179 | 4 | 僱傭軍身份證 |
| 183 | 2 | 僱傭名稱ID |
| 185 | 2 | 僱傭軍類型 |
| 187 | 4 | 僱傭經驗 |
| 191 | 144 | 未知 |
| 335 | 298 | 任務 |
| 633 | 81 | 航點 |
| 714 | 51 | NPC介紹 |
字符名稱為[16]byte該字節將包含名稱,每個byte一個字母。這個名稱可以長16個字符,一個較短的名稱將在名稱後面的0x00填充,直到我們達到16 bytes 。
-或_ 。 角色狀態是一個byte ,根據角色的狀態,將設置不同的位。仍然沒有弄清楚它們,但這是最重要的。
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| ? | 梯子 | 擴張 | ? | 死了 | 鐵桿 | ? | ? |
尚未實施。
每當您殺死ACT老闆時,價值都會增加。
| 價值 | 標準 | 鐵桿 |
|---|---|---|
| 0-3 | - | - |
| 4-7 | 先生/夫人 | 計數/伯爵夫人 |
| 8-11 | 主/女士 | 公爵/公爵夫人 |
| 12 | 男爵/男爵夫人 | 國王/王后 |
| 價值 | 擴張 | 擴展鐵桿 |
|---|---|---|
| 0-3 | - | - |
| 5-8 | 殺手 | 驅逐艦 |
| 10-13 | 冠軍 | 征服者 |
| 15 | 族長/族長 | 監護人 |
字符類是一個byte ,其中不同的值代表類。
| 班級 | 價值 |
|---|---|
| 亞馬遜 | 0x00 |
| 巫婆 | 0x01 |
| 死靈法師 | 0x02 |
| 聖騎士 | 0x03 |
| 野蠻人 | 0x04 |
| 德魯伊 | 0x05 |
| 刺客 | 0x06 |
上次播放保存為unit32 Unix Timestamp,例如1495882861 。
分配的技能部分是16個技能ID的一個數組,每個技能ID是4 byte整數(UINT32)。如果未分配技能,則值為0x00 。
任務結構是298 byte部分,描述了遊戲中的所有任務,但還包含有關ACT旅行和NPC介紹的數據。每個任務是2 byte長。
| 抵消 | 位元組 | 內容 |
|---|---|---|
| 335 | 4 | 哇! |
| 339 | 6 | 未知 |
一個任務長2 byte ,我創建了一個通用quest結構,該結構是否已完成,該結構是否完成。每個任務都有許多獨特的位置,具體取決於任務的不同里程碑。例如,如果您是否消耗了Quest“冰監獄”的抵抗滾動。
| 位元 | 描述 |
|---|---|
| 0 | 任務完成了 |
冰獄是我唯一不願實施的任務,因為我需要知道角色是否會增加滾動的阻力。
| 位元 | 描述 |
|---|---|
| 0 | 任務完成了 |
| 7 | 消耗滾動 |
這種結構將其重複3次,一次是正常,噩夢和地獄。偏移是任務結構的偏移。
| 抵消 | 位元組 | 描述 |
|---|---|---|
| 0 | 2 | 如果您在Act I中被介紹給Warriv,則設置為1 |
| 2 | [6]quest | 所有六個對Act I的任務。 |
| 14 | 2 | 如果您參加了第二幕,則設置為1 。 |
| 16 | 2 | 如果您被介紹給Jeryn,則設置為1 。 |
| 18 | [6]quest | 所有六項訴訟的任務。 |
| 30 | 2 | 如果您參加了第三幕,則設置為1 。 |
| 32 | 2 | 如果您被介紹給Hratli,則設置為1 。 |
| 34 | [6]quest | 所有六個行為的任務。 |
| 46 | 2 | 如果您旅行第四行,則設置為1 。 |
| 48 | 2 | 如果您被介紹給第四幕,則設置為1 。 (如果您旅行就擁有它) |
| 50 | [6]quest | ACT IV只有3個任務,因此該結構在這裡有6個空字節。 |
| 62 | 2 | 如果您曾1 V. V. |
| 64 | 2 | 在完成恐怖結束並與第四幕中的該隱交談後,似乎已設置為1。 |
| 66 | 4 | 似乎是某種填充。 |
| 70 | [6]quest | 所有六個對第五號法案的任務。 |
| 82 | 14 | 在所有任務數據之後,某種填充。 |
未實施
未實施
遵循標題是“屬性”部分,該部分佈局由9 bit屬性ID組成,其次是n bit長度屬性值。該部分以9 bit值為0x1ff終止。值得一提的是,這些領域有點逆轉。基本上,如果您發現00100111位,它們將被逆轉為11100100 。
| ID | 屬性 |
|---|---|
| 0 | 力量 |
| 1 | 活力 |
| 2 | 靈巧 |
| 3 | 活力 |
| 4 | 未使用的統計數據 |
| 5 | 未使用的技能 |
| 6 | 當前的HP |
| 7 | 最大HP |
| 8 | 當前法力 |
| 9 | 麥克馬娜 |
| 10 | 當前的耐力 |
| 11 | 馬克斯耐力 |
| 12 | 等級 |
| 13 | 經驗 |
| 14 | 金子 |
| 15 | 藏有黃金 |
| 位長度 | 屬性 |
|---|---|
| 10 | 力量 |
| 10 | 活力 |
| 10 | 靈巧 |
| 10 | 活力 |
| 10 | 未使用的統計數據 |
| 8 | 未使用的技能 |
| 21 | 當前的HP |
| 21 | 最大HP |
| 21 | 當前法力 |
| 21 | 麥克馬娜 |
| 21 | 當前的耐力 |
| 21 | 馬克斯耐力 |
| 7 | 等級 |
| 32 | 經驗 |
| 25 | 金子 |
| 25 | 藏有黃金 |
for {
// 1. read 9 bits id. (reverse them)
// 2. if the id is 0x1ff, terminate the loop
// 3. read bit length from attribute map for that id.
// 4. read bit length nr of bits.
}技能是一個32 byte部分,其中包含2 byte標頭,具有if值和30 byte的技能數據。每個班級都有30個技能,因此每種技能都可以獲得1 byte 。關於技能映射的棘手部分是,每個班級都有不同的偏移量,其中特定於類技能的技能圖,然後將30個索引進入地圖。因此,例如,刺客的抵消為251 。這意味著刺客技能在251和281的索引之間,正好是30個索引。
| 類型 | 位元組 | 價值 |
|---|---|---|
| 標題 | 2 | if |
| 技能 | 30 | [30]技能 |
| 班級 | 抵消 |
|---|---|
| 亞馬遜 | 6 |
| 巫婆 | 36 |
| 死靈法師 | 66 |
| 聖騎士 | 96 |
| 野蠻人 | 126 |
| 德魯伊 | 221 |
| 刺客 | 251 |
這是迄今為止最棘手的部分。項目部分以4 byte標頭開始,其中包含jm值JM和一個uint16值,該值是您當前字符的項目。配備,庫存,儲藏,立方體和皮帶全部包括。
本節的字節長度在閱讀完整之前是未知的,因為每個項目的位長度取決於其質量,插座數量和擁有的魔法屬性。
每個項目都遵循某種模式,這是:
每個項目都以111位的簡單數據開始,所有項目都包含。這是像項目類型一樣的信息,如果它是插座,則位置ID(例如配備或存放)等。
每個項目還具有一個名為SimpleItem的布爾值,該布爾值長1一點,如果將其設置為1 ,則該項目不含更多位,而下一個項目開始。
如果該項目不是簡單的項目,則意味著它將在最初的111位之後具有大量數據。其中一些例子是稀有級別,神奇的後綴,神奇的詞綴,如果是魯棒,個性化的,是集合的一部分,特定於班級等。
最後但並非最不重要的一點是,該物品是否會列出神奇的屬性列表,具體取決於它是否是Runeword,魔術,稀有,製作,獨特的部分等等。
這些列表類似於我們將閱讀的屬性部分:
9 bit idn bits of magical properties0x1ff terminator當我們擊中終結器0x1ff時,下一個項目開始。
神奇的屬性是可能發生在項目上的獨特屬性,每個屬性的位長度不同,地圖很大。
這是具有ID 83的魔法屬性,每個3位長3位。
83 : {Bits: [] uint { 3 , 3 }, Name : "+{1} to {0} Skill Levels" },所有神奇的屬性都映射在item.go文件中。
如果您的角色目前已經死亡,並且當您進入遊戲時,屍體就在地面上,則設備的物品將在此項目結構中。這是一個包含標題JM屍體標題16 bytes然後是類似於項目列表的項目數。
閱讀屍體項目的確切方式與上一部分一樣。
如果您的角色是在破壞的擴張之王中創建的,如果將包含2個部分。
僱傭部門以2 byte標頭為帶有jf值的2個字節,然後是一個4 byte項目標頭,其中包含僱傭軍目前佩戴的物品數量。這些項目像其他任何項目列表一樣讀取。
如果您的角色既是死靈法師又是擴展字符,則本節以3 byte標頭開始,其中前兩個字節是標頭kf然後是一個名為hasGolem的布爾值,如果此值為真,則有一個項目列表,其長度列表,其長度為1。
請參閱貢獻。