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 | รหัสเวอร์ชัน |
| 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 | รหัสทักษะปุ่มเมาส์ซ้าย |
| 124 | 4 | รหัสทักษะปุ่มเมาส์ขวา |
| 128 | 4 | ID ทักษะการสลับปุ่มเมาส์ซ้าย |
| 132 | 4 | ID ทักษะการสลับปุ่มเมาส์ขวา |
| 136 | 32 | ลักษณะเมนูตัวละคร |
| 168 | 3 | ความยากลำบาก |
| 171 | 4 | รหัสแผนที่ |
| 175 | 2 | ไม่รู้จัก |
| 177 | 2 | ทหารรับจ้างตาย |
| 179 | 4 | Mercenary ID |
| 183 | 2 | ชื่อ Mercenary Name 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 |
|---|---|---|---|---|---|---|---|
| - | บันไดปีน | การขยายตัว | - | เสียชีวิต | ไม่ยอมใครง่ายๆ | - | - |
ยังไม่ได้ดำเนินการ
ค่าจะเพิ่มขึ้นทุกครั้งที่คุณฆ่าเจ้านายการกระทำ
| ค่า | มาตรฐาน | ไม่ยอมใครง่ายๆ |
|---|---|---|
| 0-3 | - | - |
| 4-7 | เซอร์/ดาม | เคานต์/เคานท์เตส |
| 8-11 | ลอร์ด/เลดี้ | Duke/Duchess |
| 12 | บารอน/บารอน | กษัตริย์/ราชินี |
| ค่า | การขยายตัว | ไม่ยอมใครง่ายๆ |
|---|---|---|
| 0-3 | - | - |
| 5-8 | คนสังหาร | ผู้ทำลาย |
| 10-13 | แชมป์ | ผู้ชนะ |
| 15 | ผู้เฒ่า | ผู้ปกครอง |
คลาสอักขระคือ byte ที่ค่าที่แตกต่างกันเป็นตัวแทนของคลาส
| ระดับ | ค่า |
|---|---|
| อเมซอน | 0x00 |
| แม่มด | 0x01 |
| ผู้ตรวจการตรวจคนหนึ่ง | 0x02 |
| พาลาดิน | 0x03 |
| คนป่าเถื่อน | 0x04 |
| ดรูอิด | 0x05 |
| นักฆ่า | 0x06 |
การเล่นครั้งล่าสุดจะถูกบันทึกเป็น unit32 UNIX TIMESTAMP เช่น 1495882861
ส่วนทักษะที่ได้รับมอบหมายคืออาร์เรย์ของรหัสทักษะ 16 รายการแต่ละจำนวนเต็ม 4 byte (UINT32) หากไม่มีการกำหนดทักษะค่าคือ 0x00
โครงสร้างเควสต์คือ 298 byte ที่อธิบายเควสทั้งหมดในเกม แต่ยังมีข้อมูลเกี่ยวกับการเดินทาง ACT และการแนะนำ NPC แต่ละภารกิจมีความยาว 2 byte
| ชดเชย | ไบต์ | เนื้อหา |
|---|---|---|
| 335 | 4 | แอ่ว! |
| 339 | 6 | ไม่รู้จัก |
เควสต์มีความยาว 2 byte ฉันได้สร้างโครงสร้าง quest ทั่วไปที่เก็บข้อมูลที่สำคัญที่สุดของภารกิจหากเสร็จสมบูรณ์หรือไม่ แต่ละภารกิจมีชุดบิตที่ไม่เหมือนใครมากมายขึ้นอยู่กับเหตุการณ์สำคัญที่แตกต่างกันของภารกิจ ตัวอย่างเช่นหากคุณบริโภคการต่อต้านการต่อต้านจากภารกิจ "Prison of Ice" หรือไม่
| นิดหน่อย | คำอธิบาย |
|---|---|
| 0 | Quest เสร็จสมบูรณ์ |
Prison of Ice เป็นภารกิจเดียวที่ฉันใส่ใจที่จะนำไปใช้เพราะฉันจำเป็นต้องรู้ว่าตัวละครมีความต้านทานเพิ่มขึ้นจากการเลื่อนหรือไม่
| นิดหน่อย | คำอธิบาย |
|---|---|
| 0 | Quest เสร็จสมบูรณ์ |
| 7 | ม้วนวินิจฉัย |
โครงสร้างนี้ทำซ้ำตัวเอง 3 ครั้งหนึ่งครั้งสำหรับปกติฝันร้ายและนรก ออฟเซ็ตคือการชดเชยในโครงสร้างเควส
| ชดเชย | ไบต์ | คำอธิบาย |
|---|---|---|
| 0 | 2 | ตั้งค่าเป็น 1 หากคุณได้รับการแนะนำให้รู้จักกับ Warriv ใน Act I. |
| 2 | [6]quest | ทั้งหกเควสสำหรับ Act I. |
| 14 | 2 | ตั้งค่าเป็น 1 ถ้าคุณเดินทางไปยัง Act II |
| 16 | 2 | ตั้งค่าเป็น 1 ถ้าคุณได้รับการแนะนำให้รู้จักกับ Jerhyn |
| 18 | [6]quest | ทั้งหกเควสสำหรับ Act II |
| 30 | 2 | ตั้งค่าเป็น 1 ถ้าคุณเดินทางไปยัง Act III |
| 32 | 2 | ตั้งค่าเป็น 1 ถ้าคุณได้รับการแนะนำให้รู้จักกับ Hratli |
| 34 | [6]quest | ทั้งหกเควสสำหรับ Act III |
| 46 | 2 | ตั้งค่าเป็น 1 ถ้าคุณเดินทางไปยัง Act IV |
| 48 | 2 | ตั้งค่าเป็น 1 หากคุณได้รับการแนะนำให้รู้จักกับ Act IV (ซึ่งคุณมีถ้าคุณเดินทาง) |
| 50 | [6]quest | Act IV มีเพียง 3 เควสดังนั้นโครงสร้างมี 6 ไบต์ว่างเปล่าที่นี่ |
| 62 | 2 | ตั้งค่าเป็น 1 ถ้าคุณเดินทางไป Act V. |
| 64 | 2 | ดูเหมือนว่าจะถูกตั้งค่าเป็น 1 หลังจากเสร็จสิ้นความหวาดกลัวและพูดคุยกับคาอินใน Act IV |
| 66 | 4 | ดูเหมือนว่าจะเป็นช่องว่างภายใน |
| 70 | [6]quest | ทั้งหกเควสสำหรับ Act V. |
| 82 | 14 | ช่องว่างภายในบางชนิดหลังจากข้อมูลภารกิจทั้งหมด |
ไม่ได้ดำเนินการ
ไม่ได้ดำเนินการ
การติดตามส่วนหัวคือส่วนแอตทริบิวต์เค้าโครงส่วนนี้ประกอบด้วยอาร์เรย์ของรหัสแอตทริบิวต์ 9 bit ตามด้วยค่าแอตทริบิวต์ความยาว n bit ส่วนถูกยกเลิกโดยค่า 9 bit ที่ 0x1ff เป็นมูลค่าการกล่าวขวัญว่าฟิลด์เหล่านี้กลับด้านเล็กน้อย โดยทั่วไปหากคุณพบ BITS 00100111 พวกเขาจะกลับไปเป็น 11100100
| รหัสประจำตัว | คุณลักษณะ |
|---|---|
| 0 | ความแข็งแกร่ง |
| 1 | พลังงาน |
| 2 | ความคล่องแคล่ว |
| 3 | ความมีชีวิตชีวา |
| 4 | สถิติที่ไม่ได้ใช้ |
| 5 | ทักษะที่ไม่ได้ใช้ |
| 6 | HP ปัจจุบัน |
| 7 | สูงสุด HP |
| 8 | มานาปัจจุบัน |
| 9 | Max Mana |
| 10 | ความแข็งแกร่งในปัจจุบัน |
| 11 | ความแข็งแกร่งสูงสุด |
| 12 | ระดับ |
| 13 | ประสบการณ์ |
| 14 | ทอง |
| 15 | ทองคำ |
| ความยาวบิต | คุณลักษณะ |
|---|---|
| 10 | ความแข็งแกร่ง |
| 10 | พลังงาน |
| 10 | ความคล่องแคล่ว |
| 10 | ความมีชีวิตชีวา |
| 10 | สถิติที่ไม่ได้ใช้ |
| 8 | ทักษะที่ไม่ได้ใช้ |
| 21 | HP ปัจจุบัน |
| 21 | สูงสุด HP |
| 21 | มานาปัจจุบัน |
| 21 | Max Mana |
| 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 รายการลงในแผนที่ ตัวอย่างเช่น Assassin มีการชดเชย 251 ซึ่งหมายความว่าทักษะ Assassin อยู่ระหว่างดัชนี 251 และ 281 ซึ่งเป็นดัชนี 30 อย่างแน่นอน
| พิมพ์ | ไบต์ | ค่า |
|---|---|---|
| ส่วนหัว | 2 | if |
| ทักษะ | 30 | [30] ทักษะ |
| ระดับ | ชดเชย |
|---|---|
| อเมซอน | 6 |
| แม่มด | 36 |
| ผู้ตรวจการตรวจคนหนึ่ง | 66 |
| พาลาดิน | 96 |
| คนป่าเถื่อน | 126 |
| ดรูอิด | 221 |
| นักฆ่า | 251 |
นี่เป็นส่วนที่ยากที่สุดในการอ่าน ส่วนรายการเริ่มต้นด้วยส่วนหัว 4 byte ที่มีค่า JM และค่า uint16 ซึ่งเป็นรายการที่นับอักขระของคุณในปัจจุบัน รวมอยู่ในสินค้าคงคลังที่ซ่อนคิวบ์และสายพานรวมอยู่ด้วย
ความยาวไบต์ของส่วนไม่เป็นที่รู้จักก่อนที่จะอ่านอย่างครบถ้วนเนื่องจากความยาวบิตของแต่ละรายการแตกต่างกันไปขึ้นอยู่กับคุณภาพจำนวนซ็อกเก็ตและคุณสมบัติที่มีมนต์ขลังที่มีอยู่
แต่ละรายการเป็นไปตามรูปแบบที่แน่นอนซึ่งก็คือ:
แต่ละรายการเริ่มต้นด้วยข้อมูลง่าย ๆ 111 บิตซึ่งรายการทั้งหมดมี นี่คือข้อมูลเช่นประเภทรายการหากเป็นซ็อกเก็ต ID ตำแหน่งเช่นติดตั้งหรือซ่อนเร้นและอื่น ๆ
แต่ละรายการยังมีบูลีนที่เรียกว่า SimpleItem ซึ่งมีความยาว 1 บิตหากตั้งค่าเป็น 1 รายการไม่มีบิตอีกต่อไปและรายการถัดไปจะเริ่มขึ้น
หากรายการไม่ใช่รายการง่าย ๆ นั่นหมายความว่าจะมีข้อมูลมากมายตาม 111 บิตเริ่มต้น ตัวอย่างเล็ก ๆ น้อย ๆ ของเรื่องนี้คือระดับความหายากคำต่อท้ายเวทมนต์, Magical Affix, ถ้าเป็น Runeword, ส่วนบุคคล, ส่วนหนึ่งของชุด, คลาสเฉพาะและอื่น ๆ
สุดท้าย แต่ไม่ท้ายสุดถ้ารายการนั้นจะมีรายการคุณสมบัติเวทมนตร์ขึ้นอยู่กับว่ามันเป็น Runeword, Magical, หายาก, สร้างขึ้นมาและเป็นเอกลักษณ์ของชุดและอื่น ๆ
รายการเหล่านี้คล้ายกับส่วนแอตทริบิวต์ที่เราจะอ่าน:
9 bit idn bits of magical properties0x1ff terminator เมื่อเรากด Terminator 0x1ff รายการถัดไปจะเริ่มขึ้น
คุณสมบัติที่มีมนต์ขลังเป็นคุณสมบัติที่ไม่ซ้ำกันที่สามารถเกิดขึ้นได้ในรายการแต่ละคุณสมบัติมีความยาวบิตที่แตกต่างกันและแผนที่มีขนาดใหญ่มาก
นี่คือคุณสมบัติที่มีมนต์ขลังที่มี ID 83 ซึ่งมี 2 บิตฟิลด์แต่ละ 3 บิตยาว
83 : {Bits: [] uint { 3 , 3 }, Name : "+{1} to {0} Skill Levels" },คุณสมบัติที่มีมนต์ขลังทั้งหมดถูกแมปในไฟล์ item.go
หากตัวละครของคุณตายไปแล้วและศพอยู่บนพื้นเมื่อคุณเข้าสู่เกมรายการที่ติดตั้งของคุณจะอยู่ใน struct รายการนี้ มันเป็นส่วนหัวของศพ 16 bytes ที่มีส่วนหัว JM ตามด้วยจำนวนรายการที่คล้ายกับรายการรายการ
การอ่านรายการศพจะทำอย่างแน่นอนเป็นส่วนก่อนหน้าของรายการ
หากตัวละครของคุณถูกสร้างขึ้นในการขยายตัวของลอร์ดแห่งการทำลายล้างหากจะมีอีก 2 ส่วน
ส่วนของทหารรับจ้างเริ่มต้นด้วยส่วนหัว 2 byte ที่มีค่า jf และตามด้วยส่วนหัวรายการ 4 byte ที่มีจำนวนรายการที่ทหารรับจ้างสวมใส่อยู่ รายการจะถูกอ่านเหมือนรายการรายการอื่น ๆ
หากตัวละครของคุณเป็นทั้ง Necromancer และตัวละครการขยายตัวส่วนนี้เริ่มต้นด้วยส่วนหัว 3 byte ที่สองไบต์แรกเป็นส่วนหัว kf ตามด้วยบูลีนที่เรียกว่า hasGolem หากค่านี้เป็นจริงมีรายการรายการที่มีความยาว 1 ตามส่วนหัว
โปรดดูการสนับสนุน