Jump to content
Korean Random
Sib78

Передача параметров через сокеты UDP .

Recommended Posts

Здравствуйте! Столкнулся с проблемой...

Пытаюсь отправить сообщение во внешнюю программу расположенную  в локальной сети:

Мод ложу в папку 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 by Sib78

Share this post


Link to post

Short link
Share on other sites

Надо отправлять после того, как в агнар зашел, а у тебя сразу после загрузки мода.. т.е. именно где-то посередине загрузки игры.

В сети много исходников модов, возьми любой и посмотри как реализовано обнаружение события входа в ангар (причем как первого, так и после боя).

Вот тут исходники модов, например - 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 by fecell
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Надо отправлять после того, как в агнар зашел, а у тебя сразу после загрузки мода.. т.е. именно где-то посередине загрузки игры.

В сети много исходников модов, возьми любой и посмотри как реализовано обнаружением события входа в ангар (причем как первого, так и после боя).

Вот тут исходники модов, например - 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 by Sib78

Share this post


Link to post

Short link
Share on other sites

Вариант 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 by ShuraBB
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites
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 by Armagomen_dev
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites
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 by Sib78

Share this post


Link to post

Short link
Share on other sites

А вот скажем к примеру имеем мы данные о технике в игре... 

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 message
AttributeError: 'PlayerAccount' object has no attribute 'playerVehicleID'

 

Ругается на атрибут 'playerVehicleID'
 

Share this post


Link to post

Short link
Share on other sites

Вариант 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 by Serfer_78

Share this post


Link to post

Short link
Share on other sites

Вариант 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 by Serfer_78

Share this post


Link to post

Short link
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...