kharlashkin Posted December 4, 2013 Share Posted December 4, 2013 (edited) Добрый день, уважаемые форумчане! К сожалению, заказ мода на официальном форуме игры не привел ни к чему, публикую свои "хотелки" здесь. Существуют специальные вибронакидки для игры в WoT, которые официально поддерживаются разработчиками. Соответственно, под эти вибронакидки есть уже готовый модуль в игре для передачи обратной связи. Можно ли исправить этот модуль, находится вроде в папке World_of_Tanks\res\scripts\client\vibroeffects, для передачи данных не в вибронакидку а в контроллер от Xbox360? В нем так же два вибромотора. P.S. Могу на данный момент заплатить 50$ хоть завтра, если будет правильное обоснование в сторону увеличения, можно увеличить бюджет. В принципе, довольно много есть интересующихся (кто играют на геймпадах), можно поднять вопрос и скинуться сообща. P.P.S. Есть готовый мод, который берет данные для вибраций из файлов для вибронакидки .uwv, с помощью коэффициентов преобразовывает их и передает данные для двигателей xinput геймпада. Работают смешивание (одновременное воспроизведение нескольких эффектов), нет никаких задержек (все вибрации отрабатываются вовремя), я понял почему разработчики хвалятся тем, что эффекты делал звукорежиссер (пожар только чего стоит - как биение сердца), работают "ползунки" в настройках игры для вибронакидки (можно увеличить вибрации/уменьшить/отключить), настройки для передачи вибраций в геймпад вынесены в отдельный xml файл.Теперь по порядку:1. Необходимо установить Python версий 2.6.х (у меня стоит 2.6.1), в принципе можно перекомпилировать файлы под любую версию.2. Установить Flask, качаем файл distribute_setup.py в папку "C:\temp" (например), запускаем консоль "Win+R" - cmd и выполняем команды:C:\Python26\python.exe C:\temp\distribute_setup.pyC:\Python26\python.exe C:\Python26\Scripts\easy_install-2.6-script.py FlaskC:\Python26\python.exe C:\Python26\Scripts\easy_install-2.6-script.py Jinja2C:\Python26\python.exe C:\Python26\Scripts\easy_install-2.6-script.py WerkzeugC:\Python26\python.exe C:\Python26\Scripts\easy_install-2.6-script.py Virtualenv3. Распаковать мод в нужную папку.4. Играть.В файле GPsettings.xml уже прописаны путь к системному python "c:/python26/pythonw.exe" со скрытым запуском, коэффициенты передачи эффекта, нужная dll ( для Windows 7/Vista), для XP нужно прописать xinput1_1, для 8-ки - XInput9_1_0. Edited September 23, 2014 by kharlashkin 2 @ Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 4, 2013 Author Share Posted December 4, 2013 (edited) Покопав тему глубже, нашел следующие вводные данные: 1. На сайте производителей "виброжопки" есть SDK, т.е. очень просто понять что, как и почему работает. 2. Там же есть и стандартные эффекты для WoT, открывая которые обычным тестовым редактором понятно, как именно сделаны виброэффекты. 3. На сайте Microsoft, есть описание API для работы с геймпадом от Xbox 360. Наверное будет очень проблематично добавить поддержку геймпада в саму игру WoT - для этого придется очень много перелопатить кода WoT. По моему мнению будет проще написать программу, которая будет перехватывать команды из WoT для виброжопки и отдавать их специальные аналоги посредством XInput в геймпад. Прошу совета у сообщества - реально это сделать? Так же прикладываю ссылку на проект где уже есть открытый код с использованием библиотеки libusb, для контроллера Xbox 360. От себя могу подтвердить, что данная модификация работает с эмулятором xpadder и позволяет играть в WoT на геймпаде. Edited December 4, 2013 by kharlashkin 1 @ Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 5, 2013 Author Share Posted December 5, 2013 (edited) Вышел на разрабочиков. Пробую у них попросить добавление данного функционала или хотя бы исходников ПО для накидки с целью добавить туда нужный функционал. Edited December 6, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 5, 2013 Author Share Posted December 5, 2013 (edited) Показал все что было мною найдено программисту, который очень хорошо разбирается в коде. Нужен человек имеющий навыки программирования на Python. Откликнитесь кто-нибудь! Edited December 6, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 7, 2013 Author Share Posted December 7, 2013 Прошло два дня - расскажу, что мне удалось, может кто-то меня подтолкнет к нужным мыслям.Полазив в папках самой WoT нашел папку с скриптами, написанными на python, которые относятся именно к вибронакидке "X:\Games\World_of_Tanks\res\scripts\client\vibroeffects"Декомпилировав файлы из папки, показал этот код программисту. Мне сказали - что так будет удобнее получить нужный мне функционал. Не подменой dll От вибронакидки, а непосредственным вызовом вибраций из игры.Первое, что мне надо было сделать разобраться с вибрацией геймпада из python. В интернета нашелся нужный код. Из редактора IDLE все работает - то есть запуская этот модуль, геймпад действительно начинает вибрировать в зависимости от заданной скорости моторов. SDK для вибронакидки уже вдоль и поперек излазил, но понимание общей картины не получается. Link to comment Short link Share on other sites More sharing options...
sirmax Posted December 7, 2013 Share Posted December 7, 2013 Направление правильное. Тебе необходимо переопределить метод VibroManager.launchQuickEffect(), это можно сделать, написав плагин к XPM. Чтобы это сделать, необходимо иметь девайс для тестов, так что далеко не каждый сможет тебе помочь. Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 8, 2013 Author Share Posted December 8, 2013 Направление правильное. Тебе необходимо переопределить метод VibroManager.launchQuickEffect(), это можно сделать, написав плагин к XPM. Чтобы это сделать, необходимо иметь девайс для тестов, так что далеко не каждый сможет тебе помочь. Сразу прошу прощения - я не программист и для меня все темный лес. Мои навыки программирования остались на школьном уровне в Бейсике 20-летней давности. Про какой именно девайс идет речь? Гемпадов у меня более чем достаточно, вибронакидку покупать не хочется. В SDK вибронакидки есть очень много всего (включая исходники для тестовых программок). Можно поподробнее что значит написать плагин к XPM? Link to comment Short link Share on other sites More sharing options...
sirmax Posted December 8, 2013 Share Posted December 8, 2013 Подробно объяснять сложно. Я дал направление, может кто-то, и откликнется, кто сможет сделать. 1 @ Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 8, 2013 Author Share Posted December 8, 2013 Подробно объяснять сложно. Я дал направление, может кто-то, и откликнется, кто сможет сделать. Код вроде нашел в фале vibromanager.pyc, геймпад готов подарить человеку. кто поможет. Дополнительно могу после выполнения работы заплатить обоснованную сумму денег. Под спойлером код, может закомментируете что откуда и куда. Я начал книгу читать по Python, но пока осилил треть, возможно к концу прочтения буду лучше понимать. def launchQuickEffect(self, effectName, count = 1, gain = 100):if not self.canWork(): return elif count is None: return else: sourceEffect = None if effectName in self.__quickEffects: effectsPool = self.__quickEffects[effectName] for effect in effectsPool: if not effect.isRunning(): effect.setRelativeGain(gain) self.startEffect(effect, count) return sourceEffect = effect if sourceEffect is None: effectToLaunch = self.loadEffectFromFile(effectName) self.__quickEffects[effectName] = [effectToLaunch] else: effectToLaunch = VibroEffect(effectName, self.__vibrationObject.cloneEffect(sourceEffect.handle), sourceEffect.getPriority(), self.__vibrationObject, sourceEffect.group) self.__quickEffects[effectName].append(effectToLaunch) effectToLaunch.setRelativeGain(gain) self.startEffect(effectToLaunch, count) return Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 9, 2013 Author Share Posted December 9, 2013 (edited) Скрин настроек из игры Если у кого есть вибронакидка объясните пожалуйста, каким образом игра понимает что накидка подключена? В саму игру вставлен модуль для работы накидки или же через ПО игра отправляет сигналы в неё. Надо ли запускать ПО, идущее в комплекте с накидкой для определения её игрой? Edited December 9, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
inj3ct0r Posted December 15, 2013 Share Posted December 15, 2013 Действительно, без геймпада для тестов такое сделать по-моему нереально. Думаю связь с вибронакидкой на более низком уровне осуществляется через объект (экземпляр класса) BigWorld.WGVibration() Код в инициализации класса: class VibroManager: def __init__(self): self.__vibrationObject = BigWorld.WGVibration() и далее методы: __vibrationObject.connect() __vibrationObject.setGain() __vibrationObject.createEffect() __vibrationObject.loadEffectFromFile() __vibrationObject.setEffectGain() наводят на мысль, что непосредственная связь с устройством осуществляется в BigWorld, т.е. в файле WorldOfTanks.exe, который просто так не поправить, и исходник не посмотреть. Именно этот конкретный метод connect(), осуществляет подключение к накидке. Что это дает? Ничего хорошего, это обстоятельство сильно усложняет задачу. В идеале, все эти методы нужно переписать на новые, под геймпад, например на питоне с использованием той же Xinput. Реально ли это сделать? хз. Даже если реально, то это на это уйдет довольно много времени. Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) Получилось с помощью вышеупомянутого скрипта на python задавать не только силу но и время работы вибрации в геймпаде (добавлением time.sleep ()). Соответственно можно теперь сопоставить необходимо время работы и силу двигателей для каждого эффекта (в документе от производителей их 24). Подскажите куда их и каким образом вставлять эти скрипты. import ctypes import time # Define necessary structures class XINPUT_VIBRATION(ctypes.Structure): _fields_ = [("vibration.wLeftMotorSpeed", ctypes.c_ushort), ("vibration.wRightMotorSpeed", ctypes.c_ushort)] xinput = ctypes.windll.xinput1_3 # Load Xinput.dll # Set up function argument types and return type XInputSetState = xinput.XInputSetState XInputSetState.argtypes = [ctypes.c_uint, ctypes.POINTER(XINPUT_VIBRATION)] XInputSetState.restype = ctypes.c_uint # You can also create a helper function like this: def set_vibration(controller, left_motor, right_motor): vibration = XINPUT_VIBRATION(int(left_motor * 65535), int(right_motor * 65535)) XInputSetState(controller, ctypes.byref(vibration)) # ... and use it like so set_vibration(0, 0.5, 1.0) time.sleep(0.3) set_vibration(0, 0, 0) наводят на мысль, что непосредственная связь с устройством осуществляется в BigWorld, т.е. в файле WorldOfTanks.exe, который просто так не поправить, и исходник не посмотреть. Я и не думал что будет просто ;) Вопрос вот в чем - каким образом игра понимает что накидка подключена? Думаю что с помощью вот этой библиотеки в папке игры uwApi.dll. Если не взлетит переписанный скрипт vibroeffect.pyc, из-за того что BigWorld.WGVibration() не будет видеть наличие вибронакидки и не выполнять скрипты. Можно попробовать через proxy.dll подсунуть нужное значение основному объекту. Я правильно понимаю? Edited December 18, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
inj3ct0r Posted December 18, 2013 Share Posted December 18, 2013 Ок ты нашёл что эти функции __vibrationObject.connect() __vibrationObject.setGain() __vibrationObject.createEffect() __vibrationObject.loadEffectFromFile() __vibrationObject.setEffectGain() лежат вuwApi.dll. Эта библиотека от gametrix. Есть ли ее исходник? Обычно производители выкладывают только заголовочные файлы. Свой скрипт ты можешь вставить в игру без проблем. Самым лучшим вариантом будет создать отдельный, который будет подгружаться загрузчиком. Так твой скрипт будет работать не только в этой версии игры, но и в последующих. В твоем скрипте мне не нравится функция time.sleep() думаю надо как-то по-другому. Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) Не совсем так... Вот тут есть о создании proxy.dll. исследовав библиотеку uwApi.dll на предмет экспортируемых функций с помощью утилиты dumpbin у меня получилось: Dump of file c:\temp\uwApi.dll File Type: DLL Section contains the following exports for uwApi.dll 00000000 characteristics 4DDBD659 time date stamp Tue May 24 19:01:29 2011 0.00 version 1 ordinal base 4 number of functions 4 number of names ordinal hint RVA name 1 0 000011D0 DllCanUnloadNow 2 1 00001320 DllGetClassObject 3 2 000011F0 DllRegisterServer 4 3 00001200 DllUnregisterServer Summary 4000 .data 9000 .rdata 3000 .reloc 1000 .rsrc 25000 .text То есть в библиотеке используется всего 4 функции и они никак не связаны с скриптами в игре. Я думаю что они просто сообщают игре о подключенной вибронакидке. Попробовав подменить 2-ю функцию может удастся обмануть WoT и запускать скрипты без наличия вибронакидки в системе. Эта библиотека от gametrix. Есть ли ее исходник? Обычно производители выкладывают только заголовочные файлы. Есть SDK полный на вибронакидку - ссылка выше. В архиве очень много всего (включая сырцы на С++ для тестовых программ отладчиков). Так твой скрипт будет работать не только в этой версии игры, но и в последующих. В твоем скрипте мне не нравится функция time.sleep() думаю надо как-то по-другому. Это понятно. надо сделать "файл.pyc" и просто класть его в нужную папку с игрой. time.sleep() - Ничего более подходящего не нашел, если есть мысли - буду рад услышать. Зато можно делать циклические вибрации - 1 секунда максимум, 5 раз по 0,2 секунды на уменьшение, 1 секунда максимум и выключение вибраций на геймпаде. set_vibration(0, 1.0, 1.0) time.sleep(1) set_vibration(0, 0.8, 0.8) time.sleep(0.2) set_vibration(0, 0.6, 0.6) time.sleep(0.2) set_vibration(0, 0.4, 0.4) time.sleep(0.2) set_vibration(0, 0.2, 0.2) time.sleep(0.2) set_vibration(0, 1.0, 1.0) time.sleep(1) set_vibration(0, 0, 0) Edited December 18, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
inj3ct0r Posted December 18, 2013 Share Posted December 18, 2013 Я согласен, среди экспорт функций их нет. Но зачем тогда в этом файле такие строки: UwGetStatus - connected UwGetStatus - NOT connected uwSetGain uwCreateEffect uwLoadEffectFromFile uwSetEffectGain Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) Я согласен, среди экспорт функций их нет. Но зачем тогда в этом файле такие строки: UwGetStatus - connected UwGetStatus - NOT connected uwSetGain uwCreateEffect uwLoadEffectFromFile uwSetEffectGain Это уже непосредственно API вибронакидки. Edited December 18, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
inj3ct0r Posted December 18, 2013 Share Posted December 18, 2013 (edited) В файле uwApi.dll. Но без исходника ничего не выйдет. Думаю надо рыть в другом направлении. Будет ли работать этот твой скрипт 'скрипт' import ctypesimport time# Define necessary structuresclass XINPUT_VIBRATION(ctypes.Structure):_fields_ = [("vibration.wLeftMotorSpeed", ctypes.c_ushort),("vibration.wRightMotorSpeed", ctypes.c_ushort)]xinput = ctypes.windll.xinput1_3 # Load Xinput.dll# Set up function argument types and return typeXInputSetState = xinput.XInputSetStateXInputSetState.argtypes = [ctypes.c_uint, ctypes.POINTER(XINPUT_VIBRATION)]XInputSetState.restype = ctypes.c_uint# You can also create a helper function like this:def set_vibration(controller, left_motor, right_motor):vibration = XINPUT_VIBRATION(int(left_motor * 65535), int(right_motor * 65535))XInputSetState(controller, ctypes.byref(vibration))# ... and use it like soset_vibration(0, 0.5, 1.0)time.sleep(0.3)set_vibration(0, 0, 0) во время работы эмулятора для геймпада. Проверь Edited December 18, 2013 by inj3ct0r Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 18, 2013 Author Share Posted December 18, 2013 В файле uwApi.dll. Но без исходника ничего не выйдет. Думаю надо рыть в другом направлении. Будет ли работать этот твой скрипт 'скрипт' import ctypesimport time # Define necessary structures class XINPUT_VIBRATION(ctypes.Structure): _fields_ = [("vibration.wLeftMotorSpeed", ctypes.c_ushort), ("vibration.wRightMotorSpeed", ctypes.c_ushort)] xinput = ctypes.windll.xinput1_3 # Load Xinput.dll # Set up function argument types and return type XInputSetState = xinput.XInputSetState XInputSetState.argtypes = [ctypes.c_uint, ctypes.POINTER(XINPUT_VIBRATION)] XInputSetState.restype = ctypes.c_uint # You can also create a helper function like this: def set_vibration(controller, left_motor, right_motor): vibration = XINPUT_VIBRATION(int(left_motor * 65535), int(right_motor * 65535)) XInputSetState(controller, ctypes.byref(vibration)) # ... and use it like so set_vibration(0, 0.5, 1.0) time.sleep(0.3) set_vibration(0, 0, 0) во время работы эмулятора для геймпада. Проверь Если имеется ввиду работа xpadder, то да. Геймпад подключен к ПК, в xpadder настроен перехват геймпада, в IDLE запускаю скрипт - он отрабатывает нормально. При этом жмакаю на кнопки и прочее - xpadder перехватывает нажатия и эмулирует мышу/клаву. Link to comment Short link Share on other sites More sharing options...
inj3ct0r Posted December 18, 2013 Share Posted December 18, 2013 Это уже непосредственно API вибронакидки. Эти строки есть вVibroManager.pyc, worldowftanks.exe иuwApi.dll. Думаю чтоworldowftanks.exe эти функции импортирует из uwApi.dll и создает класс vibrationObject с этими методами. А из VibroManager.pyc эти методы вызываются, или примерно так. Нобез исходника uwApi все равно ничего не выйдет. Поэтому я думаю нужно будет самому создавать все методы для работы с геймпадом на основе твоего скрипта. Но тут есть проблема как я говорил с time.sleep(). Что думаешь делать дальше? Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted December 18, 2013 Author Share Posted December 18, 2013 (edited) Эти строки есть вVibroManager.pyc, worldowftanks.exe иuwApi.dll. Думаю чтоworldowftanks.exe эти функции импортирует из uwApi.dll и создает класс vibrationObject с этими методами. А из VibroManager.pyc эти методы вызываются, или примерно так. Наконец-то дельное объяснение работы этого всего "хозяйства". Но без исходника uwApi все равно ничего не выйдет. Так вот же исходники. Но думаю что полностью переписывать .dll нет необходимости. Надо только показать игре, что накидка подключена, VibroManager.pyc уже будет сам отрабатывать скрипты прямо на геймпад, когда BigWorld будет их вызывать для накидки. Может просто попробовать вырезать проверку подключения вибронакидки в VibroManager.pyc? Но тут есть проблема как я говорил с time.sleep() Ну это единственный аналог, для переписки подобного: <uberwoorf_vibro_effect> <vibration_1 comment="" zones="2" looped="false"> <vpoint_1 time="0" amplitude="0" time_relative="false"/> <vpoint_2 time="7200" amplitude="0" time_relative="false"/> </vibration_1> <vibration_2 comment="" zones="2" looped="true"> <vpoint_1 time="0" amplitude="0" time_relative="false"/> <vpoint_2 time="80" amplitude="0" time_relative="true"/> <vpoint_3 time="80" amplitude="30" time_relative="true"/> <vpoint_4 time="140" amplitude="30" time_relative="true"/> <vpoint_5 time="140" amplitude="0" time_relative="true"/> <vpoint_6 time="180" amplitude="0" time_relative="true"/> </vibration_2> <vibration_3 comment="" zones="200" looped="true"> <vpoint_1 time="0" amplitude="30" time_relative="false"/> <vpoint_2 time="60" amplitude="30" time_relative="true"/> <vpoint_3 time="60" amplitude="0" time_relative="true"/> <vpoint_4 time="180" amplitude="0" time_relative="true"/> </vibration_3> <vibration_4 comment="" zones="404" looped="true"> <vpoint_1 time="0" amplitude="10" time_relative="false"/> <vpoint_2 time="60" amplitude="10" time_relative="false"/> <vpoint_3 time="60" amplitude="0" time_relative="true"/> <vpoint_4 time="360" amplitude="0" time_relative="false"/> </vibration_4> <sound path="Tiger_idle_02.wav"/> </uberwoorf_vibro_effect> Что думаешь делать дальше? Продолжаю читать Лутца :) Edited December 18, 2013 by kharlashkin Link to comment Short link Share on other sites More sharing options...
Recommended Posts