• Страница 1 из 1
  • 1
Модератор форума: Dimitro  
Holidays.dbc ( время событий ) [HELP PLEASE ]
DeathStroke
Скаут
Привет. Отталкиваясь отсюда: https://trinitycore.atlassian.net/wiki/spaces/tc/pages/2130082/Holidays

11 столб - время.

Мой 11 столб: 



Вопрос к знатокам, почему 11 колонка идёт не временем аббревиатурой?
Может я ошибаюсь, мб в клиенте есть уже выставленное время событий?
Как изменить время? Подскажите пожалста с меня плюзики (5шт)
(При изменении этого параметра, например как в гайде на время, то события просто нет в календаре.)
Сообщение # 1 отредактировано DeathStroke - Суббота, 26.05.2018, 14:55
p620
Маршал
Воспользуйтесь другим .dbc редактором. Этот интерпретирует данные колонки как число с плавающей точкой и пытается отобразить его в десятичной экспоненциальной форме. О реальном формате этого поля можно прочитать здесь.
Сообщение # 2 написано 26.05.2018 в 16:12
DeathStroke
Скаут
Посоветовать можете какие нибудь?

Добавлено (26.05.2018, 17:33)
---------------------------------------------
Качал несколько других dbc editor'ов, некоторые выдавали опять те же цифры а некоторые начали выдавать вот это: 536855424
Далее решил скачать новый dbcutil и он тоже выдал эти цифры

Сообщение # 3 написано 26.05.2018 в 17:33
p620
Маршал
Они и должны в целочисленной беззнаковой форме представляться. Я выше прилагал ссылку на описание формата. По поводу нового редактора .dbc - посмотрите здесь.
Сообщение # 4 написано 26.05.2018 в 18:28
DeathStroke
Скаут
Цитата p620 ()
Они и должны в целочисленной беззнаковой форме представляться. Я выше прилагал ссылку на описание формата. По поводу нового редактора .dbc - посмотрите здесь.Сп
Спасибо за редактор, однако очень помог. Плюсы закидываю.
Скажите ещё пожалуйста такой момент. Как именно расшифровать эти цифры по дате: 536855424
В игре отображается как 14:00
Мне нужно поменять время нового ивента например на 19:00.

Скриншот:


Сайт который Вы выше кидали - спасибо, в некоторых моментах я разобрался и нашел ответ на нужные вопросы, но вот дата до сих пор меня мучает sad
Сообщение # 5 написано 27.05.2018 в 12:15
p620
Маршал
А что Вас, собственно, смутило? Там прямым текстом написано, как интерпретируются данные.
Цитата
Packed blizzdate (integers with bits (LSB->MSB) 6: minutes, 5: hours, 3: day of week, 6: day of month, 4: month, 5: year, 2: time zone, last bit unused) - Epochdate=01.01.2000-00:00


"Упакованные" даты, представлены целыми x32 числами. Далее, от младшего бита к старшему, перечисление:
Первые 6 битов - минуты, следующие 5 битов - часы, следующие 3 - день недели, следующие 6 - день месяца, следующие 4 - месяц, следующие 5 - год, следующие 2 - часовая зона, последний не используется (6 + 5 + 3 + 6 + 4 + 5 + 2 + 1 = 32).
Таким образом, для получения значения конкретного параметра вычисляем '(val >> x) & y', где 'val' - значение колонки, 'x' - количество битов, предшествующих битам параметра, а 'y' - маска с количеством установленных в единицу битов равным количеству битов, занимаемых параметром. '>>' - побитовый сдвиг вправо (Bitwise Right Shift), '&' - побитовое И (Bitwise AND).
Для сборки итогового значения из набора параметров требуется совершить обратный набор действий. 'val | (x << y)'. Здесь 'x' - "неупакованное" значение параметра, 'y' - количество битов, предшествующих битам целевого параметра, 'val' - как и в предыдущем примере, итоговое значение. '|' - побитовое ИЛИ (Bitwise OR), '<<' - побитовый сдвиг влево (Bitwise Left Shift).
В целях облегчения понимания, пример. Ваше последнее сообщение (15 м., 12 ч., Вс. (0), 27, 5, 18 (учитывая, что отсчет начинается с 2000 года, согласно спецификации формата) ) записывается в "упакованном" формате следующим образом:
Код
(15 & 63) << 0 | (12 & 31) << 0 + 6 | (0 & 3) << 0 + 6 + 5 | (26 & 63) << 0 + 6 + 5 + 3 | (4 & 15) << 0 + 6 + 5 + 3 + 6 | (18 & 31) << 0 + 6 + 5 + 3 + 6 + 4 | (0 & 3) << 0 + 6 + 5 + 3 + 6 + 4 + 5
= 15 | 768 | 0 | 425984 | 4194304 | 301989888 | 0 = 306610959 (0x1246830F)


