Перейти к содержимому
Korean Random

Monstrofil

Пользователь
  • Публикации

    53
  • Зарегистрирован

  • Посещение

Репутация

34

Контакты

  • Ник
    Monstrofil

Посетители профиля

5 776 просмотров профиля
  1. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Что-то мне подсказывает что все же физ. движок если не захлебнется от такого количества моделей, то как минимум начнет подтормаживать. И в итоге придется сначала писать препроцессор, который поубирает лишние полигоны.
  2. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    XXXXZZZZ[o|i].chunk, каждый 100х100 попугаев. В питоне есть метод BigWorld.findChunkFromPoint(point, spaceID), можешь проверить, но емнип ты правильно написал. spaceID можно из какой-нибудь entity вытянуть
  3. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    @Dragon armorпроверил танки, тут это пакет 0x24 в реплее, используется для обновления destroyedFragiles/fallenColumns/fallenTrees/damageStickers/других list/dict . ...или вот DEBUG:root:nested property request for id=10261187 isSlice=True data=ef0093bda506 DEBUG:root:next path item: fallenTrees(3) DEBUG:root:object: [[0, 141, 189, 112, 163], [0, 145, 189, 113, 58], [0, 146, 189, 128, 30]] <class 'def_generator.nested_types.PyFixedList'> DEBUG:root:Bits per array index: 2 DEBUG:root:List index: 3 DEBUG:root:Slice index: 3 DEBUG:root:new list object: [[0, 147, 189, 165, 6]] DEBUG:root: DEBUG:root: DEBUG:root:nested property request for id=10912843 isSlice=True data=e3c00802ea66e2ed5d87 DEBUG:root:next path item: damageStickers(12) DEBUG:root:object: [11992011582228136455L, 4675071338421158407L, 5466597707613143559L] <class 'def_generator.nested_types.PyFixedList'> DEBUG:root:Bits per array index: 2 DEBUG:root:List index: 3 DEBUG:root:Slice index: 3 DEBUG:root:new list object: [9754213924599366152L] Те же три пустых байта в пакете, тот же формат. self.entity_id, = struct.unpack('I', stream.read(4)) self.is_slice = struct.unpack('b', stream.read(1))[0] == 1 self.payload_size, = struct.unpack('b', stream.read(1)) self.u = stream.read(3) # unknown self.payload = stream.read() Так что если будут с ним проблемы - пиши, попробую помочь.
  4. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Так вот без контекста сложно сказать... причешу код для корабельных реплеев и опопробую то же самое на танковых, тогда смогу сказать точно. К примеру, разбор одного из упакованных путей для изменения свойства entity.state['resources'][0]['amountByEntities'][2]. 1010 1110 0111 1110‬ | AE 7E + PAYLOAD len(entity) == 11 => 4 bytes for entityPropertyId ‭1 0101 => entityPropertyId = 5 => state len(entity.state) == 16 keys in dict => 4 bytes 1 1001 => PropertyId = 9 => resources //resources - под индексом 9 в .def файле len(entity.state['resources']) == 1 item in array => 0 bytes 1 => PropertyId = 0 => resorces[0] len(entity.state['resources'][0]) == 2 keys in dict => 1 bytes 1 1 => PropertyId = 1 => resources[0]['amountByEntities'] //amountByEntities - под индексом 1 в .def файле len(entity.state['resources'][0]['amountByEntities']) == 3 items in array => 2 bytes 1 10 => PropertyId = 2 => resources[0]['amountByEntities'][2] 0 => exit while Object by path: {'current': 0, 'max': 550, 'id': 550, 'min': 0}, len = 4 => 3 bytes 001 => 1 => current
  5. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Именно что 3 байта, не знаю их предназначение но они всегда по нулям.. Да, это оно, а obj.childLength() - как раз текущее кол-во свойств (размер массива / кол-во ключей в словаре / кол-во свойств в entity).
  6. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    @Dragon armor, короче разобрался с этим кошмаром, австралийские(?) разрабы решили там зачем-то экономить каждый бит(!). Определить setNested/setSlice можно по флагу в пакете, он сразу после entityId лежит. Потом лежит размер, 3 байта 0x00 и, собственно, данные (по крайней мере в реплее). Что setNested что setSlice начинаются с упакованного пути к изменяемому элементу, читать приходится побитово. Псевдокодом будет примерно так. pOwner = entity while bits.pop(0) == 1 && pOwner length = obj.childLength() // длина массива || кол-во элементов в словаре || для entity - кол-во свойств bits = bitsRequires(length) // смотрим сколько бит нужно дабы уместить индекс для контейнера выше => ceil(log(length, 2)) propertyId = readBits(bitsArray, bits) // читаем нужное кол-во бит, недостающее добиваем нулями до "целого" байта, переводим в int32 pOwner = pOwner.getPropertyByIndex(propertyId) // для массива - берем по индексу элемент, для словаря - по порядковому номеру свойство в .def файлике, для entity - по exposedId Потом (уже вне цикла while) начинаются отличия, для setNested читаем индекс изменяемого свойства как обычно: maxBits = bitsRequires(pOwner.childLenght()) propertyId = readBits(bits, maxBits) Всё, остаток информации можно распаковать используя тип данных из def/alias. Для setSlice чуть иначе maxBits = bitsRequires(pOwner.childLenght() + 1) index1 = readBits(bits, maxBits) index2 = readBits(bits, maxBits) // если индекс превышает кол-во элементов в pOwner -> добавляем новый // если index2 > index1 && payload == None -> удаляем из массива // замены, похоже, выполняются через setNested В общем-то ничего особо сложного когда разобрался, но мозг мне этот пакет выносил долго...
  7. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    С setNested_PROPERTY / setSlice_PROPERTY ещё не сталкивался?
  8. Monstrofil

    Распакова *.pkg файлов

    Декомпильнуть - не знаю, а влезть можно через copy_reg.pyc. Правда ходят слухи за модификацию скриптов присылают письма счастья. Вкратце: в idx лежат: - список нод (mx32 байта, тут есть id и parent_id) - строки-соответствия нодам - список структур с информацией о файлике (nx40 байт), тут же можно найти смещение и размер файла в .pkg Периодически формат немного меняют. https://github.com/Monstrofil/project_m/blob/master/dev/ResMgr.py
  9. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    @Dragon armor, действительно что-то заумное придумали разрабы BigWorld, особенно с этой зависимостью exposedId от размера пакета... Anyway, проверил работоспособность на версии 1.0.2.2. Для моих нужд нужны только ClientMethods, так что и парсил только их. В общем что пришлось сделать: 1. Парсим .def не забывая про implements и parent, записываем ClientMethods в список в порядке чтения def-файлов (необходимо для корректной сортировки сообщений с variable-length. 2. Высчитываем длинну тех сообщений, которые можем (те, которые нельзя вычислить помечаем как +inf) 3. Сортируем массив сообщений по их длинне. exposedIndex - индекс нужного метода в массиве после сортировки по длинне сообщения, никаких INDEX_CLIENT_METHOD_BEGIN добавлять не нужно. Прогнал на нескольких реплеях, все сообщения распаковуются без проблем. p.s. Properties по той же схеме работают.
  10. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Кстати, может и правильно определяется, т.к. chatCommandFromClient в последнем клиенте вообще нет. UPD: а, не, обманываю, chatCommandFromClient есть в интерфейсе "Chat", сорри.
  11. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Парсинг alias/.def я давно сделал, не заморачивайся. В принципе я уже сейчас могу весь реплей "проиграть" сторонней тулзой, включая создание Entity, вызов методов и изменение в ней proretries. Мне интересны пакеты 0x7 и 0x8, там вторым параметром приходит messageId, по которому клиент определяет какой метод вызвать/какую property установить. Вот его сейчас приходится тянуть из памяти клиента, а хотелось бы получать автоматически при парсинге def-файлов.
  12. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    А не разобрался случайно как происходит подгрузка информации из def-файлов и (главный вопрос - каким образом назначаются exposedId для пропертей и методов)? Мне приходится эту информацию для каждой версии из памяти клиента выдергивать, было бы круто иметь возможность "отвязаться" от клиента игры вообще. Честно, не знаю что там в заголовке/футере валяется, как вариант - для быстрой отсечки дубликатов/устаревших пакетов.
  13. Monstrofil

    Мод "Эмулятор сервера World of Tanks".

    Задавал себе этот вопрос когда писал парсер реплеев, могу вот такую цитату привести. Chapter 28. Encrypting Client-Server Traffic BigWorld guarantees the security of the client-server session in two important ways: The login handshake is RSA-encrypted using a public key stored in the client resources. The client-proxy channel is symmetrically encrypted using Blowfish. As a result, it is impossible for an attacker to: Steal a player's password Hijack a player's session Inject upstream packets into the player's traffic to disrupt his/her session 28.3. Customising the symmetric encryption algorithm The Client-Proxy Channel is encrypted using 128-bit Blowfish by default. This encryption method was selected as it was the most secure, high-performance symmetric cipher offered in the standard OpenSSL distribution. Should you wish to use a different encryption algorithm, you should be able to edit src/lib/network/encryption_filter.cpp to change the encryption algorithm without needing to modify any header files. https://gist.github.com/Monstrofil/939b6b16d95fab3fe16f8003093c1aa9 Цитата из вот этой документации, не думаю что со времен bw2.0 там что-то существенно меняли.
  14. Monstrofil

    Blender Tank Viewer

    Привет Под кораблики никто ещё плагин не адаптировал?
  15. В картошкоконкурсе модиков кто-то собирается участвовать?

    1. Показать предыдущий комментарий  ещё 3
    2. Monstrofil
    3. vlad_cs_sr

      vlad_cs_sr

      насколько они мертвы при рождении?

    4. SNART

      SNART

      Что-за кораблики, говорят есть ещё самолётики?.

×