Sib78 0 Posted June 28, 2017 (edited) Здравствуйте! Столкнулся с проблемой... Пытаюсь отправить сообщение во внешнюю программу расположенную в локальной сети: Мод ложу в папку mods. В моде код клиента UDP который ниже... import socket import sys UDP_IP = '127.0.0.1' UDP_PORT = 7777 MESSAGE = 'Hello, World!' sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) Сообщение доходит до адресата и выводится в виде надписи "Hello, World!" в окне сервера но 1) Раньше времени, нужно получить сообщение после загрузки ангара ,а отправляется намного раньше. 2) Загрузка клиента world of tanks зависает на половине после отправки сообщения и дальше только выход помогает. А это код сервера. import socket UDP_IP = "127.0.0.1" UDP_PORT = 7777 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((UDP_IP, UDP_PORT)) while True: data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes print "received message:", data Ребята подскажите пожалуйста что не так делаю? Может у кого то уже получалось удачно проделать подобный фокус? А вот так уже лучше.. Сохранил код клиента UDP ( из сообщения выше) отдельным файлом "serv_message.pyc" и попытался его подгрузить таким методом.. import BigWorld import serv_message import sys from gui import SystemMessages from Account import Account Var = 'Hello User!!!': link = Account.onBecomePlayer def _First(self): link(self) msg = 'Var' type = SystemMessages.SM_TYPE.Information SystemMessages.pushMessage(msg, type) Account.onBecomePlayer = link serv_message.init() Account.onBecomePlayer = _First Лаунчер танков загрузился без проблем, но сообщение все так же приходит на сервер не вовремя, т.е где то по середине загрузки клиента игры.. А хотелось бы принять его по окончании, когда в ангаре выскочит message - 'Hello User!!!' WOT работает на UDP , может можно где то в исходниках подсмотреть как правильно организовать обмен данными с внешним приложением по этому протоколу? Подскажите путь истинный ребята)) Зеленоват я в питоне, но схватываю на лету. Может есть уже где то похожие реализации, с удовольствием бы взглянул на алгоритмы. Я конечно могу со своим уровнем познаний написать костыльный велосипед )) , но хочется научиться писать правильны читабельный код , по этому обращаюсь к настоящим знатокам этого дела... Edited June 28, 2017 by Sib78 Quote Share this post Link to post Short link Share on other sites
fecell 125 #396294 Posted June 28, 2017 (edited) Надо отправлять после того, как в агнар зашел, а у тебя сразу после загрузки мода.. т.е. именно где-то посередине загрузки игры. В сети много исходников модов, возьми любой и посмотри как реализовано обнаружение события входа в ангар (причем как первого, так и после боя). Вот тут исходники модов, например - https://koreanrandom.com/forum/topic/28020-%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D0%B8%D0%BA%D0%B8-%D0%BC%D0%BE%D0%B4%D0%BE%D0%B2-spotera-%D0%BD%D0%B0-github/ Edited July 1, 2017 by fecell 1 Quote Share this post Link to post Short link Share on other sites
Sib78 0 #396297 Posted June 28, 2017 (edited) Надо отправлять после того, как в агнар зашел, а у тебя сразу после загрузки мода.. т.е. именно где-то посередине загрузки игры. В сети много исходников модов, возьми любой и посмотри как реализовано обнаружением события входа в ангар (причем как первого, так и после боя). Вот тут исходники модов, например - https://koreanrandom.com/forum/topic/28020-%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D0%B8%D0%BA%D0%B8-%D0%BC%D0%BE%D0%B4%D0%BE%D0%B2-spotera-%D0%BD%D0%B0-github/ Вот в том то и дело.. В середине .. В питоне я чисто интуитивно все это нахожу так как программировал в основном на Autoit и Delphi , а по поводу отследить загрузку ангара... В этой теме разговор был . Вот только не соображу как правильно на питоне все это оформляется. from gui.shared import events, g_eventBus def onLobbyLoaded(event): pass g_eventBus.addListener(events.GUICommonEvent.LOBBY_VIEW_LOADED, onLobbyLoaded) Тут я вижу что из gui.shared импортируется events для использования в коде мода.. Далее объявляется функция onLobbyLoaded и наверное скорее всего ей передается какой о параметр (event) .. А в место кода функции заглушка. Последняя строка темный лес))) И не совсем понятно как создать условие проверки полной загрузки ангара на питоне , так как не ясно где содержится результат выполнения выше приведенной функции. Если не трудно раскомментируйте выше приведенный код пожалуйста. Тогда уж точно смогу сообразить что к чему. В теме отписались что этот код рабочий и если бы я писал на автоите то сделал бы так: $angar = 'Код проверки' ; проверка состояния ангара результат сохранится в переменной $angar If $angar == True Then ; если состояние = истина UDPSend($socket, $data) ; отправляем сообщение EndIf ; окончание условия на дельфине тоже все просто if (условие) then begin //Если условие верно, выполняем действия end else begin //Если условие не верно, выполняем действия end; А вот с питоном еще не разобрался куда сохраняется результат . И как правильно его проверить . Edited June 28, 2017 by Sib78 Quote Share this post Link to post Short link Share on other sites
ShuraBB 1,151 #396303 Posted June 28, 2017 (edited) Вариант 2й: def onAccountShowGUI(ctx): print '* Игрок в ангаре' Вариант 3й: from PlayerEvents import g_playerEvents class TestEvents(): def __init__(self): g_playerEvents.onAccountShowGUI += self.onAccountShowGUI def onAccountShowGUI(self, ctx): print '* Игрок в ангаре' test = TestEvents() >Последняя строка темный лес))) Эта строка "подписывает" функцию onLobbyLoaded на событие загрузки ангара. Когда ангар начинает загрузку, произойдет событие и будет вызвана функция onLobbyLoaded Edited June 28, 2017 by ShuraBB 2 Quote Share this post Link to post Short link Share on other sites
Armagomen_UA 158 #396446 Posted June 30, 2017 (edited) import socket from PlayerEvents import g_playerEvents UDP_IP = '127.0.0.1' UDP_PORT = 7777 MESSAGE = 'Hello, World!' g_playerEvents.onAccountShowGUI += lambda ctx: socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(MESSAGE, (UDP_IP, UDP_PORT)) или так. import socket from PlayerEvents import g_playerEvents class Message(object): def __init__(self): g_playerEvents.onAccountShowGUI += self.message def message(self, ctx): UDP_IP = '127.0.0.1' UDP_PORT = 7777 MESSAGE = 'Hello, World!' socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(MESSAGE, (UDP_IP, UDP_PORT)) g_playerEvents.onAccountShowGUI -= self.message Message() Edited June 30, 2017 by Armagomen_dev 1 Quote Share this post Link to post Short link Share on other sites
Sib78 0 #396587 Posted July 3, 2017 (edited) import socket from PlayerEvents import g_playerEvents UDP_IP = '127.0.0.1' UDP_PORT = 7777 MESSAGE = 'Hello, World!' g_playerEvents.onAccountShowGUI += lambda ctx: socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(MESSAGE, (UDP_IP, UDP_PORT)) или так. import socket from PlayerEvents import g_playerEvents class Message(object): def __init__(self): g_playerEvents.onAccountShowGUI += self.message def message(self, ctx): UDP_IP = '127.0.0.1' UDP_PORT = 7777 MESSAGE = 'Hello, World!' socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(MESSAGE, (UDP_IP, UDP_PORT)) g_playerEvents.onAccountShowGUI -= self.message Message() Armagomen_dev Огромное тебе человеческое Спасибо!! Оба твоих варианта работают , и причем очень четко, погонял проверку много раз, результат всегда стабилен. Информация уходит на минисервер принимающий сообщение и выводится в консоли минисервера. Только одна печаль , сообщение приходит когда крутится колесо загрузки, может так и должно быть, в любом случае от души благодарю вас ребята за помощь. PS: Теперь буду разбираться опираясь на приведенные примеры как правильно оформить отправку разных сообщений в соответствии с игровой обстановкой. Edited July 3, 2017 by Sib78 Quote Share this post Link to post Short link Share on other sites
Serfer_78 2 #399457 Posted July 29, 2017 А вот скажем к примеру имеем мы данные о технике в игре... import BigWorld, Math #Данные о технике playerVehicle = BigWorld.entity(BigWorld.player().playerVehicleID) if playerVehicle is not None: position = playerVehicle.position direction = Math.Matrix(playerVehicle.matrix).applyVector(Math.Vector3(0, 0, 1)) gunPosition = playerVehicle.appearance.modelsDesc['gun']['model'].position gunDirection = Math.Matrix(playerVehicle.appearance.modelsDesc['gun']['model'].matrix).applyVector(Math.Vector3(0, 0, 1)) speedVector = playerVehicle.velocity speed = playerVehicle.velocity.length speed2 = playerVehicle.getSpeed() HP = playerVehicle.health operatable = playerVehicle.isCrewActive and playerVehicle.health > 0 isAlive = playerVehicle.isAlive() typeDescriptor = vehicle.typeDescriptor Подскажите как можно по проще передать "speed" пробовал вот так : import BigWorld import socket from PlayerEvents import g_playerEvents MESSAGE = '' class Message(object): def __init__(self): g_playerEvents.onAccountShowGUI += self.message def message(self, ctx): global MESSAGE UDP_IP = '127.0.0.1' UDP_PORT = 7777 playerVehicle = BigWorld.entity(BigWorld.player().playerVehicleID) if playerVehicle is not None: MESSAGE = str(playerVehicle.velocity.length) socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(MESSAGE, (UDP_IP, UDP_PORT)) g_playerEvents.onAccountShowGUI -= self.message Message() Но ничего не выходит сыпет ошибками в лог... Ребята кто силен в питоне покажите пожалуйста на простом примере как в этом случае можно хотя бы один из параметров через сокет вывести. Выдает ошибку.. 2017-07-30 01:31:09.005: ERROR: [EXCEPTION] (scripts/common/Event.py, 46):Traceback (most recent call last):File "scripts/common/Event.py", line 44, in __call__File "mod_tor", line 18, in messageAttributeError: 'PlayerAccount' object has no attribute 'playerVehicleID' Ругается на атрибут 'playerVehicleID' Quote Share this post Link to post Short link Share on other sites
Serfer_78 2 #399605 Posted August 1, 2017 (edited) Вариант 2й: def onAccountShowGUI(ctx): print '* Игрок в ангаре' Вариант 3й: from PlayerEvents import g_playerEvents class TestEvents(): def __init__(self): g_playerEvents.onAccountShowGUI += self.onAccountShowGUI def onAccountShowGUI(self, ctx): print '* Игрок в ангаре' test = TestEvents() >Последняя строка темный лес))) Эта строка "подписывает" функцию onLobbyLoaded на событие загрузки ангара. Когда ангар начинает загрузку, произойдет событие и будет вызвана функция onLobbyLoaded От души благодарю за примеры, для новичка самое то оказалось.. Опираясь на ваши примеры удалось написать код который более менее нормально заработал. Переделал под UDP Edited August 1, 2017 by Serfer_78 Quote Share this post Link to post Short link Share on other sites
Serfer_78 2 #401680 Posted August 26, 2017 (edited) Вариант 2й: def onAccountShowGUI(ctx): print '* Игрок в ангаре' Вариант 3й: from PlayerEvents import g_playerEvents class TestEvents(): def __init__(self): g_playerEvents.onAccountShowGUI += self.onAccountShowGUI def onAccountShowGUI(self, ctx): print '* Игрок в ангаре' test = TestEvents() >Последняя строка темный лес))) Эта строка "подписывает" функцию onLobbyLoaded на событие загрузки ангара. Когда ангар начинает загрузку, произойдет событие и будет вызвана функция onLobbyLoaded С передачей из клиента во внешнее приложение разобрался.. Передача идет в отдельном потоке. def threadDecorate(object): def decorate(*args, **kwargs): th = threading.Thread(target=object, args=args, kwargs=kwargs) th.setDaemon = True th.start() return decorate @threadDecorate def sendMessage(Message): try: socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(Message, (UDP_IP, UDP_PORT)) socket.close() except: pass А можно ли как то к этому делу приладить прием данных в клиент? К примеру вывод сообщения в ангаре , что то типа from gui import SystemMessages import socket #данные сервера UDP_IP = '127.0.0.1' UDP_PORT = 10020 udp_socket = socket.socket(AF_INET, SOCK_DGRAM).bind( (UDP_IP,UDP_PORT) ) data, adress = udp_socket.recvfrom(1024) if not data : udp_socket.close() type = SystemMessages.SM_TYPE.Warning SystemMessages.pushMessage(str(data), type) udp_socket.close() Есть ли такой функционал в картохе? ЗЫ: Отвечаю сам Можно) Edited August 29, 2017 by Serfer_78 Quote Share this post Link to post Short link Share on other sites