Ekspoint 2,122 #290204 Posted September 4, 2015 Почитал - понял что ошибка означает, что отступов в коде неожиданное количество. К примеру, если питон счёл, что у вас вложенность кода означается четырьмя пробелами, а именно эта строка отбита одним табом, то будет такая ошибка. Но не понял как исправить??? Не могли бы показать на примере в вложенном файле? Заранее спасибо... у тебя не везде после try прописан except поэтому и ошибка 'COD' __author__ = 'Kiselev Evgeni' __copyright__ = 'Copyright 2013' __credits__ = [ 'Kiselev Evgeni'] __license__ = 'Special. Readme.txt' __version__ = '0.0.9@099' __email__ = '[email protected]' __status__ = 'Beta' if __version__ == '0.0.9@099': __status__ = 'Beta' else: __status__ = 'Rel' __email__ = '[email protected]' x5 = '000000' x5 = '000000' try: import BigWorld import os import AvatarInputHandler from debug_utils import * import Keys import GUI import ResMgr import Math from Account import PlayerAccount import ClientArena collideBC = False def add_ControlMode__init__(self, a, b): global collideBC self.BalCalc_mode_dist = None self.BalCalc_mod_start = None self.BalCalc_mode_keyPressTime = 0 ds = ResMgr.openSection('scripts/client/mods/BalCalc.xml') if ds is not None: collideBC = ds.readInt('correctAim', False) self.keyCaptureTarget = ds.readInt('BalCalcKey') self.BCIndicatorX = ds.readInt('xPos') self.BCIndicatorY = ds.readInt('yPos') self.BCColor = ds.readVector3('indicatorColor') self.StrategicFactorZ = ds.readFloat('strategicFactorZ', 0.0041666) if self.StrategicFactorZ == 0: LOG_NOTE('***WARNING*** strategicFactorZ = 0') self.autoBCTimeout = ds.readFloat('autoBCTimeout', 0) else: LOG_NOTE('unable to open BalCalc.xml') self.autoLockTime = 0 scrRes = GUI.screenResolution() self._info0 = GUI.Text('') self._info0.horizontalAnchor = 'CENTER' self._info0.verticalAnchor = 'CENTER' self._info0.heightMode = 'PIXEL' self._info0.widthMode = 'PIXEL' self._info0.verticalPositionMode = 'PIXEL' self._info0.horizontalPositionMode = 'PIXEL' self._info0.colour = Math.Vector4(self.BCColor[0], self.BCColor[1], self.BCColor[2], 255) self._info0.font = 'default_small.font' self._info0.visible = True self._info0.position = Math.Vector3(scrRes[0] / 2 + self.BCIndicatorX, scrRes[1] / 2 + self.BCIndicatorY, 1) self._info0.text = '0' def new_SniperControlMode_timer(self): BigWorld.callback(0.1, self.new_SniperControlMode_timer) t = BigWorld.target() now = BigWorld.time() if t is not None: self.autoLockTime = BigWorld.time() mp = (GUI.mcursor().position.x, GUI.mcursor().position.y) if abs(mp[0]) < 0.995 and abs(mp[1]) < 0.995: (dir, start) = AvatarInputHandler.cameras.getWorldRayAndPoint(mp[0], mp[1]) p = t.position - start self.BalCalc_mode_dist = p.length self.BalCalc_mod_start = start self._info0.text = '%dm' % int(self.BalCalc_mode_dist) GUI.addRoot(self._info0) elif now - self.autoLockTime > self.autoBCTimeout and not BigWorld.isKeyDown(self.keyCaptureTarget): self.BalCalc_mode_dist = None self.BalCalc_mod_start = None GUI.delRoot(self._info0) if self.BalCalc_mod_start is not None and self.BalCalc_mode_keyPressTime == 0: try: p = BigWorld.player() ownVeh = p.gunRotator self.BalCalc_mod_start = Math.Matrix(ownVeh.appearance.modelsDesc['gun']['model'].node('HP_gunFire')).translation except: LOG_CURRENT_EXCEPTION() AvatarInputHandler.control_modes.SniperControlMode.new_SniperControlMode_timer = new_SniperControlMode_timer def add_SniperControlMode_enable(self, **args): if self.autoBCTimeout > 0: BigWorld.callback(0.1, self.new_SniperControlMode_timer) def add_ControlMode_disable(self, isDestroy = False): if self.BalCalc_mode_dist is not None: self.BalCalc_mode_dist = None self.BalCalc_mod_start = None GUI.delRoot(self._info0) def add_ControlMode_getDesiredShotPoint(self = None): mode = 0 if hasattr(self, '_SniperControlMode__aimingMode'): mode = self._SniperControlMode__aimingMode if hasattr(self, '_ArcadeControlMode__aimingMode'): mode = self._ArcadeControlMode__aimingMode BC_spec = self.BalCalc_mode_dist pl = BigWorld.player() if hasattr(pl, 'MOD_stop_BC') and pl.MOD_stop_BC() and BC_spec is None: return None mp = (None.mcursor().position.x, GUI.mcursor().position.y) dir = None start = None if abs(mp[0]) < 0.995 and abs(mp[1]) < 0.995: (dir, start) = AvatarInputHandler.cameras.getWorldRayAndPoint(mp[0], mp[1]) if BC_spec is not None and mode == 0 and dir is not None: dir.normalise() dir *= BC_spec start += dir return start def add_ControlMode_handleKeyEvent(self, isDown, key, mods, event = None): if key == self.keyCaptureTarget: if isDown: self.BalCalc_mode_dist = None self.BalCalc_mod_start = None now = BigWorld.time() if now - self.BalCalc_mode_keyPressTime < 0.2: self.BalCalc_mode_keyPressTime = 0 else: self.BalCalc_mode_keyPressTime = now sp = self.getDesiredShotPoint() t = BigWorld.target() if sp is not None: mp = (GUI.mcursor().position.x, GUI.mcursor().position.y) if abs(mp[0]) < 0.995 and abs(mp[1]) < 0.995: (dir, start) = AvatarInputHandler.cameras.getWorldRayAndPoint(mp[0], mp[1]) pl = BigWorld.player() BC_spec = None if hasattr(pl, 'SVM_get_BC_special'): try: BC_spec = pl.SVM_get_BC_special(dir, start) except: LOG_CURRENT_EXCEPTION() if BC_spec is not None: self.BalCalc_mode_dist = BC_spec elif t is not None: p = t.position - start self.BalCalc_mode_dist = p.length else: p = sp - start self.BalCalc_mode_dist = p.length self.BalCalc_mod_start = start self._info0.text = '%dm' % int(self.BalCalc_mode_dist) GUI.addRoot(self._info0) elif self.BalCalc_mode_keyPressTime != 0: self.BalCalc_mode_dist = None self.BalCalc_mod_start = None GUI.delRoot(self._info0) return True def add_StrategicControlMode_handleKeyEvent(self, isDown, key, mods, event = None): if key == self.keyCaptureTarget: if isDown: self.BalCalc_mode_dist = 0 self.BalCalc_mod_start = None self._info0.text = '%0.2fm' % self.BalCalc_mode_dist GUI.addRoot(self._info0) else: GUI.delRoot(self._info0) self.BalCalc_mode_dist = None self.BalCalc_mod_start = None return True def add_StrategicControlMode_handleMouseEvent(self, dx, dy, dz): if self.BalCalc_mode_dist is not None and dz != 0: self.BalCalc_mode_dist += dz * self.StrategicFactorZ self._info0.text = '%0.2fm' % self.BalCalc_mode_dist return True def add_StrategicControlMode_getDesiredShotPoint(self = None): if self.BalCalc_mode_dist is not None and self._StrategicControlMode__aimingMode == 0: return Math.Vector3(0, self.BalCalc_mode_dist, 0) def replace_collideWithSpaceBB(self, start, end): if collideBC: p = self.collideWithBalCalc(start, end) if p is not None: return p if not self._ClientArena__spaceBBCollider is None and self._ClientArena__setupBBColliders(): return None return self._ClientArena__spaceBBCollider.collide(start, end) ClientArena.ClientArena.collideWithSpaceBB = replace_collideWithSpaceBB def new_collideWithBalCalc(self, prevCheckPoint, curCheckPoint): player = BigWorld.player() try: dist = getattr(player.inputHandler._AvatarInputHandler__curCtrl, 'BalCalc_mode_dist') start = getattr(player.inputHandler._AvatarInputHandler__curCtrl, 'BalCalc_mod_start') except: return None if dist is not None and start is not None: v0 = prevCheckPoint - start v1 = curCheckPoint - start if v0.length <= dist and v1.length > dist: p = curCheckPoint - prevCheckPoint p = p * ((dist - v0.length) / p.length) return prevCheckPoint + p ClientArena.ClientArena.collideWithBalCalc = new_collideWithBalCalc RET_UNK = 0 RET_ORIG = 1 RET_HOOK = 2 RET_HOOK_IF_NOT_NONE = 3 RET_SUM = 4 CALL_ORIGIN_BEFORE_HOOK = 1 CALL_HOOK_BEFORE_ORIGIN = 2 CALL_HOOK_ONLY_IF_RET_IS_NONE = 3 def set_hook(obj, meth, callback, callOrder = CALL_ORIGIN_BEFORE_HOOK, retOrig = RET_ORIG): originalMeth = getattr(obj, meth) def hook_meth(*w, **kw): retValCB = None retValOrig = None if callOrder == CALL_ORIGIN_BEFORE_HOOK: retValOrig = originalMeth(*w, **w) try: retValCB = callback(*w, **w) except: LOG_NOTE('error while calling ', callback) LOG_CURRENT_EXCEPTION() elif callOrder == CALL_HOOK_BEFORE_ORIGIN: try: retValCB = callback(*w, **w) except: LOG_NOTE('error while calling ', callback) LOG_CURRENT_EXCEPTION() retValOrig = originalMeth(*w, **w) elif callOrder == CALL_HOOK_ONLY_IF_RET_IS_NONE: try: retValCB = callback(*w, **w) except: LOG_NOTE('error while calling ', callback) LOG_CURRENT_EXCEPTION() if retValCB is None: retValOrig = originalMeth(*w, **w) else: retValOrig = retValCB if retOrig == RET_ORIG: return retValOrig if None == RET_HOOK: return retValCB if None == RET_HOOK_IF_NOT_NONE: if retValCB is None: return retValOrig return None if None == RET_SUM and retValOrig is not None and retValCB is not None: return retValOrig + retValCB setattr(obj, meth, hook_meth) from Account import _readClientServerVersion (v0, v1) = _readClientServerVersion() from gui import SystemMessages sys_msg = '' def info(): try: if len(sys_msg) != 0: if SystemMessages.g_instance is None: BigWorld.callback(4, info) else: SystemMessages.pushMessage(sys_msg) except: LOG_CURRENT_EXCEPTION() isPack = True try: f = open('..\client\Readme_AutoTelescope.txt') aaa = f.read() if len(aaa) > 0: import hashlib xxx = hashlib.md5(aaa).hexdigest() if xxx == 'c2d8a943f70d5efc90078c3e097a3b55': isPack = False except: pass if not isPack: set_hook(AvatarInputHandler.control_modes.SniperControlMode, 'handleKeyEvent', add_ControlMode_handleKeyEvent, CALL_HOOK_BEFORE_ORIGIN, RET_ORIG) set_hook(AvatarInputHandler.control_modes.SniperControlMode, 'getDesiredShotPoint', add_ControlMode_getDesiredShotPoint, CALL_HOOK_ONLY_IF_RET_IS_NONE, RET_HOOK_IF_NOT_NONE) set_hook(AvatarInputHandler.control_modes.SniperControlMode, 'enable', add_SniperControlMode_enable, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.SniperControlMode, 'disable', add_ControlMode_disable, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.SniperControlMode, '__init__', add_ControlMode__init__, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.ArcadeControlMode, 'handleKeyEvent', add_ControlMode_handleKeyEvent, CALL_HOOK_BEFORE_ORIGIN, RET_ORIG) set_hook(AvatarInputHandler.control_modes.ArcadeControlMode, 'getDesiredShotPoint', add_ControlMode_getDesiredShotPoint, CALL_HOOK_ONLY_IF_RET_IS_NONE, RET_HOOK_IF_NOT_NONE) set_hook(AvatarInputHandler.control_modes.ArcadeControlMode, 'disable', add_ControlMode_disable, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.ArcadeControlMode, '__init__', add_ControlMode__init__, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.StrategicControlMode, 'handleMouseEvent', add_StrategicControlMode_handleMouseEvent, CALL_HOOK_ONLY_IF_RET_IS_NONE, RET_HOOK_IF_NOT_NONE) set_hook(AvatarInputHandler.control_modes.StrategicControlMode, 'handleKeyEvent', add_StrategicControlMode_handleKeyEvent, CALL_HOOK_BEFORE_ORIGIN, RET_ORIG) set_hook(AvatarInputHandler.control_modes.StrategicControlMode, 'getDesiredShotPoint', add_StrategicControlMode_getDesiredShotPoint, CALL_HOOK_BEFORE_ORIGIN, RET_SUM) set_hook(AvatarInputHandler.control_modes.StrategicControlMode, 'disable', add_ControlMode_disable, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) set_hook(AvatarInputHandler.control_modes.StrategicControlMode, '__init__', add_ControlMode__init__, CALL_ORIGIN_BEFORE_HOOK, RET_ORIG) sys_msg = 'BCM: BalCalcMod %s started' % __version__ else: sys_msg = 'Please update BalCalcMod http://ktod.ru/BalCalc/BalCalcMod.rar' LOG_NOTE('*********** Please update BalCalcMod http://ktod.ru/BalCalc/BalCalcMod.rar ***********') BigWorld.flushPythonLog() BigWorld.callback(6, info) except: from debug_utils import * LOG_CURRENT_EXCEPTION() Quote Share this post Link to post Short link Share on other sites
Stealthz 21 #290219 Posted September 4, 2015 (edited) держи и сравнивай где ты накосячил:) тык Edited September 4, 2015 by Stealthz 1 Quote Share this post Link to post Short link Share on other sites
gromv 69 #290333 Posted September 5, 2015 спасибо большое! Подскажите я в этом файле изменил только путь res_mods/0.9.9/scripts/client/Readme_BalCalc.txt на res_mods/0.9.10/scripts/client/Readme_BalCalc.txt И не работает! При чем если старый мод кинуть в папку 0.9.9 то все работает! Что может быть? Кидаю на всякий случай исходный рус и измененный... Всем спс... BalCalc_mod.rar BalCalc_mod-измененый.rar Quote Share this post Link to post Short link Share on other sites
Vampire_BY 3 #290430 Posted September 5, 2015 Кто нибудь пробовал подключать lxml в PjOrion? В интерпретатор python подключения библиотеки проходит нормально а вот в PjOrion не могу подключить. Quote Share this post Link to post Short link Share on other sites
GPCracker 2,088 #290433 Posted September 5, 2015 Кто нибудь пробовал подключать lxml в PjOrion? В интерпретатор python подключения библиотеки проходит нормально а вот в PjOrion не могу подключить.Так подключи Орион к интерпретатору и будет тебе счастье. Quote Share this post Link to post Short link Share on other sites
Vampire_BY 3 #290448 Posted September 5, 2015 (edited) Да что за, не как не получается вывести через PjOrion данные xml файла import xml.etree.ElementTree as ET tree = ET.parse('test.xml') root = tree.getroot() print root[0].text Выдает ошибку << Traceback (most recent call last):<<< File "<string>", line 2, in <module><<< File "ElementTree", line 1182, in parse<<< File "ElementTree", line 651, in parse<<< File "ElementTree", line 1465, in __init__<<< ImportError: No module named expat; use SimpleXMLTreeBuilder instead Код рабочий и не требует сторонних библиотек Edited September 5, 2015 by DannyGreene Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290449 Posted September 5, 2015 Код рабочий и не требует сторонних библиотек Что такое expat и где этот модуль у тебя лежит по отношению к папке Ориона? Quote Share this post Link to post Short link Share on other sites
Vampire_BY 3 #290451 Posted September 5, 2015 (edited) Что такое expat и где этот модуль у тебя лежит по отношению к папке Ориона? Может я ошибаюсь, он не должен быть по умолчанию? В документации python про подключения не чего не сказано https://docs.python.org/2/library/xml.etree.elementtree.html Edited September 5, 2015 by DannyGreene Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290456 Posted September 5, 2015 Может я ошибаюсь, он не должен быть по умолчанию? В документации python про подключения не чего не сказано https://docs.python.org/2/library/xml.etree.elementtree.html 1. Это модуль лежит в пакетах и вызывается вот так import xml.parsers.expat 2. Для его работы нужна DDLs\pyexpat.pyd Quote Share this post Link to post Short link Share on other sites
Vampire_BY 3 #290458 Posted September 5, 2015 (edited) 1. Это модуль лежит в пакетах и вызывается вот так import xml.parsers.expat 2. Для его работы нужна DDLs\pyexpat.pyd На одни и те же грабли наступаю, спс Edited September 5, 2015 by DannyGreene Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290466 Posted September 5, 2015 (edited) По общей теме ------------------------------------- Я тут вдруг вспомнил, что, если у вас скрипт в UTF-8 и вы его загоняете в WOT-трансмиттер, то чтобы русские символы в игре не были кракозябликами, нужно жать не "Exec script in client (SHIFT+F5)", а "Import/Reload script (SHIFT+F6)". Сам попался пару раз... ))))) Edited September 5, 2015 by StranikS_Scan Quote Share this post Link to post Short link Share on other sites
gromv 69 #290527 Posted September 5, 2015 Помогите плз нормально декомпилить мод - после моей декомпиляции, а затем компиляции, мод не работает... Если не трудно... BalCalc_mod.rar Quote Share this post Link to post Short link Share on other sites
fecell 125 #290530 Posted September 6, 2015 (edited) Если не трудно... http://rghost.ru/75m6bwLDP будет ли после компиляции работать как положено - хз. Edited September 6, 2015 by fecell Quote Share this post Link to post Short link Share on other sites
gromv 69 #290554 Posted September 6, 2015 http://rghost.ru/75m6bwLDP будет ли после компиляции работать ка к положено - хз. О!!! Огромное спс! А как так декомпилил? Я скачал PjOrion 1.3.0 with P2.7 с этого сайта и дикомпилил им - но у меня он даже не компилился после этого? Хотя был вроде читаем...а с твоим все ок!!! Как? Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290557 Posted September 6, 2015 А как так декомпилил? Я скачал PjOrion 1.3.0 with P2.7 с этого сайта и дикомпилил им - но у меня он даже не компилился после этого? Хотя был вроде читаем...а с твоим все ок!!! Как? Учи питон Вася. 2 Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290704 Posted September 6, 2015 (edited) Тест версии Орион 1.3.1 -------------------------------- В этой версии еще не все исправлено/добавлено, кое-что осталось в кттс, что-то писалось юзверами в данной теме, и будет сделано к релизу, однако так как много всяких исправлений и добавлений, то выкладываю промежуточную версию: ЗАВЕРШЕН Изменения: Устранена проблема с переполнением аргументов в jrel- и jabs-инструкциях при обфускации скриптов больших размеров, обфускатор обучен правильной работе с EXTENDED_ARG Внесены улучшения в протектор: Добавлено шифрование целых чисел в co_consts Оптимизирован код наложения протектора, а также код шифрования, что позволило многократно снизить время протекции и время запуска скриптов больших размеров с EXE-инжектором и без Добавлен внешний шифрующий слой с zip-сжатием и компактным загрузчиком, уменьшающий размер модуля и препятствующий экспресс-анализу и расшифровке кода протектора В механизме File Assoсiation добавил удаление дублирующих ключей в HKCU, мешающих ассоциации файлов с программой Если файлы *.info.txt и *.dis.txt уже существуют, то создаются файлы *.info1.txt и *.dis1.txt и т.д. Исправил ошибку в определении пути к файлу при запуске программы из командной строки CMD Исправил ошибку при исполнении py-файлов в UTF-8 формате из контекстного меню командной Run Проверил и исправил ошибки в работе некоторых функций и команд в Орионе под Python 3.x Добавил возможность компиляции файлов с точками в именах, зачем не спрашивайте, так как сам не знаю Команда Save теперь не затирает Undo- и Redo-списки операций Зациклил поиск в редакторе, а также добавил вызов поиска и замены в экспресс-окне по горячим клавишам Улучшил работу алгоритма, формирующего список атрибутов в выпадающем меню после точки В синтаксис Ориона добавил операцию @!(abc), приводящую к вызову pprint(abc), данный вариант структурирует списки и словари при выводе На вкладке Settings - Basic setup добавил опцию "Ignore <Exit> in Python" В функции Minimize script улучшил распознавание docstrings, также исправил ошибки парсинга строковых констант В обфускаторе имен Script - Obfuscate - Variables добавлена обфускация аргумента "self" в функциях Добавлен обфускатор строковых констант Script - Obfuscate - Strings... Добавлен обфускатор кода Script - Obfuscate - Structure..., пока что умеет заменять цепочки атрибутов вида a.b.c... на вложенные вызовы getattr В WOT-Transmission исправил ошибку при добавлении путей в sys.path и добавил компиляцию скриптов налету перед exec Обновил python34.dll и архив python34.zip до Python 3.4.3 В WOT-Transmission я в файле \wottransmission\wottransmission\scripts\common\debug_utils.py выставил по умолчанию RELEASE = 5, так как расширенный лог тем кому он не нужен - шибко мешает. Я еще не сделал переключалку в самом Орионе, поэтому кому нужен расширенный лог сами залезьте в файл трансмиттера и замените 5 на 1. Изменения (07/09/2015): Подправил работу обфускатора строк с док-стрингами Сделал вынос переменных в начало модуля в обфускаторе строк Изменения (09/09/2015): Заменил в обфускаторе строк блок переменных на словарь Сделал кэш-файл для обмена большими массива данных между GUI Ориона и средой питона, что должно существенно снизить задержки при различных обфускациях в программе. Изменения (10/09/2015): Исправил ошибки в парсере строк Убрал подчеркивание в буфере обфускатора строк Изменения (07/10/2015): Доработал обфускацию строк, добавил обфускацию всех видом импорта кроме import * Ввёл операцию Obfuscate - Applay all, выполняющую в автоматическом режиме вызов всех функций обфускации текста Переработал некоторые системные скрипты Edited October 11, 2015 by StranikS_Scan 5 Quote Share this post Link to post Short link Share on other sites
DrWebber 5 #290752 Posted September 6, 2015 (edited) А если кто-то сделает вот так "Script - Obfuscate - Structure" + "Script - Obfuscate - Strings" просадок фпс в каком-нибудь цикле не будет? "Script - Obfuscate - Strings"- багованная штука, то половина скрипта пропадет, то закоментируется. upd: а не, это был не комментарий - просто лишняя ковычка Edited September 6, 2015 by DrWebber Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290786 Posted September 6, 2015 (edited) А если кто-то сделает вот так "Script - Obfuscate - Structure" + "Script - Obfuscate - Strings" просадок фпс в каком-нибудь цикле не будет? "Когда на питоне начинаются разговоры про быстроту я сразу волнуюсь" © ВЛ Так и надо делать ))) В 2.7 что getattr, что точка разницы нет. А что касается вычисления строк, то надо чтоб очень много их было и чтоб по кругу крутились, тогда только нагрузка будет. А в модах там даже отдаленно нет такого. Так что на потерю производительности данной фичи применительно к wot-модам можно забить )))) upd: а не, это был не комментарий - просто лишняя ковычка Опасный ты человек ))))) Edited September 6, 2015 by StranikS_Scan Quote Share this post Link to post Short link Share on other sites
DrWebber 5 #290820 Posted September 6, 2015 (edited) Так и надо делать ))) В 2.7 что getattr, что точка разницы нет. А что касается вычисления строк, то надо чтоб очень много их было и чтоб по кругу крутились, тогда только нагрузка будет. А в модах там даже отдаленно нет такого. Так что на потерю производительности данной фичи применительно к wot-модам можно забить )))) Ладно не буду спорить, но мне кажется все не так радужно - вместо одного вызова PyObject_GetAttr, появляется куча разной лабуды с перевыделением памяти. Надо будет потом затестить. Опасный ты человек ))))) Почему?) Edited September 6, 2015 by DrWebber Quote Share this post Link to post Short link Share on other sites
StranikS_Scan 4,203 #290828 Posted September 6, 2015 (edited) Ладно не буду спорить, но мне кажется все не так радужно - вместо одного вызова PyObject_GetAttr, появляется куча разной лабуды с перевыделением памяти. Надо будет потом затестить. Да чего там тестить: import time __times__ = 10000000 def timeit(func, res): '''Check if 'func' returns 'res', if true, execute it '__times__' times (__times__ should be defined in parent namespace) measuring elapsed time.''' assert func() == res t_start = time.clock() for i in xrange(__times__): func() return time.clock() - t_start def aaa(): a = sys.api_version sys.api_version = a return None print timeit(aaa,None) <<< 2.51478396917 <<< 2.52974799936 <<< 2.48672122493 <<< 2.53768407167 <<< 2.56445894453 import time __times__ = 10000000 def timeit(func, res): '''Check if 'func' returns 'res', if true, execute it '__times__' times (__times__ should be defined in parent namespace) measuring elapsed time.''' assert func() == res t_start = time.clock() for i in xrange(__times__): func() return time.clock() - t_start def aaa(): a = getattr(sys,'api_version') sys.api_version = a return None print timeit(aaa,None) <<< 3.48087091521 <<< 3.48028097552 <<< 3.48857806236 <<< 3.47373719659 <<< 3.59471633584 import time __times__ = 1000000 def timeit(func, res): '''Check if 'func' returns 'res', if true, execute it '__times__' times (__times__ should be defined in parent namespace) measuring elapsed time.''' assert func() == res t_start = time.clock() for i in xrange(__times__): func() return time.clock() - t_start def aaa(): sys.a = 'krj caedgr caerhg eragcamerhg cgerugmeuhc aekcg ealurgicmaegcerug rugmaergcaerugckr' return None print timeit(aaa,None) <<< 0.208776178574 <<< 0.206176784668 <<< 0.186909586163 <<< 0.259926895672 <<< 0.189876688323 import time __times__ = 1000000 def timeit(func, res): assert func() == res t_start = time.clock() for i in xrange(__times__): func() return time.clock() - t_start def aaa(): sys.a = ''.join(map(chr,((165^206),(188^206),(164^206),(238^206),(173^206),(175^206),(171^206),(170^206),(169^206),(188^206),(238^206),(173^206),(175^206),(171^206),(188^206),(166^206),(169^206),(238^206),(171^206),(188^206),(175^206),(169^206),(173^206),(175^206),(163^206),(171^206),(188^206),(166^206),(169^206),(238^206),(173^206),(169^206),(171^206),(188^206),(187^206),(169^206),(163^206),(171^206),(187^206),(166^206),(173^206),(238^206),(175^206),(171^206),(165^206),(173^206),(169^206),(238^206),(171^206),(175^206),(162^206),(187^206),(188^206),(169^206),(167^206),(173^206),(163^206),(175^206),(171^206),(169^206),(173^206),(171^206),(188^206),(187^206),(169^206),(238^206),(188^206),(187^206),(169^206),(163^206),(175^206),(171^206),(188^206),(169^206),(173^206),(175^206),(171^206),(188^206),(187^206),(169^206),(173^206),(165^206),(188^206)))) return None print timeit(aaa,None) <<< 15.0864101009 <<< 15.1273863663 <<< 15.2073107005 -------------------------------------- Думаю с a.b vs getattr в питоне 2.7 все понятно - разница микроскопическая - можно забить. Что касается обфускации строки, то берем цифры выше. Пусть время, тратящееся на вызов aaa в тесте - это запас в худшую сторону, т.е. приплюсуем его ко времени вычисления строки, тогда на 1 строку весьма не слабой длины в 80 символов (4 символа тоже в запас), будет траться примерно 15/10^6 сек - если она обфусцирована, и в 100 раз меньше, если - не обфусцирована. Пусть в нашем моде таких строк 1000, т.е. у нас большой хороший мод-сборка, и эта 1000 строк крутиться в цикле незаметно для юзвера. Подсчитаем доп. задержку - 1000*15/10^6 = 15/10^3 = 15 мс. Выходит +15 мс к каждой итерации цикла. То есть если цикл занимает 100 мс, то получим 115 мс с обфускацией строк в данном примере. Для 99% модов цифры будут в десятки раз меньше. Таким образом, для wot-модов это копейки )))) Edited September 6, 2015 by StranikS_Scan Quote Share this post Link to post Short link Share on other sites