Создание стороннего чат клиента для WorldOfTanks с использованием XMPP протокола. Часть 2
Posted January 18, 2022 by ‐ 4 min read
Снифинг XMPP пакетов через Wireshark
С прошлой статьи я немного переделал структуру проекта и теперь репозиторий подключен как субмодуль. По идее боле правильный подход и упростит обновление в будущем.
Так же самым удачным решением было разобраться с фильтрами в Wireshark. Оказалось, что xmpp протокол очень легко отфильтровать и это позволило полностью разобраться в том в каком порядке происходи отправка сообщений, и какой ресурс используется для соединения с клановым чатом (до этого я на это убил кучу времени так и не добившись ничего)
Для отображения только xmpp протокола введите
xmpp
в поле фильтра и нажмите Enter
Диалог танкового клиента с серверами по протоколу xmpp
Из того, что удалось выяснить по поводу функционала XMPP в танковой экосистеме:
- используется для личных сообщений
- используется для клановых сообщений
- сообщает об изменении статусе игрока из клана или друзей (на каком сервере, онлайн ли он, в бою ли он)
- отвечает за добавление в друзья
- отвечает за блокировку пользователей (это пока точно не подтвердил)
- ресурс для конекта к клановому чату
clan-<clan id>@clans.wot.wot-ru.loc/<username>
- ресурс для конекта к серверу личных сообщений
<account id>@wot-ru.loc/wot
К сожалению общий чат видимо использует танковый протокол, который работает на основе UDP. Признаюсь честно, до общего чата мне хотелось добраться больше всего :)
Создание эхо бота
Я вдохновился кодом из репозитория galaxy-integration-wargaming, а именно частью xmpp клиента и примерам из репозитория slixmpp
import logging
import slixmpp
# часть которая генерирует token2 для моего аккаунта.
# Подумаю как красиво ее опубликовать чуть позже
from get_chat_token import get_token
class EchoBot(slixmpp.ClientXMPP):
def __init__(self, jid, password):
slixmpp.ClientXMPP.__init__(self, jid, str(password), sasl_mech='PLAIN')
self.register_plugin('xep_0199') # XMPP Ping
# enable authentication via unencrypted PLAIN
self['feature_mechanisms'].unencrypted_plain = True
# disable aiodns
self.use_aiodns = False
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
self.add_event_handler("session_start", self.start)
# The message event is triggered whenever a message
# stanza is received. Be aware that that includes
# MUC messages and error messages.
self.add_event_handler("message", self.message)
def connect(self):
return super().connect(("xmppcs.worldoftanks.net", "5222"))
async def start(self, event):
"""
Process the session_start event.
Typical actions for the session_start event are
requesting the roster and broadcasting an initial
presence stanza.
Arguments:
event -- An empty dictionary. The session_start
event does not provide any additional
data.
"""
self.send_presence(pfrom=jid, ppriority=0)
await self.get_roster()
def message(self, msg):
"""
Process incoming message stanzas. Be aware that this also
includes MUC messages and error messages. It is usually
a good idea to check the messages's type before processing
or sending replies.
Arguments:
msg -- The received message stanza. See the documentation
for stanza objects and the Message stanza to see
how it may be used.
"""
if msg['type'] in ('chat', 'normal'):
msg.reply("Thanks for sending\n%(body)s" % msg).send()
if __name__ == '__main__':
# Setup logging.
logging.basicConfig(
level=logging.DEBUG,
format='%(levelname)-8s %(message)s'
)
# Ваш jid для подключения
# Вам нужно использовать ваш танковый account id вместо 123123123
jid = "123123123@wot-ru.loc/wot_general"
password = get_token()
# Setup the EchoBot and register plugins. Note that while plugins may
# have interdependencies, the order in which you register them does
# not matter.
xmpp = EchoBot(jid, password)
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process()
Несколько важных моментов в строчке jid = "123123123@wot-ru.loc/wot_general"
1. вместо 123123123
должен быть ваш танковый id
2. в качестве ресурса для подключения используется wot_general
а не wot
- это позволяет побороть проблему с единой сессией xmpp сервера. Если использовать wot
то вы будете конфликтовать с чатом из запущенных танков.
После запуска скрипта любой кто нам напишет - тут же получит свое сообщение в ответ в формате Thanks for sending <сообщение>
Автоматом в друзья!
В процессе тестирования получил неожиданный эффект - заявки в друзья автоматом принимаются. Пока не знаю как именно контролировать это поведение, но думаю это будет несложно.
Я знаю, где мой друг
В сообщении о смене статуса приходит так же поле: GAME-HOST login.p2.worldoftanks.net:20014
и оно несет в себе информацию о том на каком сейчас сервере находится игрок. Пока не сильно понятно где такое может пригодится, но находка есть находка)
В следующей статье мы начнем оформлять наши наработки в что-то полезное.
Есть несколько идей:
- трансляция кланового чата в телеграм канал (read-only)
- телеграм бот для отправки и получения личных сообщений пока ты в дали от танков
- отслеживание онлайна друзей в танках (или определенного друга)
Но перед этим всем придется копнуть в устройство galaxy-integration-wargaming, чтобы понять как безопасно хранить секреты и получать token2