Make OnPacket return a result struct

This commit is contained in:
ChillerDragon 2024-06-20 12:29:26 +08:00
parent 5627630145
commit a78bf12bf0
2 changed files with 46 additions and 38 deletions

View file

@ -95,17 +95,17 @@ func byteSliceToString(s []byte) string {
return string(s) return string(s)
} }
func (connection *Connection) OnSystemMsg(msg int, chunk chunk7.Chunk, u *packer.Unpacker, response *Packet) { func (connection *Connection) OnSystemMsg(msg int, chunk chunk7.Chunk, u *packer.Unpacker, result *PacketResult) {
if msg == network7.MsgSysMapChange { if msg == network7.MsgSysMapChange {
fmt.Println("got map change") fmt.Println("got map change")
response.Messages = append(response.Messages, messages7.Ready{}) result.Response.Messages = append(result.Response.Messages, messages7.Ready{})
} else if msg == network7.MsgSysConReady { } else if msg == network7.MsgSysConReady {
fmt.Println("got ready") fmt.Println("got ready")
response.Messages = append(response.Messages, connection.MsgStartInfo()) result.Response.Messages = append(result.Response.Messages, connection.MsgStartInfo())
} else if msg == network7.MsgSysSnapSingle { } else if msg == network7.MsgSysSnapSingle {
// tick := u.GetInt() // tick := u.GetInt()
// fmt.Printf("got snap single tick=%d\n", tick) // fmt.Printf("got snap single tick=%d\n", tick)
response.Messages = append(response.Messages, messages7.CtrlKeepAlive{}) result.Response.Messages = append(result.Response.Messages, messages7.CtrlKeepAlive{})
} else { } else {
fmt.Printf("unknown system message id=%d data=%x\n", msg, chunk.Data) fmt.Printf("unknown system message id=%d data=%x\n", msg, chunk.Data)
} }
@ -120,10 +120,10 @@ func (client *Connection) OnMotd(motd string) {
fmt.Printf("[motd] %s\n", motd) fmt.Printf("[motd] %s\n", motd)
} }
func (client *Connection) OnGameMsg(msg int, chunk chunk7.Chunk, u *packer.Unpacker, response *Packet) { func (client *Connection) OnGameMsg(msg int, chunk chunk7.Chunk, u *packer.Unpacker, result *PacketResult) {
if msg == network7.MsgGameReadyToEnter { if msg == network7.MsgGameReadyToEnter {
fmt.Println("got ready to enter") fmt.Println("got ready to enter")
response.Messages = append(response.Messages, messages7.EnterGame{}) result.Response.Messages = append(result.Response.Messages, messages7.EnterGame{})
} else if msg == network7.MsgGameSvMotd { } else if msg == network7.MsgGameSvMotd {
motd := u.GetString() motd := u.GetString()
if motd != "" { if motd != "" {
@ -145,7 +145,7 @@ func (client *Connection) OnGameMsg(msg int, chunk chunk7.Chunk, u *packer.Unpac
} }
} }
func (client *Connection) OnMessage(chunk chunk7.Chunk, response *Packet) { func (client *Connection) OnMessage(chunk chunk7.Chunk, result *PacketResult) {
// fmt.Printf("got chunk size=%d data=%v\n", chunk.Header.Size, chunk.Data) // fmt.Printf("got chunk size=%d data=%v\n", chunk.Header.Size, chunk.Data)
if chunk.Header.Flags.Vital { if chunk.Header.Flags.Vital {
@ -161,39 +161,48 @@ func (client *Connection) OnMessage(chunk chunk7.Chunk, response *Packet) {
msg >>= 1 msg >>= 1
if sys { if sys {
client.OnSystemMsg(msg, chunk, &u, response) client.OnSystemMsg(msg, chunk, &u, result)
} else { } else {
client.OnGameMsg(msg, chunk, &u, response) client.OnGameMsg(msg, chunk, &u, result)
} }
} }
func (connection *Connection) OnPacketPayload(header []byte, data []byte, response *Packet) (*Packet, error) { func (connection *Connection) OnPacketPayload(data []byte, result *PacketResult) (*PacketResult, error) {
chunks := chunk7.UnpackChunks(data) chunks := chunk7.UnpackChunks(data)
for _, c := range chunks { for _, c := range chunks {
connection.OnMessage(c, response) connection.OnMessage(c, result)
} }
return response, nil return result, nil
} }
// the response packet might be nil even if there is no error type PacketResult struct {
func (connection *Connection) OnPacket(data []byte) (*Packet, error) { // Suggested response that should be sent to the server
header := PacketHeader{} // Will be *nil* if no response should be sent
headerRaw := data[:7] Response *Packet
payload := data[7:]
header.Unpack(headerRaw)
response := connection.BuildResponse()
if header.Flags.Control { // Incoming traffic from the server parsed into a Packet struct
Packet *Packet
}
func (connection *Connection) OnPacket(data []byte) (*PacketResult, error) {
result := &PacketResult{
Response: connection.BuildResponse(),
Packet: &Packet{},
}
result.Packet.Header.Unpack(data[:7])
payload := data[7:]
if result.Packet.Header.Flags.Control {
ctrlMsg := int(payload[0]) ctrlMsg := int(payload[0])
fmt.Printf("got ctrl msg %d\n", ctrlMsg) fmt.Printf("got ctrl msg %d\n", ctrlMsg)
if ctrlMsg == network7.MsgCtrlToken { if ctrlMsg == network7.MsgCtrlToken {
copy(connection.ServerToken[:], payload[1:5]) copy(connection.ServerToken[:], payload[1:5])
response.Header.Token = connection.ServerToken result.Response.Header.Token = connection.ServerToken
fmt.Printf("got server token %x\n", connection.ServerToken) fmt.Printf("got server token %x\n", connection.ServerToken)
response.Messages = append( result.Response.Messages = append(
response.Messages, result.Response.Messages,
messages7.CtrlConnect{ messages7.CtrlConnect{
Token: connection.ClientToken, Token: connection.ClientToken,
}, },
@ -201,7 +210,7 @@ func (connection *Connection) OnPacket(data []byte) (*Packet, error) {
} else if ctrlMsg == network7.MsgCtrlAccept { } else if ctrlMsg == network7.MsgCtrlAccept {
fmt.Println("got accept") fmt.Println("got accept")
// TODO: don't hardcode info // TODO: don't hardcode info
response.Messages = append(response.Messages, messages7.Info{}) result.Response.Messages = append(result.Response.Messages, messages7.Info{})
} else if ctrlMsg == network7.MsgCtrlClose { } else if ctrlMsg == network7.MsgCtrlClose {
// TODO: get length from packet header to determine if a reason is set or not // TODO: get length from packet header to determine if a reason is set or not
// len(data) -> is 1400 (maxPacketLen) // len(data) -> is 1400 (maxPacketLen)
@ -214,14 +223,14 @@ func (connection *Connection) OnPacket(data []byte) (*Packet, error) {
fmt.Printf("unknown control message: %x\n", data) fmt.Printf("unknown control message: %x\n", data)
} }
if len(response.Messages) == 0 { if len(result.Response.Messages) == 0 {
return nil, nil return nil, nil
} }
return response, nil return result, nil
} }
if header.Flags.Compression { if result.Packet.Header.Flags.Compression {
huff := huffman.Huffman{} huff := huffman.Huffman{}
var err error var err error
payload, err = huff.Decompress(payload) payload, err = huff.Decompress(payload)
@ -231,6 +240,6 @@ func (connection *Connection) OnPacket(data []byte) (*Packet, error) {
} }
} }
response, err := connection.OnPacketPayload(headerRaw, payload, response) result, err := connection.OnPacketPayload(payload, result)
return response, err return result, err
} }

View file

@ -60,34 +60,33 @@ func main() {
go readNetwork(ch, conn) go readNetwork(ch, conn)
packet := client.CtrlToken() tokenPacket := client.CtrlToken()
conn.Write(packet.Pack(client)) conn.Write(tokenPacket.Pack(client))
for { for {
time.Sleep(10_000_000) time.Sleep(10_000_000)
select { select {
case msg := <-ch: case msg := <-ch:
packet, err = client.OnPacket(msg) result, err := client.OnPacket(msg)
if err != nil { if err != nil {
panic(err) panic(err)
} }
if packet != nil { if result.Response != nil {
// example of modifying outgoing traffic // example of modifying outgoing traffic
for i, msg := range packet.Messages { for i, msg := range result.Response.Messages {
if msg.MsgId() == network7.MsgCtrlConnect { if msg.MsgId() == network7.MsgCtrlConnect {
if connect, ok := packet.Messages[0].(messages7.CtrlConnect); ok { if connect, ok := result.Response.Messages[0].(messages7.CtrlConnect); ok {
connect.Token = [4]byte{0xaa, 0xaa, 0xaa, 0xaa} connect.Token = [4]byte{0xaa, 0xaa, 0xaa, 0xaa}
packet.Messages[i] = connect result.Response.Messages[i] = connect
} }
} }
} }
conn.Write(packet.Pack(client)) conn.Write(result.Response.Pack(client))
} }
default: default:
// do nothing // do nothing
} }
} }
} }