Многие из представленных действий записывать нужды не было (все Bitwise AND, а также сложения констант), они приведены исключительно для облегчения понимания демонстрируемых манипуляций. Временная зона была записана как 0, поскольку формат ее записи (какие часовые пояса с каким значением (всего их 4) соотносятся) необходимо устанавливать опытным путем.
Сообщение # 6 отредактировано p620 - Среда, 13.02.2019, 16:29
DeathStroke
Скаут
тяжко)))
но спасибо за ответ, мб сёрфить буду

Добавлено (28.05.2018, 17:20)
---------------------------------------------

Цитата p620 ()
p620

дабы не создавать 2.000.000 тем, спрошу тут. Так как Вы гуру этого форума smile
Подскажите пожалуйста. Хочу впихнуть звание в ачивку. Ачивку создал, в бд так же закинул, сделал для клиента и сервера - ачивка работает и засчитывается от нужного моба.
Не могу найти проводник который будет за это достижение давать звание.
Сделал звание, залил на сервер и клиент, работает и отображается, все отлично.
Подскажите пожалуйста, куда тыкать?

P.s (В награды за достижение вписал: "Наградное звание: Мастер")

Добавлено (28.05.2018, 17:32)
---------------------------------------------
Отбой, ракушкин мозг забыл добавить в бд действие за ачивку.
Разобрался

Добавлено (28.05.2018, 19:42)
---------------------------------------------
Другой вопрос, не могу уже битый день найти dbc или какой то файл который отвечает за отдаление камеры, не подскажите где можно найти?

Сообщение # 7 написано 28.05.2018 в 19:42
p620
Маршал
Цитата DeathStroke ()
который отвечает за отдаление камеры

Это Вы о чем сейчас пишете? На своей/измененной карте, надо полагать, происходит?
Сообщение # 8 написано 28.05.2018 в 23:53
DeathStroke
Скаут
Нет, просто камеру отдалить чуть дальше, ибо боссы немного большие а камера прям в ногах..

Добавлено (29.05.2018, 00:40)
---------------------------------------------
То есть она отдаляется но до предела, и этого мало.
Как в клиенте изменить отдаление камеры чуть чуть подальше?

Сообщение # 9 написано 29.05.2018 в 00:40
Tehnokrat011
Капрал
Это не файл, а нужно модифицировать клиент


Код
char __cdecl ValidateCameraDistance(int a1, int a2, int strVar)
{
  double distance; // st7@1
  char result; // al@3

  distance = SStrToFloat(strVar);
  if ( distance < 0.0 || distance > 50.0 )
  {
    ConsoleWriteA("Value out of range (%f - %f)\n", 0, 0.0, 50.0);
    result = 0;
  }
  else
  {
    result = 1;
  }
  return result;
}


константа 50.0f лежит по адресу (not rebased)


Цитата
.rdata:00A1E2FC 00 00 48 42                 flt_A1E2FC      dd 50.0                 ; DATA XREF: ValidateCameraDistance+17r

Сами глобальные переменные:
Регистрация, как видно, дефолтное значение дистанции 15.0f, множитель 1

 
Цитата
s_cameraDistanceMax = CVar::Register("cameraDistanceMax", 0, 16, "15.0", (int)ValidateCameraDistance, 5, 0, 0, 0);
s_cameraDistanceMaxFactor = CVar::Register("cameraDistanceMaxFactor", 0, 16, "1.0", 0, 5, 0, 0, 0);


