D2S - это двоичный анализатор, написанный в Go, который используется для анализа файлов .d2s . Это бинарный формат, который использует Game 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 | Идентификатор навыка кнопки мыши левого обмена |
| 132 | 4 | Идентификатор навыка кнопки мыши правого обмена |
| 136 | 32 | Появление меню персонажа |
| 168 | 3 | Сложность |
| 171 | 4 | Идентификатор карты |
| 175 | 2 | Неизвестный |
| 177 | 2 | Наемник мертв |
| 179 | 4 | Наемник идентификатор |
| 183 | 2 | Идентификатор наемника |
| 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 | Господь/Леди | Герцог/герцогиня |
| 12 | Барон/баронесса | Король/королева |
| Ценить | Расширение | Расширение хардкор |
|---|---|---|
| 0-3 | - | - |
| 5-8 | Убийца | Разрушитель |
| 10-13 | Чемпион | Завоеватель |
| 15 | Патриарх/Матриарх | Опекун |
Класс символов - это byte , где разные значения представляют класс.
| Сорт | Ценить |
|---|---|
| Амазонка | 0x00 |
| Колдунья | 0x01 |
| Некромант | 0x02 |
| Паладин | 0x03 |
| Варвар | 0x04 |
| Друид | 0x05 |
| Убийца | 0x06 |
Последнее воспроизведение сохраняется как unit32 Unix TimeStamp Eg 1495882861 .
Раздел «Назначенные навыки» представляет собой массив из 16 идентификаторов навыков, каждый из которых 4 byte (UINT32). Если навык не назначен, значение составляет 0x00 .
Структура квестов составляет 298 byte , в котором описываются все квесты в игре, но также содержит данные о путешествиях ACT и введения NPC. Каждый квест длиной 2 byte .
| Компенсировать | Байты | Содержание |
|---|---|---|
| 335 | 4 | Верна! |
| 339 | 6 | Неизвестный |
Квест длиной 2 byte , я создал общую quest структуру, которая содержит наиболее важные данные квеста, если он завершен или нет. В каждом квесте есть много уникальных битов, установленных в зависимости от различных этапов квеста. Например, если вы поглотили свиток сопротивления от квеста «тюрьма льда» или нет.
| Кусочек | Описание |
|---|---|
| 0 | Квест завершен |
Тюрьма льда - единственный квест, который я удосужился реализовать, потому что мне нужно было знать, увеличил ли персонаж сопротивление от свитка или нет.
| Кусочек | Описание |
|---|---|
| 0 | Квест завершен |
| 7 | Потребляется свиток |
Эта структура повторяет себя 3 раза, один раз для нормального, кошмара и ада. Смещение - это смещение в Quest Struct.
| Компенсировать | Байты | Описание |
|---|---|---|
| 0 | 2 | Установите 1 , если вы были представлены Warriv в акте I. |
| 2 | [6]quest | Все шесть квестов для акта I. |
| 14 | 2 | Установите 1 если вы отправились в акт II. |
| 16 | 2 | Установите 1 если вы были представлены Jerhyn. |
| 18 | [6]quest | Все шесть квестов для акта II. |
| 30 | 2 | Установите 1 если вы отправились в акт III. |
| 32 | 2 | Установите 1 если вы были представлены в Hratli. |
| 34 | [6]quest | Все шесть квестов для акта III. |
| 46 | 2 | Установите 1 если вы поехали на ACT IV. |
| 48 | 2 | Установите 1 если вы были представлены в ACT IV. (что у вас есть, если вы путешествовали) |
| 50 | [6]quest | ACT IV имеет только 3 квеста, поэтому у структуры здесь 6 пустых байтов. |
| 62 | 2 | Установите 1 если вы поехали на действие V. |
| 64 | 2 | Похоже, что установлен в 1 после завершения конца террора и разговора с Каином в акте IV. |
| 66 | 4 | Кажется, что -то вроде прокладки. |
| 70 | [6]quest | Все шесть квестов для акта V. |
| 82 | 14 | Некоторая заполнение после всех данных квеста. |
Не реализовано
Не реализовано
Следуя заголовка, находится раздел «Атрибуты», этот макет разделов состоит из массива 9 bit идентификатора атрибута, за которым следует значение атрибута длина n bit . Раздел завершается 9 bit значением 0x1ff . Стоит отметить, что эти поля перевернуты. По сути, если вы найдете биты 00100111 они перевернуты на 11100100 .
| ИДЕНТИФИКАТОР | Атрибут |
|---|---|
| 0 | Сила |
| 1 | Энергия |
| 2 | Ловкость |
| 3 | Жизнеспособность |
| 4 | Неиспользованная статистика |
| 5 | Неиспользованные навыки |
| 6 | Текущий HP |
| 7 | Макс |
| 8 | Текущая мана |
| 9 | Макс Мана |
| 10 | Текущая выносливость |
| 11 | Макс выносливости |
| 12 | Уровень |
| 13 | Опыт |
| 14 | Золото |
| 15 | Спрятанное золото |
| Бит длина | Атрибут |
|---|---|
| 10 | Сила |
| 10 | Энергия |
| 10 | Ловкость |
| 10 | Жизнеспособность |
| 10 | Неиспользованная статистика |
| 8 | Неиспользованные навыки |
| 21 | Текущий HP |
| 21 | Макс |
| 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 , и значение uint16 , которое является подсчетом элементов, который в настоящее время имеет ваш персонаж. Оборудование, инвентарь, тайник, куб и ремень включены.
Длина байта секции неизвестна, прежде чем читать его полностью, потому что длина бита каждого элемента варьируется в зависимости от его качества, количества сокетов и магических атрибутов, которыми он обладает.
Каждый элемент следует определенному шаблону, хотя:
Каждый элемент начинается с 111 бит простых данных, которые содержат все элементы. Это информация, такая как тип элемента, если она разъединяется, идентификатор позиции, как оборудование или тайник, и так далее.
Каждый элемент также имеет логический под названием SimpleItem , который составляет 1 бит длиной, если он установлен на 1 , элемент больше не содержит битов, а следующий элемент запускается.
Если элемент не является простым элементом, это означает, что он будет иметь тонны данных после начальных 111 бит. Несколько примеров этого - уровень редкости, магический суффикс, магический аффикс, если это Runword, персонализированный, часть набора, специфичного класса и так далее.
И последнее, но не менее важное, если у предмет будет иметь списки магических свойств в зависимости от того, является ли это Runeword, Magical, Eder, Crastted, уникальной частью сета и так далее.
Эти списки похожи на раздел атрибутов, где мы прочитаем:
9 bit idn bits of magical properties0x1ff terminator Когда мы достигли терминатора 0x1ff начинается следующий элемент.
Волшебное свойство - это уникальное свойство, которое может возникнуть на предмете, каждое свойство имеет разные длина бита, а карта огромна.
Это магическое свойство с ID 83 , которое содержит 2 -битные поля каждые 3 бита длиной.
83 : {Bits: [] uint { 3 , 3 }, Name : "+{1} to {0} Skill Levels" },Все магические свойства отображаются в файле item.go.
Если ваш персонаж в настоящее время мертв, а труп находится на месте, когда вы входите в игру, ваши оборудованные предметы будут в этом элементе. Это заголовок трупа 16 bytes содержащий заголовок JM за которым следует количество предметов, аналогичное списку предметов.
Чтение предметов трупа выполняется точным способом как предыдущий раздел предметов.
Если ваш персонаж создан в расширении лорда разрушения, если будет содержать еще 2 раздела.
Секции наемника начинаются с 2 byte заголовка со значением jf , за которым следует заголовок 4 byte содержащий количество предметов, которые в настоящее время носит наемник. Элементы читаются как любой другой список предметов.
Если ваш персонаж является одновременно как некромантером, так и персонажем расширения, этот раздел начинается с заголовка 3 byte , где первые два байта являются заголовком kf за которым следует логический, называемый hasGolem , если это значение верно, есть список предметов с длиной 1, следующий за заголовком.
Пожалуйста, смотрите Anplying.md.