Monstrofil Posted July 19, 2018 Share Posted July 19, 2018 (edited) 21 минуту назад, Dragon armor сказал: Например, вот пакет. 95 должно быть chatCommandFromClient, а определяется неправильно. Кстати, может и правильно определяется, т.к. chatCommandFromClient в последнем клиенте вообще нет. UPD: а, не, обманываю, chatCommandFromClient есть в интерфейсе "Chat", сорри. Edited July 19, 2018 by Monstrofil @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 19, 2018 Author Share Posted July 19, 2018 (edited) Из entities.xml берём энтити. Порядок не важен. Парсим секции def-файлов. Если есть секция "Parent", то рекурсивно сначала тот файл, потом этот, результат объединяем. Затем Implements. После, остальные секции. В файле парсим BaseMethods/CellMethods/ClientMethods раздельно. Для них у меня есть enum. typedef enum METHODS_COMPONENT { CLIENT, CELL, BASE, PROPERTIES, } METHODS_COMPONENT; Понадобится секция VariableLengthHeaderSize, по умолчанию принять 1. Ищем секцию Exposed, для ClientMethods у меня обозначено, как ошибка, т.е. его быть не должно. Для остальных, если нет, по идее, можно проигнорировать, потому что этот метод не отправляет клиент. enum { DATA_GHOSTED = 0x01, ///< Synchronised to ghost entities. DATA_OTHER_CLIENT = 0x02, ///< Sent to other clients. DATA_OWN_CLIENT = 0x04, ///< Sent to own client. DATA_BASE = 0x08, ///< Sent to the base. DATA_CLIENT_ONLY = 0x10, ///< Static client-side data only. DATA_PERSISTENT = 0x20, ///< Saved to the database. DATA_EDITOR_ONLY = 0x40, ///< Only read and written by editor. DATA_ID = 0x80, ///< Is an indexed column in the database. // New DATA_REPLAY_UNK = 0x100, DATA_BACKUPABLE = 0x200, }; const char *exposed_type = mxmlGetText(exposed, NULL); if (!exposed_type) { dd->flags |= DATA_OWN_CLIENT | DATA_BASE; } else if (component == CELL && !strcmp(exposed_type, "ALL_CLIENTS")) { dd->flags |= DATA_OWN_CLIENT; } else if (!strcmp(exposed_type, "OWN_CLIENT")) { dd->flags |= DATA_BASE; } else { printf("Error???\n"); assert(FALSE); // bp } Дальше у меня сделано вот так: dd->flags |= component & 7; Где component - это из METHODS_COMPONENT. Давно уже делал, поэтому не помню, зачем и нужно ли это. Дальше, в цикле читаем все аргументы (Arg) и подсчитываем размер, необходимый для сообщения. Размеры стандартных данных "FLOAT", "FLOAT32", "FLOAT64", "INT8", "INT16", "INT32", "INT64", "UINT8", "UINT16", "UINT32", "UINT64", "VECTOR2", "VECTOR3", "VECTOR4" стандартны, размеры "STRING", "PYTHON" сам устанавливаю в -1, чтобы пометить, что данное сообщение не фиксированного размера, соответственно, если среди аргументов встречается этот тип данных, то всё сообщение не фиксированного размера. Для "ARRAY", "TUPLE", если не указан размер (секция size вроде бы), также -1, иначе подсчитываем, согласно аргументам. Для "FIXED_DICT" только аргументы. Далее сохраняем exposed методы в порядке чтения. Устанавливаем флаги. if (component == CLIENT) { dd->flags |= IS_EXPOSED; } if (dd->flags & (IS_EXPOSED | DATA_BASE)) { Exposed_Index_Push(&method->exposed_index, dd->internal_index); } exposed_index - это просто самодельный вектор internal_index - внутренний индекс, соответствует номеру метода в def файле. Exposed_Index_Push - аналог vector.push После того, как всё прочитал, нужно отсортировать по размеру каждую энтити отдельно и каждый метод в энтити отдельно. Sort(&entity->client); Sort(&entity->base); Sort(&entity->cell); Sort(&entity->properties); //properties парсится аналогично, с той лишь разницей, что там Type, а не Arg У меня сортируется qsort_s'ом. И только для method->exposed_index. В функции сравнения. Берём длину сообщения, подсчитанную ранее, Get_Custom_Msg_Length. static int __cdecl Callback_Sort_Index(void *context, const void *key, const void *compared_key) { methods_s *client = context; const uint32_t key_index = *(uint32_t*)key; const uint32_t compared_key_index = *(uint32_t*)compared_key; const data_description_s *dd_key = Data_Description_Get_By_Index(&client->ddv, key_index); const data_description_s *dd_compared_key = Data_Description_Get_By_Index(&client->ddv, compared_key_index); const int length1 = Get_Custom_Msg_Length(dd_key); const int length2 = Get_Custom_Msg_Length(dd_compared_key); if (length2 == length1) { return dd_key->internal_index - dd_compared_key->internal_index; } if (length2 >= 0) { if (length1 >= 0) { return length1 - length2; } } else if (length1 < 0) { return -length1 - -length2; } return length2 - length1; } int32_t Get_Custom_Msg_Length(const data_description_s *dd) { int32_t result = dd->args.size; if (result < 0) { return -Get_Custom_Msg_Length_Header_Size(dd); } else if ((dd->flags & (DATA_OWN_CLIENT|DATA_BASE)) && (dd->flags & (DATA_GHOSTED|DATA_OTHER_CLIENT)) == 1) { return result + 4; } else { return result; } } static int Get_Custom_Msg_Length_Header_Size(const data_description_s *dd) { if (!(dd->flags & (DATA_OWN_CLIENT|DATA_BASE)) || dd->end_index == -1) { return dd->VariableLengthHeaderSize; } else { return 1; } } end_index у меня всегда -1, в движке, по-видимому, не всегда. Всё, отсортировали. Теперь назначаем messageID. Упрощенно, назначается таким образом: к exposed индексу прибавляется число, с которого начинаются методы. properties #define INDEX_CLIENT_SERVER_PROPERTY_BEGIN 0xA2 client #define INDEX_CLIENT_METHOD_BEGIN 0x44 base #define INDEX_EXPOSED_BASE_METHOD_BEGIN 0x87 cell #define INDEX_EXPOSED_CELL_METHOD_BEGIN 0xE Если хоть что-то понятно, то хорошо, потому что объяснять не умею. 28 минут назад, Dragon armor сказал: Из entities.xml берём энтити. Порядок не важен. Да, не важен. Но нужно запомнить их номер, потом что именно он нужен 8 методе реплея (а 7 либо ни разу не встречал, либо не нужен). От того, какая энтити используется, зависит и значение messageID. Для разных энтитей они могут повторяться. Зачем такие сложности придумали разработчики BigWorld, когда можно было бы обойтись двумя байтами, вместо одного, мне не понятно. Видимо, был смысл. Да, и ещё. Сначала парсится spaces.xml, затем entities.xml. Хотя из первого файла ничего не используется, он будет нулевым элементом. @Monstrofil В новом движке у меня срабатывает ассерт на повторяющиеся методы. Поэтому и ошибочно выбирается неправильный. Движок это обрабатывает, а мне не нужно, поэтому не смотрел, как именно обрабатывает. Edited July 19, 2018 by Dragon armor 1 @ Quote Link to comment Short link Share on other sites More sharing options...
Monstrofil Posted July 20, 2018 Share Posted July 20, 2018 (edited) @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 по той же схеме работают. Edited July 20, 2018 by Monstrofil 1 @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 20, 2018 Author Share Posted July 20, 2018 1 час назад, Monstrofil сказал: exposedIndex - индекс нужного метода в массиве после сортировки по длинне сообщения, никаких INDEX_CLIENT_METHOD_BEGIN добавлять не нужно. Этого уже не вспомнил, давно делал и просто забыл, что для реплеев немного по другому. @ Quote Link to comment Short link Share on other sites More sharing options...
SkepticalFox Posted July 20, 2018 Share Posted July 20, 2018 (edited) Кстати, тут есть файлы .xml ресурсов игры с комментариями https://koreanrandom.com/forum/topic/45741-world-editor-for-mod-creators/ Edited July 20, 2018 by SkepticalFox @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 24, 2018 Author Share Posted July 24, 2018 Пытаюсь запустить арену. Пока что безрезультатно. Клиент вылетает без сообщений об ошибках, хотя отправляю тоже, что и оригинальный сервер. Пытался ускорить загрузку и отправил совсем немного информации о магазине, как клиент опять начал писать странную ошибку в лог. 2018-07-24 15:28:19.821: ERROR: Traceback (most recent call last): 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/framework/entities/BaseDAAPIComponent.py", line 67, in registerFlashComponent 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/framework/entities/DisposableEntity.py", line 62, in create 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 127, in _populate 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 102, in update 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 155, in _update 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 179, in __updateDevices 2018-07-24 15:28:19.821: ERROR: File "scripts/client/helpers/dependency.py", line 134, in wrapper 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 70, in getFittingSlotsData 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 40, in __init__ 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 113, in _prepareModule 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 64, in _prepareModule 2018-07-24 15:28:19.821: ERROR: IndexError: list index out of range Хотел узнать, что ему не нравится в FittingSlotVO._prepareModule путём установки хука. Для функции получилось легко, а для существующего класса не получается. Пытался вот так from gui.Scaleform.daapi.view.lobby.shared.fitting_slot_vo import FittingSlotVO class FittingSlotVO_hook(FittingSlotVO): def _prepareModule(self, modulesData, vehicle, slotType, slotId): print 'FittingSlotVO_hook {0}-{1}-{2}-{3}'.format(modulesData, vehicle, slotType, slotId) super(FittingSlotVO_hook, self)._prepareModule(modulesData, vehicle, slotType, slotId) FittingSlotVO = FittingSlotVO_hook Но не получается. 2018-07-24 15:36:16.921: ERROR: TypeError: super(type, obj): obj must be an instance or subtype of type Проблема в том, что он ещё и наследуется. Кто-то может подсказать, как поставить хук? Или проще в декомпилированный файл добавить print'оф в нужных местах и в папку модов закинуть? @ Quote Link to comment Short link Share on other sites More sharing options...
SkepticalFox Posted July 24, 2018 Share Posted July 24, 2018 (edited) 14 minutes ago, Dragon armor said: Пытаюсь запустить арену. Пока что безрезультатно. Клиент вылетает без сообщений об ошибках, хотя отправляю тоже, что и оригинальный сервер. Пытался ускорить загрузку и отправил совсем немного информации о магазине, как клиент опять начал писать странную ошибку в лог. 2018-07-24 15:28:19.821: ERROR: Traceback (most recent call last): 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/framework/entities/BaseDAAPIComponent.py", line 67, in registerFlashComponent 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/framework/entities/DisposableEntity.py", line 62, in create 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 127, in _populate 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 102, in update 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 155, in _update 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 179, in __updateDevices 2018-07-24 15:28:19.821: ERROR: File "scripts/client/helpers/dependency.py", line 134, in wrapper 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/hangar/AmmunitionPanel.py", line 70, in getFittingSlotsData 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 40, in __init__ 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 113, in _prepareModule 2018-07-24 15:28:19.821: ERROR: File "scripts/client/gui/Scaleform/daapi/view/lobby/shared/fitting_slot_vo.py", line 64, in _prepareModule 2018-07-24 15:28:19.821: ERROR: IndexError: list index out of range Хотел узнать, что ему не нравится в FittingSlotVO._prepareModule путём установки хука. Для функции получилось легко, а для существующего класса не получается. Пытался вот так from gui.Scaleform.daapi.view.lobby.shared.fitting_slot_vo import FittingSlotVO class FittingSlotVO_hook(FittingSlotVO): def _prepareModule(self, modulesData, vehicle, slotType, slotId): print 'FittingSlotVO_hook {0}-{1}-{2}-{3}'.format(modulesData, vehicle, slotType, slotId) super(FittingSlotVO_hook, self)._prepareModule(modulesData, vehicle, slotType, slotId) FittingSlotVO = FittingSlotVO_hook Но не получается. 2018-07-24 15:36:16.921: ERROR: TypeError: super(type, obj): obj must be an instance or subtype of type Проблема в том, что он ещё и наследуется. Кто-то может подсказать, как поставить хук? Или проще в декомпилированный файл добавить print'оф в нужных местах и в папку модов закинуть? Сделай как stranics в debugutils Edited July 24, 2018 by SkepticalFox @ Quote Link to comment Short link Share on other sites More sharing options...
Pavel3333 Posted July 24, 2018 Share Posted July 24, 2018 24 минуты назад, Dragon armor сказал: from gui.Scaleform.daapi.view.lobby.shared.fitting_slot_vo import FittingSlotVO class FittingSlotVO_hook(FittingSlotVO): def _prepareModule(self, modulesData, vehicle, slotType, slotId): print 'FittingSlotVO_hook {0}-{1}-{2}-{3}'.format(modulesData, vehicle, slotType, slotId) super(FittingSlotVO_hook, self)._prepareModule(modulesData, vehicle, slotType, slotId) FittingSlotVO = FittingSlotVO_hook Попробуй так: from gui.Scaleform.daapi.view.lobby.shared.fitting_slot_vo import FittingSlotVO class FittingSlotVO_hook(FittingSlotVO): def _prepareModule(self, modulesData, vehicle, slotType, slotId): print 'FittingSlotVO_hook {0}-{1}-{2}-{3}'.format(modulesData, vehicle, slotType, slotId) super(FittingSlotVO_hook, self)._prepareModule(modulesData, vehicle, slotType, slotId) FSVO_hooked = FittingSlotVO_hook() FittingSlotVO = FSVO_hooked @ Quote Link to comment Short link Share on other sites More sharing options...
SkepticalFox Posted July 24, 2018 Share Posted July 24, 2018 (edited) 1 hour ago, Pavel3333 said: Попробуй так: бред достаточно так orig_prepareModule = FittingSlotVO._prepareModule def hooked_prepareModule(self, modulesData, vehicle, slotType, slotId): print 'hooked_prepareModule {0}-{1}-{2}-{3}'.format(modulesData, vehicle, slotType, slotId) orig_prepareModule(self, modulesData, vehicle, slotType, slotId) FittingSlotVO._prepareModule = orig_prepareModule зачем подменять класс? Edited July 24, 2018 by SkepticalFox @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 24, 2018 Author Share Posted July 24, 2018 3 часа назад, SkepticalFox сказал: достаточно так Так сразу же попробовал, по аналогии с функциями. SyntaxError: invalid syntax class A(object): def f(self, a): print a o = A.f def h(self, a): print 'hook {0}'.format(a) o(self, a) A.f = h a = A() a.f('fff') Вот простейший пример, не работает. A.f = h ^ SyntaxError: invalid syntax Поэтому просто подменил файл на свой. И сразу же стало понятно, где и в чём ошибка. 2018-07-24 17:44:40.898: INFO: FittingSlotVO_prepareModule []-Vehicle<id:1, intCD:48657, nation:1, lock:(0, 0)>-vehicleChassis-None Первый параметр modulesData равен [], module = modulesData[0] вызывает ошибку, т.к. в modulesData нет элементов. А в __init__ такое описание: modulesData: list of modules, installed in current slot type. There is always one element for vehicle modules and zero to three for optional devices and equipments. If there's no corresponding artifact in slot, empty icon is displayed Взял сдампленный CMD_SYNC_SHOP (с которым ошибки нет) и посмотрел, что же содержится в modulesData. 2018-07-24 20:33:23.533: INFO: FittingSlotVO_prepareModule [VehicleChassis<intCD:57362, type:vehicleChassis, nation:1>]-Vehicle<id:1, intCD:48657, nation:1, lock:(0, 0)>-vehicleChassis-None 2018-07-24 20:33:23.533: INFO: FittingSlotVO_prepareModule [VehicleTurret<intCD:49683, type:vehicleTurret, nation:1>]-Vehicle<id:1, intCD:48657, nation:1, lock:(0, 0)>-vehicleTurret-None 2018-07-24 20:33:23.534: INFO: FittingSlotVO_prepareModule [VehicleGun<intCD:32788, type:vehicleGun, nation:1>]-Vehicle<id:1, intCD:48657, nation:1, lock:(0, 0)>-vehicleGun-None И так далее. А потом Ctrl+F по intCD в CMD_SYNC_SHOP. Нашёл в 'itemPrices' и 'notInShopItems'. Теперь хотя бы знаю, как исправить, когда понадобится. 4 часа назад, Pavel3333 сказал: FSVO_hooked = FittingSlotVO_hook() А так разве не будет вызов функции? Только что, Dragon armor сказал: Вот простейший пример, не работает. Ну да, Enter забыл после o(self, a). Работает, хотя и пробовал до этого так же. Попробовал с наследованием, работает. Почему-то делал также до этого, не работало. Тоже Enter что-ли забыл? @ Quote Link to comment Short link Share on other sites More sharing options...
SkepticalFox Posted July 24, 2018 Share Posted July 24, 2018 (edited) 41 minutes ago, Dragon armor said: class A(object): а зачем object? Да и код этот отрабатывает на Python 2.7(и на 3.6) <<< hook fff <<< fff Edited July 24, 2018 by SkepticalFox @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 24, 2018 Author Share Posted July 24, 2018 2 часа назад, SkepticalFox сказал: а зачем object? Пока что плохо знаком с питоном, поэтому делаю как вижу в исходниках. Может и нет разницы. Прогресс есть. Немного печалят мелкие баги, которые, тем не менее, приходится долго искать. Всего-то надо было флаг выставить, чтобы номер пакета добавился. Картинка, видимо, по умолчанию, потому что информация об арене ещё не передана. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
reven86 Posted July 29, 2018 Share Posted July 29, 2018 @Dragon armor очень крутая работа! За алгоритм по определению номеров из .def отдельное спасибо. Такой вопрос, понимая протокол между сервером и клиентом, можно ли сделать отдельное приложение/сервис для подключения к игровым чатам на реальном сервере (клановый, список друзей)? 1 @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted July 30, 2018 Author Share Posted July 30, 2018 В 29.07.2018 в 21:49, reven86 сказал: понимая протокол между сервером и клиентом, можно ли сделать отдельное приложение/сервис для подключения к игровым чатам на реальном сервере (клановый, список друзей)? Можно. Но нужно много чего сделать. Повторить сетевой протокол движка (обработка доставки сообщений, подтверждение доставки, разбивка больших данных на небольшие пакеты и прочее), имитировать реальный клиент (вдруг забанят, если поведение будет отличаться). В общем, то же, что и сам делаю, но в обратную сторону. Возможно, даже проще. Кроме сетевой части. У меня все данные пересылаются с помощью Enet, чтобы избежать (по крайней мере, в данный момент) работы над сетевой частью. Над сервером работа идёт, но неспешно, ибо энтузиазм вещь такая, то он есть и засиживаешься за полночь, то его нет и даже строчки не хочется напечатать. И очень сильно не понятно, как должно быть построено взаимодействие сервера с клиентом. Кстати, почему уведомления перестали приходить на почту? @ Quote Link to comment Short link Share on other sites More sharing options...
DrWeb7_1 Posted August 1, 2018 Share Posted August 1, 2018 Интересно... очень даже хороший проект! Перестала игра нравиться в каком-то смысле после патча 0.9.23 (он же 1.0), а тут возможность ещё раз взглянуть на 0.9.22... удачи в разработке! @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted August 2, 2018 Author Share Posted August 2, 2018 @DrWeb7_1 Благодарю. Сегодня чуть-чуть дальше продвинулся. Карту почему-то эту выбирает, хотя пока что информацию о ней не отправлял. Как-то много непонятного с id энтитей. Почему-то используется уникальный id для каждой, а не id из базы данных для игрока. Создаётся Avatar со своим id, для него техника со своим id, для аватара отправляется сообщение о том, что он больше не контролируется (controlEntity с id аватара и false). И не понятно, id разных энтитей (аватар и техника) могут повторяться или нет? @SkepticalFox , взял было твой питоновый модуль XmlPacker/XmlUnpacker, надеясь избавиться от mxml, который у меня используется для парсинга, но производительность так сильно упала (с 6 секунд до 40+ при загрузке сервера), что пришлось на сишке самому написать. И там у тебя баг, вместо PackedTypes.Section почему-то PackedTypes.Float с нулевой длиной создаётся. Хотя это не мешает, созданный с помощью XmlPacker корректно распаковывается и работает. @ Quote Link to comment Short link Share on other sites More sharing options...
SkepticalFox Posted August 3, 2018 Share Posted August 3, 2018 (edited) 8 hours ago, Dragon armor said: с 6 секунд до 40+ при загрузке сервера а что ты хотел от питона? кстати, какая у тебя версия? на второй очень тормозит ты для сервера каждый раз парсишь все эти файлы? а паковщик тебе зачем? просто создай БД с нужной информацией из этих файлов 8 hours ago, Dragon armor said: И там у тебя баг, вместо PackedTypes.Section почему-то PackedTypes.Float с нулевой длиной создаётся. Скорее вместо PackedTypes.String, а это вообще не страшно Edited August 3, 2018 by SkepticalFox @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted August 4, 2018 Author Share Posted August 4, 2018 В 03.08.2018 в 08:01, SkepticalFox сказал: а что ты хотел от питона? СКОРОСТИ!!!111 Это ожидаемо, поэтому ресурсоёмкие вещи переношу в модули на C. В 03.08.2018 в 08:01, SkepticalFox сказал: кстати, какая у тебя версия? на второй очень тормозит 2.7.7, такая же, как и в клиенте. В 03.08.2018 в 08:01, SkepticalFox сказал: ты для сервера каждый раз парсишь все эти файлы? Да. В 03.08.2018 в 08:01, SkepticalFox сказал: а паковщик тебе зачем? Особенности сервера. Константа BigWorld.component = 'base'. А из-за этого вылезло много ошибок из-за отсутствующих значений в xml, например 'xpFactor', 'creditsFactor', 'freeXpFactor', '****Health' и прочих. Пришлось добавлять эти значения и решил заново запаковать. В 03.08.2018 в 08:01, SkepticalFox сказал: просто создай БД с нужной информацией из этих файлов Долго, муторно, не нужно (хотя бы на данный момент). В 03.08.2018 в 08:01, SkepticalFox сказал: Скорее вместо PackedTypes.String Самый первый элемент, Root. Не понятная для меня вещь - дублирование информации в энтитях и излишний (на мой взгляд) оверхед в сетевом трафике. На хабре WG писали несколько статей о том, как они стараются сократить количество трафика, борясь за каждый байт. А что в действительности? Каждый раз, когда сервер отправляет сообщение, которое принадлежит клиенту (Avatar, Account), перед ним отправляется selectPlayerEntity. Если в одном сетевом пакете будет десяток таких сообщений, их будет столько же. При этом, для других энтитей, которые принадлежат другим игрокам (Vehicle) энтити выбирается только один раз, а дальше все сообщения будут принадлежать выбранной энтити. Команда, в которую попал игрок, передаётся в Avatar.updateArena (VEHICLE_LIST) и при создании энтити игрока на арене, которая передаётся следом за предыдущей. id техники так же дублируется и тут, и там. id в базе данных аналогично, что для меня абсолютно не понятно, это-то как может измениться? Не достаточно один раз при логине передать? Или это такая задуманная (штатная) возможность смены игрока на другого? Долго не мог понять, из-за чего ошибки постоянно в логе вылазят: arena_vos.py", line 503, in getTypeInfo: ERROR: IndexError: tuple index out of range - из-за неправильной id техники AssertionError: Player's databaseID can not be empty При том с такой частотой, что клиент подвисал. Разобрался и продвинулся ещё дальше. 4 @ Quote Link to comment Short link Share on other sites More sharing options...
Serfer_78 Posted August 5, 2018 Share Posted August 5, 2018 @Dragon armor Просто шикарная работа , однозначно + @ Quote Link to comment Short link Share on other sites More sharing options...
Dragon armor Posted August 5, 2018 Author Share Posted August 5, 2018 @Serfer_78 Благодарю. Максимальная дальность видимости 565 метров, говорили они, это максимальная дистанция, на которой в принципе можно увидеть технику, говорили они. It was a lie, Morpheus. The prophecy was a lie. В снайперском прицеле за кустами немного видно, но силуэт не обводится. 4 @ Quote Link to comment Short link Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.