Адреса

Цитата
.data:00C24988 ?? ?? ?? ??                 s_cameraDistanceMaxFactor dd ?
.data:00C2498C ?? ?? ?? ??                 s_cameraDistanceMax dd ?
Disassembling, Intercepting/Hooking, Sniffing, Cryptography, Cracking - D.I.S.C.C )
IDA - is the best disassembler, SoftICE - is good debugger :) ©
Programming, Hacking, Reverse Engineering - is everything!
Да иди ты в ...регистр eax )
The world is not enough....
Сообщение # 10 отредактировано Tehnokrat011 - Вторник, 29.05.2018, 10:09
zzzzzz_1983
Скаут
p620, Прошу подскажите мне пожалуйста про смещения. Вот у нас есть допустим число 536855424. Я это число перевожу в бинарный вид? И потом смещаю на ‘х’ битов вправо, а ‘y’ как мне тогда применить? Или я неправильно понял? Прошу объясните пожалуйста.
Сообщение # 11 написано 09.02.2019 в 10:19
p620
Маршал
Цитата zzzzzz_1983 ()
p620, Прошу подскажите мне пожалуйста про смещения. Вот у нас есть допустим число 536855424. Я это число перевожу в бинарный вид? И потом смещаю на ‘х’ битов вправо, а ‘y’ как мне тогда применить? Или я неправильно понял? Прошу объясните пожалуйста.


Цитата p620 ()
Таким образом, для получения значения конкретного параметра вычисляем '(val >> x) & y', где 'val' - значение колонки, 'x' - количество битов, предшествующих битам параметра, а 'y' - маска с количеством установленных в единицу битов равным количеству битов, занимаемых параметром. '>>' - побитовый сдвиг вправо (Bitwise Right Shift), '&' - побитовое И (Bitwise AND).


Здесь написано, как 'y' применять. Побитовое И двух неотрицательных целых чисел Вы можете так воспринимать: вернуть число, в котором установлены только те биты, которые установлены в обоих операндах (вернуть общие единицы). В данном случае это применяется для вычленения подзначения из значения.
Рассмотрим простейший пример. Нам дано x16 целое неотрицательное число 26070, подзначение в котором находится с 8 по 11 биты (включительно), если нумерацию начинать с нуля. В бинарном виде оно записывается следующим образом (биты подзначения выделены):

0 1 1 0 0 1 0 1 1 1 0 1 0 1 1 0 (26070d)

Это подзначение нам надлежит извлечь. Для начала сделаем младший разряд подзначения младшим разрядом значения, для этого побитово сдвинем число вправо на количество неинтересующих нас младших битов (8): 26070d >> 8 = 101d

0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 (101d)

Как можно видеть, 8 старших разрядов утратили свои значения и теперь заполнены нулями. Значения интересующих же нас 4 битов теперь занимают младшие разряды числа. Остается каким-то образом отбросить все следующие за ними старшие разряды, чтобы "в остатке" получить только интересующие нас разряды. Для этого и применяется побитовое И и его свойство "возвращать общие единицы". Мы используем число 15d (в бинарном представлении: 1111b), т.е. такое, в котором в единицы установлены биты только тех разрядов, которые попадают в порядковый диапазон целевого подзначения (первые четыре). Получаем: 101d & 15d = 5

  0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 (101d)
&
                                      1 1 1 1 (15d)
______________________________
  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 (5)

Подзначение извлечено.
Сообщение # 12 отредактировано p620 - Суббота, 09.02.2019, 16:04
zzzzzz_1983
Скаут
Спасибо Огромнейшее, за то, что показали. Т.е. как я понимаю каждый столбец это или часы, или минуты. И их я извлекаю т.е. целиком дата не содержится в одном столбце.
Или снова не правильно. Вся сложность заключается в том, что ядро, которое я использую требует чтобы таблица holiday_dates была заполнена. И без нее не видит праздник, лунный фестиваль например.
Сообщение # 13 написано 09.02.2019 в 17:24
p620
Маршал
Цитата zzzzzz_1983 ()
Т.е. как я понимаю каждый столбец это или часы, или минуты. И их я извлекаю т.е. целиком дата не содержится в одном столбце.


