D2Sは、 .d2sファイルを解析するために使用されるGOで書かれたバイナリパーサーです。これは、ゲームDiablo IIが特定の文字に関するすべての情報を保存するために使用するバイナリ形式です。
このパッケージは、Slash Diabloと呼ばれるDiablo IIのプライベートサーバー向けに構築され、サーバー上のすべての文字用のアーモリーを構築しました。特定のキャラクターに関するすべてを特定の時点で見ることができる場所。いくつかの例があります。
$ 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 | merc兵が死んだ |
| 179 | 4 | merc兵ID |
| 183 | 2 | merc兵名ID |
| 185 | 2 | merc兵タイプ |
| 187 | 4 | merc兵エクスペリエンス |
| 191 | 144 | 未知 |
| 335 | 298 | クエスト |
| 633 | 81 | ウェイポイント |
| 714 | 51 | NPC紹介 |
文字名は[16]byteとして頑張られており、名前にはbyteごとに1文字が含まれています。名前の長さは16文字で、短い名前は16 bytesに達するまで0x00の後ろに0x00をパディングします。
-つまたは_を含む場合があります。 文字ステータスは、文字のステータスに応じて、異なるビットが設定されるbyteです。まだそれらをすべて理解していませんが、これが最も重要なものです。
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| ? | ラダー | 拡大 | ? | 死んだ | ハードコア | ? | ? |
まだ実装されていません。
ACTのボスを殺すたびに、値は増加します。
| 価値 | 標準 | ハードコア |
|---|---|---|
| 0-3 | - | - |
| 4-7 | サー/ダム | count/countess |
| 8-11 | 主/女性 | 公爵/公爵夫人 |
| 12 | 男爵/男爵領 | 王/女王 |
| 価値 | 拡大 | 拡張ハードコア |
|---|---|---|
| 0-3 | - | - |
| 5-8 | スレイヤー | 駆逐艦 |
| 10-13 | チャンピオン | 征服者 |
| 15 | 家長/家長 | ガーディアン |
文字クラスは、異なる値がクラスを表すbyteです。
| クラス | 価値 |
|---|---|
| アマゾン | 0x00 |
| 魔術師 | 0x01 |
| ネクロマンサー | 0x02 |
| パラディン | 0x03 |
| 野b人 | 0x04 |
| ドルイド | 0x05 |
| 暗殺者 | 0x06 |
最後のプレイは、 unit32 UnixタイムスタンプEG 1495882861として保存されます。
割り当てられたスキルセクションは、それぞれ4 byte整数(UINT32)の16のスキルIDの配列です。スキルが割り当てられていない場合、値は0x00です。
Quests structは、ゲーム内のすべてのクエストを説明する298 byteセクションですが、ACT旅行とNPCの導入に関するデータも含まれています。各クエストの長さは2 byteです。
| オフセット | バイト | コンテンツ |
|---|---|---|
| 335 | 4 | うわー! |
| 339 | 6 | 未知 |
クエストの長さは2 byteです。クエストが完了しているかどうかにかかわらず、クエストの最も重要なデータを保持する一般的なquest構造を作成しました。各クエストには、クエストのさまざまなマイルストーンに応じて、多くのユニークなビットが設定されています。たとえば、「氷の刑務所」のクエストから抵抗の巻物を消費した場合。
| 少し | 説明 |
|---|---|
| 0 | クエストが完了しました |
刑務所の刑務所は、巻物からの抵抗が増加しているかどうかを知る必要があるため、私が実装することを気にした唯一のクエストです。
| 少し | 説明 |
|---|---|
| 0 | クエストが完了しました |
| 7 | 消費されたスクロール |
この構造は、通常の悪夢と地獄のために1回、3回自己繰り返します。オフセットは、クエスト構造体へのオフセットです。
| オフセット | バイト | 説明 |
|---|---|---|
| 0 | 2 | Act I.でWarrivを紹介された場合は1に設定します。 |
| 2 | [6]quest | 第1幕の6つのクエストすべて |
| 14 | 2 | Act IIに旅行した場合は1に設定します。 |
| 16 | 2 | Jerhynに紹介された場合は1に設定します。 |
| 18 | [6]quest | 第2幕の6つのクエストすべて。 |
| 30 | 2 | Act IIIに旅行した場合は1に設定します。 |
| 32 | 2 | Hratliに紹介された場合は1に設定します。 |
| 34 | [6]quest | Act IIIの6つのクエストすべて。 |
| 46 | 2 | Act IVに旅行した場合は1に設定します。 |
| 48 | 2 | Act IVを紹介されている場合は1に設定します。 (旅行した場合はこれを持っています) |
| 50 | [6]quest | Act IVには3つのクエストのみがあるため、ここには構造体には6つの空のバイトがあります。 |
| 62 | 2 | ACT Vに旅行した場合は1に設定します。 |
| 64 | 2 | Terrorの終わりを完了し、Act IVでCainと話した後、1に設定されているようです。 |
| 66 | 4 | ある種のパディングのようです。 |
| 70 | [6]quest | ACT Vの6つのクエストすべて。 |
| 82 | 14 | すべてのクエストデータの後、ある種のパディング。 |
実装されていません
実装されていません
ヘッダーに続く属性セクションでは、このセクションレイアウトは9 bit属性IDの配列で構成され、その後にn bit長属性値が続きます。セクションは、 0x1ffの9 bit値で終了します。これらのフィールドはビット逆になっていることに言及する価値があります。基本的に、ビット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.
}スキルは、値のifと30 byteのスキルデータを備えた2 byteヘッダーを含む32 byteセクションです。各クラスには30のスキルがあります。そのため、各スキルはそれぞれ1 byteを取得します。スキルマッピングのトリッキーな部分は、各クラスがクラスの特定のスキルが始まるスキルマップに異なるオフセットを持ち、30インデックスをマップに移動することです。たとえば、アサシンのオフセットは251です。つまり、暗殺者のスキルは、正確に30のインデックスである251と281のインデックスの間にあります。
| タイプ | バイト | 価値 |
|---|---|---|
| ヘッダ | 2 | if |
| スキル | 30 | [30]スキル |
| クラス | オフセット |
|---|---|
| アマゾン | 6 |
| 魔術師 | 36 |
| ネクロマンサー | 66 |
| パラディン | 96 |
| 野b人 | 126 |
| ドルイド | 221 |
| 暗殺者 | 251 |
これは、断然最も難しい部分です。アイテムセクションは、値JMを含む4 byteヘッダーと、キャラクターが現在持っているアイテムカウントであるuint16値から始まります。装備、在庫、スタッシュ、キューブ、ベルトがすべて含まれています。
各アイテムのビットの長さは、その品質、ソケットの数、所有する魔法の属性によって異なるため、セクションのバイトの長さは完全に読み取る前に不明です。
ただし、各アイテムは特定のパターンに従います。
各アイテムは、すべてのアイテムに含まれる111ビットの単純なデータから始まります。これは、アイテムタイプなどの情報、ソケットの場合、装備やスタッシュなどの位置IDなどです。
また、各アイテムには、 1ビットの長さのSimpleItemというブール波があります。これが1に設定されている場合、アイテムにはビットが含まれておらず、次のアイテムが開始されます。
アイテムが単純なアイテムでない場合、これは最初の111ビットに続いて大量のデータがあることを意味します。これのいくつかの例は、それがRuneword、Personalized、セットの一部、クラス固有などである場合、希少レベル、魔法の接尾辞、魔法の接辞です。
最後になりましたが、アイテムが持っている場合は、それがルーンワード、魔法のような、珍しい、細工された、セットのユニークな部分であるかどうかに応じて、魔法の特性のリストがあります。
これらのリストは、読み取る属性セクションに似ています。
9 bit idn bits of magical properties0x1ff terminatorターミネーター0x1ffを押すと、次のアイテムが始まります。
魔法のプロパティは、アイテムで発生する可能性のあるユニークなプロパティであり、各プロパティの長さは異なり、マップは巨大です。
これは、 3ビットそれぞれ2ビットフィールドを含むID 83を持つ魔法のプロパティです。
83 : {Bits: [] uint { 3 , 3 }, Name : "+{1} to {0} Skill Levels" },すべての魔法のプロパティは、item.goファイルにマッピングされています。
あなたのキャラクターが現在死んでいて、ゲームに入るときに死体が地面にある場合、装備されたアイテムがこのアイテムの構造になります。これは、ヘッダーJMを含む16 bytes死体ヘッダーで、その後にアイテムリストと同様のアイテムカウントが続きます。
死体のアイテムを読むことは、アイテムの前のセクションとして正確に行われます。
あなたのキャラクターが拡張Lord of Destructionで作成されている場合、さらに2つのセクションが含まれている場合。
merc兵のセクションは、値jfを備えた2 byteヘッダーから始まり、その後、merc兵が現在着ているアイテムの数を含む4 byteアイテムヘッダーが続きます。アイテムは他のアイテムリストと同様に読み取られます。
キャラクターがネクロマンサーと拡張キャラクターの両方である場合、このセクションは3 byteヘッダーで始まります。最初の2つのバイトはヘッダーkfに続いてhasGolemと呼ばれるブール値です。この値が真である場合、ヘッダーに続く長さ1のアイテムリストがあります。
Converting.mdをご覧ください。