Jump to content
Korean Random

Monstrofil

User
  • Content Count

    59
  • Joined

  • Last visited

Community Reputation

39

Contacts

  • Nick
    Monstrofil

Recent Profile Visitors

6359 profile views
  1. совсем наглея Таки ещё раз предлагаю опенсорснуться, пока интереснейшая тема совсем не заглохла
  2. Учитывая что сервер собирается под linux, я очень удивился бы наличию sln
  3. Вы меня ещё больше запутали Понятное дело что ВГшные правки не утекали. В изначальном сообщении говорилось что исходников сервера (т.е. даже "ванильных") нет даже в древнем сливе bw191(?), а во втором @Dragon armor упоминает что есть только линуксовые бинари. Но в то же время я их прямо сейчас наблюдаю в виде сорсов.
  4. А в тех что я кидал разве серверной части нет?
  5. Что-то все разбежались... а опенсорснуть свои достижения никто не желает?
  6. Что-то мне подсказывает что все же физ. движок если не захлебнется от такого количества моделей, то как минимум начнет подтормаживать. И в итоге придется сначала писать препроцессор, который поубирает лишние полигоны.
  7. XXXXZZZZ[o|i].chunk, каждый 100х100 попугаев. В питоне есть метод BigWorld.findChunkFromPoint(point, spaceID), можешь проверить, но емнип ты правильно написал. spaceID можно из какой-нибудь entity вытянуть
  8. @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() Так что если будут с ним проблемы - пиши, попробую помочь.
  9. Так вот без контекста сложно сказать... причешу код для корабельных реплеев и опопробую то же самое на танковых, тогда смогу сказать точно. К примеру, разбор одного из упакованных путей для изменения свойства 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
  10. Именно что 3 байта, не знаю их предназначение но они всегда по нулям.. Да, это оно, а obj.childLength() - как раз текущее кол-во свойств (размер массива / кол-во ключей в словаре / кол-во свойств в entity).
  11. @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 В общем-то ничего особо сложного когда разобрался, но мозг мне этот пакет выносил долго...
  12. С setNested_PROPERTY / setSlice_PROPERTY ещё не сталкивался?
  13. Декомпильнуть - не знаю, а влезть можно через copy_reg.pyc. Правда ходят слухи за модификацию скриптов присылают письма счастья. Вкратце: в idx лежат: - список нод (mx32 байта, тут есть id и parent_id) - строки-соответствия нодам - список структур с информацией о файлике (nx40 байт), тут же можно найти смещение и размер файла в .pkg Периодически формат немного меняют. https://github.com/Monstrofil/project_m/blob/master/dev/ResMgr.py
  14. @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 по той же схеме работают.
×