Я начал было расписывать Вам пример, как внезапно обнаружил, что данные, приведенные на скриншоте DeathStroke, распаковываются по спецификации с wowdev.wiki в какую-то ересь. Например, Ваш вариант (536855424d), отмеченный в т.ч. на скриншоте, имеет бинарную форму 00011111`11111111`11000011`10000000b. Если следовать приведенной на вики спецификации
Цитата
Packed blizzdate (integers with bits (LSB->MSB) 6: minutes, 5: hours, 3: day of week, 6: day of month, 4: month, 5: year, 2: time zone, last bit unused) - Epochdate=01.01.2000-00:00


,
выходит, что выделенные под месяц 4 разряда (20-23 включительно) в данном случае все установлены в 1, что даст месяц (в современной норме <= 12) 15, а год (следующие 5 битов) 2031, что есть определенно абсурд. С другой стороны, часть со временем суток корректна и соответствует заявлению
Цитата DeathStroke ()
Скажите ещё пожалуйста такой момент. Как именно расшифровать эти цифры по дате: 536855424
В игре отображается как 14:00


, т.к. 6 минутных разрядов здесь сброшены (0 минут), а в следующих за ними пяти часовых записано 01110b, что действительно соответствует 14d.
Однако, следующие 6 разрядов, которые, согласно вышеупомянутой спецификации, должны распаковываться в день месяца (т.е. <= 31) снова все установлены в единицу и дают 63. Более того, следует отметить, что именно по этой причине шесть разрядов для записи дня месяца и не требуется, хватит пяти (2 ** 5 - 1 = 31).
В связи с этим, zzzzzz_1983, прошу Вас сообщить, как рассматриваемую в примере дату (536855424d) представляет клиент, дабы можно было попытаться установить реальную спецификацию формата.
Сообщение # 14 отредактировано p620 - Суббота, 09.02.2019, 20:47
zzzzzz_1983
Скаут
Вот просто огромнейшее человеческое спасибо. Даже незнаю как благодарить, единственный человек, который как то помогает новичкам. Одними плюсами тут не обойтись =) 
К сожалению не могу вставить скриншот с программы. 
Вот что у меня в holiday.dbc
101104000      118749568          135346560         151386496    169048448  184924160    201684992  218429440 Это все в полях от 11 до 18 ти. по Х начинается с 11 и до 18 ти. А по Y 10, и не меняется. 

В базе данных в таблице у меня тоже идет 8 дат я так понимаю, но они отличаются от этих. 
   id     date_id        date_value
 327       7              218529792 
327        8            235192320 
327         9          252952576 
327      10          269484032 
327      11         2 85540352 
327     12         303169536 
327    13        319209472

И в календаре показано что фестиваль начался 28.01.2019 и закончится 17.02.2019. 
пробовал все это через EpochCalculator какая то ересь получается.
Сообщение # 15 написано 09.02.2019 в 21:35
p620
Маршал
Цитата zzzzzz_1983 ()
Это все в полях от 11 до 18 ти. по Х начинается с 11 и до 18 ти. А по Y 10, и не меняется.
 

Можно вот это расшифровать? Какой X и какой Y? С какими датами эти числа из Holiday.dbc соотносятся?
Сообщение # 16 написано 10.02.2019 в 01:46
zzzzzz_1983
Скаут


Добавлено (10.02.2019, 18:19)
---------------------------------------------
Эта строка относится к празднику 'Лунный фестиваль'

Добавлено (10.02.2019, 18:21)
---------------------------------------------
Я не думаю что игра берет отсюда эти даты. Скорее всего все таки из таблицы в базе данных.
Но и это не меняет ничего. Дату то я пока не могу расшифровать =)

Добавлено (11.02.2019, 12:33)
---------------------------------------------
Приветствую, p620 =)
Я тут попробовал сделать следующее.
Взял число из Holidays.dbc перевел его в бинарный вид.
И пошел следующим путем
Первые шесть бит записал значение, и сместил вправо на 5 бит. Записал следующие 5 и также сместил вправо на 3 и т.д..
Packed blizzdate (integers with bits (LSB->MSB) 6: minutes, 5: hours, 3: day of week, 6: day of month, 4: month, 5: year, 2: time zone, last bit unused) - Epochdate=01.01.2000-00:00

Как Вы считаете имеет место быть ?
Или же это неправильно.
С Уважением, Владимир!

Добавлено (11.02.2019, 15:00)
---------------------------------------------
Вроде бы правильно. И получается нормальные даты получить. А вот обратно собрать не получается =)

Сообщение # 17 отредактировано zzzzzz_1983 - Понедельник, 11.02.2019, 13:18
p620
Маршал
Цитата zzzzzz_1983 ()
Я не думаю что игра берет отсюда эти даты. Скорее всего все таки из таблицы в базе данных.
Но и это не меняет ничего. Дату то я пока не могу расшифровать =)


Для календаря - именно отсюда.
Цитата zzzzzz_1983 ()
Вроде бы правильно. И получается нормальные даты получить. А вот обратно собрать не получается =)


Я же выше пример разобрал: дата 536855424 соответствует 64/16/2031 (DD/MM/YYYY) 14:00, т.к. в ней все биты года, месяца и дня (согласно приведенной спецификации) выставлены в единицу. Как Вам кажется, это нормальная дата?
Цитата zzzzzz_1983 ()
Эта строка относится к празднику 'Лунный фестиваль'


Вот я Вас и попросил мне выписать реальные даты из календаря, соответствующие этим записям, чтобы я мог уточнить формат.
Сообщение # 18 написано 11.02.2019 в 17:19
zzzzzz_1983
Скаут
Если Вы про пример, то если поле 12 в dbc пустое. То год отбрасывается.
Так было написано. Packed blizzdate - Epochdate=01.01.2000-00:00 - Year is discarded if column12 is 0

Добавлено (11.02.2019, 18:18)
---------------------------------------------
Я только что пересчитал все цифры которые я писал выше. почти везде ересь написана.
Из таблицы dbc там хотя-бы что-то получается. сегодня приду домой с работы, посмотрю обязательно и отпишусь.

Добавлено (11.02.2019, 23:03)
---------------------------------------------
Приветствую!
У меня даты в календарь не берутся из файла Holidays.dbc, я очистил строку с 11 по 18 столбец.
И ничего не изменилось.
А вот когда добавил в базу данных при очищенном Holidays.dbc. вот эти значения:

218529792         27 января 2013 года  00:01 - 16 февраля 2013  23:59
235192320         20 января 2014 года  00:01 - 09 февраля 2014  23:59
252952576         16 февраля 2015 года 00:01 -  08 марта 2015 23:59
269484032         1 февраля 2016 года 00:01 -  21 февраля 2016 года 23:59
285540352         21 января 2017 года 00:01 -   10 февраля 2017 года 23:59
303169536         09 февраля 2018 года 00:01 -  01 марта 2018 года 23:59
319209472         28 января 2019 года 00:01  -  17 февраля 2019 года 23:59

В таблицу holiday_dates то в календаре появились даты.

Вот как то так.

Добавлено (12.02.2019, 15:23)
---------------------------------------------
Приветствую р620, Я вот нашел на сайте ядра вот такую функцию.
void ByteBuffer::AppendPackedTime     (     time_t      time    )     
{
tm lt;
localtime_r(&time, <);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}

Правда не понимаю как получается это 319209472. Потому как скорее всего упаковано это число.

Сообщение # 19 отредактировано zzzzzz_1983 - Понедельник, 11.02.2019, 23:04
p620
Маршал
Цитата zzzzzz_1983 ()
Приветствую р620, Я вот нашел на сайте ядра вот такую функцию.


Хотел порекомендовать оборачивать сниппеты тэгом `code`, чтобы не билось содержимое (как у Вас на четвертой строке, например), но оказалось, что оно бьется в любом случае... Используйте `&`, за которым сразу следует `amp`, вместо одинокого символа '&', если будете публиковать содержащий этот символ код на этом портале. Не публикуйте код на этом портале, используйте что-то вроде PasteBin (здесь бьется даже экранированный символ).

Этот метод принимает POSIX timestamp, разворачивает его потокобезопасной (судя по всему) версией библиотечного функционала в т.н. "календарное время", которое затем снова перепаковывает в x32 беззнаковое целое и добавляет во внутренний буфер объекта, относительно которого изначально и вызывался.
Согласно официальной спецификации, поле `tm_year` содержит кол-во лет, прошедших с 1900 года; здесь из этого числа вычетается еще сотня (что следует учитывать при обратной распаковке, т.е. конечное значение надлежит отсчитывать от 2000 года). Месяцы пакуются в неизменном виде, т.к. хранят смещение относительно января (т.е. значение в диапазоне [0, 11]), а вот из дней вычетается единица, поскольку значение `tm_mday` соответствует диапазону [1, 31] (конкретной дате), а packed blizzdate требует [0, 30], т.к., как и в случае с месяцами, рассчитано на хранение смещения относительно первого дня месяца, а не на конкретную готовую дату. `tm_wday` соответствует индексу дня недели (по порядку: 0 - воскресенье, 6 - суббота). Часы и минуты соответствуют 24-часовому формату. Все смещения, по которым упаковываются компоненты даты в целевой четырехбайтовый буфер, соответствуют вышеупомянутой информации с wowdev.wiki.
Сообщение # 20 отредактировано p620 - Вторник, 12.02.2019, 19:48
zzzzzz_1983
Скаут
Чего-то я не совсем понимаю. Вы могли бы раскрыть одну дату ? Например вот эту.319209472
Потому что я все таки не такой специалист, далеко не такой. Я только учусь.
Сообщение # 21 написано 12.02.2019 в 22:16
Tehnokrat011
Капрал
Вот так перепаковывается db время в WoW - тут
Не путать с WoWTime - это особое отдельное специальное время, содержащее в себе еще и некие флаги диапазона дат.

И вы неправильно понимаете преднзначение dbc - dbc нужен серверу, чтобы извлекать из этих таблицы данные. ТО, что вы очистите их, не повлияет на работу клиента, у него есть свои, по которым он ориентируется. Просто ваши даты работают потому, что с сервера можно манипулировать клиентским календарем через таблицу holiday_dates. Если бы календарь был чисто клиентский и строго захардкоржен в dbc - то после 2017 или 2018 года (не помню) на всех клиентах WotLK 3.3.5 календарь бы перестал работать.

Так выглядит структура dbc на 4.0.1 версии, что думаю не изменилось и с вашим 4.3.4.


Цитата
struct HolidaysRec
{
uint32    m_ID;
uint32    m_duration[10];
uint32    m_date[26];
uint32    m_region;
uint32    m_looping;
uint32    m_calendarFlags[10];
uint32    m_holidayNameID;
uint32    m_holidayDescriptionID;
string     m_textureFilename;
uint32    m_priority;
uint32    m_calendarFilterType;
uint32    m_flags;
};
Disassembling, Intercepting/Hooking, Sniffing, Cryptography, Cracking - D.I.S.C.C )
IDA - is the best disassembler, SoftICE - is good debugger :) ©
Programming, Hacking, Reverse Engineering - is everything!
Да иди ты в ...регистр eax )
The world is not enough....
Сообщение # 22 написано 13.02.2019 в 01:46
p620
Маршал
Судя по информации, любезно предоставленной Tehnokrat011 (за что ему отдельное спасибо), "абсурдные" компоненты дат - реальная часть формата, которая выфильтровывается кодом клиента. Рассмотрим наш старый пример (536855424, 64/16/2031 (DD/MM/YYYY) 14:00), следуя обновленному алгоритму (с надеждой, что символ '&' нигде не засчитается за сигнал управляющей последовательности):
Распаковка из packedBlizzDate:
Код
minutes = packedBlizzDate & 0b111111; /* минуты */
if(minutes == 0b111111)
  minutes = 0xFF; /* если все биты в подзначении минут установлены в 1 - сделать минуты равными 255 */
hours = packedBlizzDate >> 6 & 0b11111; /* часы */
if(hours == 0b11111)
  hours = 0xFF; /* если все биты в подзначении часов установлены в 1 - сделать часы равными 255 */
/* 3 бита дня недели проигнорированы */
dayIdx = packedBlizzDate >> 14 & 0b111111; /* день */
if(dayIdx == 0b111111)
  dayIdx = -1; /* если все биты в подзначении дня месяца установлены в 1 - сделать день месяца равным -1 */
++dayIdx; /* формат хранит смещение относительно первого дня месяца ([0, 30]); получаем дату сложением смещения с единицей */
monthIdx = packedBlizzDate >> 20 & 0b1111; /* месяц */
if(monthIdx == 0b1111)
  monthIdx = 0xFF; /* если все биты в подзначении месяца установлены в 1 - сделать месяц равным 255 */
++monthIdx; /* формат хранит смещение относительно первого месяца года ([0, 11]); получаем дату сложением смещения с единицей */
year = packedBlizzDate >> 24 & 0b11111; /* год */
if(year == 0b11111)
  year = 0xFF; /* если все биты в подзначении года установлены в 1 - сделать год равным 255 */
year += 2000; /* формат хранит смещение от начала третьего тысячелетия; получаем дату сложением смещения с двумя тысячами */
/* два бита "часовой зоны" проигнорированы */


Упаковка в packedBlizzDate:
Код
/* инверсия распаковки (биты дня недели и "часовой зоны" по-прежнему игнорируются) */
packedBlizzDate = minutes & 0b111111 | (hours & 0b11111) << 6 | (dayIdx - 1 & 0b111111) << 14 | (monthIdx - 1 & 0b1111) << 20 | (year - 2000 & 0b11111) << 24;


Разбор примера:
Код
minutes = 0; /* 536855424 & 0b111111 */
hours = 14; /* 536855424 >> 6 & 0b11111 */
dayIdx = 0; /* 536855424 >> 14 & 0b111111; if(x == 0b111111) x = -1; ++x */
monthIdx = 256; /* 536855424 >> 20 & 0b1111; if(x == 0b1111) x = 255; ++x */
year = 2255; /* 536855424 >> 24 & 0b11111; if(x == 0b11111) x = 255; x += 2000 */


Результат:
00/256/2255 (DD/MMM/YYYY ?!) 14:00
Делаем вывод, что Метелица все еще "держит уровень" и задаемся закономерным вопросом: "Как интерпретировать особые случаи, которые отлавливаются проверками на этапе распаковки, ибо, как следует из многострадального рассмотренного примера, они очень даже встречаются?"

Я на этот вопрос ответить не могу, поскольку на данный момент не имею возможности реверсить клиент. Возможно, на него ответит Tehnokrat011.
В противном случае устанавливать способ интерпретации Вам придется опытным путем, zzzzzz_1983.
Сообщение # 23 отредактировано p620 - Среда, 13.02.2019, 03:36
Tehnokrat011
Капрал
Судя по данным клиента, на вики написана ересь и как раз этот формат (о котором писал выше) является PackedTime, что используется в пакетах и интерфейсе WoW

Из парсера ТК

Цитата
public static DateTime GetDateTimeFromGameTime(int packedDate)

{
var minute = packedDate & 0x3F;
var hour = (packedDate >> 6) & 0x1F;
// var weekDay = (packedDate >> 11) & 7;
var day = (packedDate >> 14) & 0x3F;
var month = (packedDate >> 20) & 0xF;
var year = (packedDate >> 24) & 0x1F;
// var flags = (packedDate >> 29) & 3; always 0

return new DateTime(2000, 1, 1).AddYears(year).AddMonths(month).AddDays(day).AddHours(hour).AddMinutes(minute);
}


Дата 536855424 действительно распаковывается в странную вещь, но клиент просто отбрасывает те значения, которые не соответствуют, вот эти 255, ничто иное, как -1, маркер, что поле "пустое" или "не используется", потому что исходная структура WoWTime (не путать опять же с форматом для пакетов, в котором дни недели скажем не используются) выглядит так
Конструктор WoWTime класса.

Цитата
WoWTime *__thiscall WowTime::WowTime(WoWTime *this)
{
WoWTime *result; // eax@1

result = this;
this->m_minute = -1;
this->m_hour = -1;
this->m_weekDay = -1;
this->m_monthDay = -1;
this->m_month = -1;
this->m_year = -1;
this->m_flags = 0;
this->m_unused = 0;
return result;
}
Disassembling, Intercepting/Hooking, Sniffing, Cryptography, Cracking - D.I.S.C.C )
IDA - is the best disassembler, SoftICE - is good debugger :) ©
Programming, Hacking, Reverse Engineering - is everything!
Да иди ты в ...регистр eax )
The world is not enough....
Сообщение # 24 отредактировано Tehnokrat011 - Среда, 13.02.2019, 12:59
zzzzzz_1983
Скаут
Спасибо Вам огромное tehnokrat011 и p620. Буду изучать полученные ответы.
Сообщение # 25 написано 13.02.2019 в 15:51
p620
Маршал
Цитата Tehnokrat011 ()
но клиент просто отбрасывает те значения, которые не соответствуют, вот эти 255, ничто иное, как -1, маркер, что поле "пустое" или "не используется", потому что исходная структура WoWTime


Так это то как раз очевидно, но даты с такими данными предназначаются для календаря. Вопрос в том, как они в этой связи дальше обрабатываются.
Цитата Tehnokrat011 ()
Судя по данным клиента, на вики написана ересь и как раз этот формат (о котором писал выше) является PackedTime, что используется в пакетах и интерфейсе WoW


В чем противоречие? На вики ведь описано точно то же самое, что Вы предоставили в своих сниппетах.
Сообщение # 26 написано 13.02.2019 в 16:07
zzzzzz_1983
Скаут
Спасибо вам обоим за такую поддержку.
Я написал простенькую программку для упаковки и распаковки дат на основе метода который был выше.
Сегодня приеду домой и проверю на лунном фестивале =)

Добавлено (13.02.2019, 19:27)
---------------------------------------------
Подскажите есть хороший сайт помимо тринити, где можно больше прочитать про скрипты для ядра.
Просто в моем ядре от тринити многие квесты не исправлены..

Добавлено (13.02.2019, 20:47)
---------------------------------------------
Проверил только что упаковать дату.
Все работает.
В календаре отображается дата, которая была заложена.

Сообщение # 27 написано 13.02.2019 в 19:24
Tehnokrat011
Капрал
Цитата p620 ()
Так это то как раз очевидно, но даты с такими данными предназначаются для календаря. Вопрос в том, как они в этой связи дальше обрабатываются.


Да никак, например в функции WoWTime::GetTimeString для ачивок просто игнорируются эти кусочки, там вывод идет на основании значений, который больше 0. Остальное является текущей датой, текущий год, месяц и т.д. Там несколько функций еще в этом классе, которые считают это.

Цитата p620 ()
В чем противоречие? На вики ведь описано точно то же самое, что Вы предоставили в своих сниппетах.


timeZone там нету вообще, ну мб они так назвали m_flags, weekDay тоже для этих данных (конкретно для Holidays.dbc) не используется и даже не упаковывается. Тут стоит говорить о 2 форматах времени, но очень похожих. Странно, что у близов второй формат называется вроде бы так же WoWTime (из функций а-ля WowTime::WowDecodeTimeToDbDate), однако не упаковывает некоторые части.
Disassembling, Intercepting/Hooking, Sniffing, Cryptography, Cracking - D.I.S.C.C )
IDA - is the best disassembler, SoftICE - is good debugger :) ©
Programming, Hacking, Reverse Engineering - is everything!
Да иди ты в ...регистр eax )
The world is not enough....
Сообщение # 28 написано 13.02.2019 в 20:56
p620
Маршал
Цитата Tehnokrat011 ()
Остальное является текущей датой, текущий год, месяц и т.д.


Вот, теперь ясно.
Цитата Tehnokrat011 ()
timeZone там нету вообще, ну мб они так назвали m_flags


Именно так.
Сообщение # 29 написано 13.02.2019 в 21:47
  • Страница 1 из 1
  • 1
Поиск: