Мне приходится обрабатывать несколько версий протокола связи. У меня есть пакеты со всеми пакетами и их идентификаторами, которые выглядят как
package v1_8
//Clientbound packet IDs
const (
KeepAliveClientbound byte = iota
JoinGame
ChatMessageClientbound
TimeUpdate
EntityEquipment
SpawnPosition
UpdateHealth
Respawn
PlayerPositionAndLookClientbound
HeldItemChangeClientbound
UseBed
AnimationClientbound
SpawnPlayer
CollectItem
...
и
package v1_14_3
//Clientbound packet IDs
const (
SpawnObject byte = iota //0x00
SpawnExperienceOrb
SpawnGlobalEntity
SpawnMob
SpawnPainting
SpawnPlayer
AnimationClientbound
Statistics
BlockBreakAnimation
UpdateBlockEntity
BlockAction
BlockChange
BossBar
ServerDifficulty
ChatMessageClientbound
MultiBlockChange
...
Существуют небольшие различия между версиями (разные идентификаторы для тех же пакетов или измененный тип данных) как мне go справиться с ними? Пока я просто использую оператор switch, чтобы проверить, какой пакет обрабатывается, но это работает только для одной версии. У меня есть информация о версии протокола клиента, поэтому мне просто нужно изменить пакет, который используется в операторе switch.
for {
pkt, err := src.ReadPacket()
if err != nil {
...handle error
}
switch pkt.ID {
case v1_14_3.<Packet Const>:
...handle packet - there might be different data type assigned for different versions of protocol
}
err = dst.WritePacket(pkt)
if err != nil {
...handle error
}
}
@ Edit: предоставление дополнительной информации
Структура пакета, возвращаемая ReadPacket()
type Packet struct {
ID byte
Data []byte
}
И некоторые реальные данные
{0 [234 3 9 108 111 99 97 108 104 111 115 116 99 156 1]}
Это один из пакетов, определенных здесь как Рукопожатие
Затем я использую Scan
метод Packet
struct наподобие
switch pkt.ID {
case v1_14_3.Handshake:
var (
protocolVersion packet.VarInt
serverAddress packet.String
serverPort packet.UnsignedShort
nextState packet.VarInt
)
err = pkt.Scan(&protocolVersion, &serverAddress, &serverPort, &nextState)
if err != nil {
...handle error
}
...process packet
}
Как я уже говорил, типы, переданные в метод Scan
, могут немного отличаться для разных версий, а также для идентификаторов пакетов. Таким образом, пакет Handshake
между версиями может иметь различную pkt.ID
или различную полезную нагрузку (поэтому свойства, передаваемые для сканирования, будут другими). Scan
- это просто переменная c функция, которая передает переданные переменные с pkt.Data