Проблема при создании пакета struct.pack()
Мне надо создать пакет для сервера Minecraft (подробнее о этом https://minecraft-ru.gamepedia.com/Протокол_сервера_Classic). Мой код:
import socket
import struct
username = "123123123"
verification_key = "123123123"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("SLeZH.aternos.me", 25565))
packet = ""
packet += struct.pack(">B", 1)
packet += struct.pack(">B", 7)
packet += "%-64s" % username
packet += "%-64s" % verification_key
packet += struct.pack(">B", 0)
s.send(packet)
А ошибка такая:
Traceback (most recent call last):
File "C:\Users\nokim\Desktop\example.py", line 12, in <module>
packet += struct.pack(">B", 1)
TypeError: can only concatenate str (not "bytes") to str
Как это можно исправить? Заранее спасибо
upd: забыл сказать что я собираю пакет "Идентификация игрока"
Ответы (1 шт):
Вы инициализируете пакет как строку packet = "", а struct.pack() возвращает байты. Ошибка вам и говорит о том что нельзя просто взять и сложить строку и байты. Также метод сокета send принимает на вход байты, а не строку, поэтому в любом случае все части пакета нужно преобразовывать в байты.
В данном случае можно собрать пакет за один вызов struct.pack():
# Пробелы в "> B B 64s 64s B" добавил для лучшей читаемости. На конечный результат эти пробелы не влияют.
packet = struct.pack("> B B 64s 64s B", 1, 7,
username.encode().ljust(64, b' '),
verification_key.encode().ljust(64, b' '), 0)
Если строки могут содержать не только латиницу, нужно указать правильную кодировку как аргумент encode (судя по информации по ссылке, которую вы указали в вопросе, это не требуется).
На всякий случай добавлю исправленный вариант сборки пакета по частям:
packet = bytes()
packet += struct.pack(">B", 1)
packet += struct.pack(">B", 7)
packet += username.encode().ljust(64, b' ')
packet += verification_key.encode().ljust(64, b' ')
packet += struct.pack(">B", 0)
Результат будет одним и тем же в обоих вариантах.