package main import ( "encoding/binary" "encoding/json" "fmt" "io" ) const ( RemoteGetState = uint16(0x01) RemoteHandleMessage = uint16(0x02) ResponseBody = uint16(0x03) RemoteGetStateReply = uint16(0x04) RemoteHandleMessageReply = uint16(0x05) ) type CartPacket struct { Version uint16 MessageType uint16 DataLength uint16 Id CartId } type Packet struct { Version uint16 MessageType uint16 DataLength uint16 } func SendCartPacket(conn io.Writer, id CartId, messageType uint16, datafn func(w io.Writer) error) error { data, err := GetData(datafn) if err != nil { return err } if conn == nil { return fmt.Errorf("no connection to send to") } binary.Write(conn, binary.LittleEndian, CartPacket{ Version: 2, MessageType: messageType, DataLength: uint16(len(data)), Id: id, }) _, err = conn.Write(data) return err } func SendPacket(conn io.Writer, messageType uint16, datafn func(w io.Writer) error) error { data, err := GetData(datafn) if err != nil { return err } err = binary.Write(conn, binary.LittleEndian, Packet{ Version: 1, MessageType: messageType, DataLength: uint16(len(data)), }) if err != nil { return err } packetsSent.Inc() _, err = conn.Write(data) return err } func SendRawResponse(conn io.Writer, data []byte) error { err := binary.Write(conn, binary.LittleEndian, Packet{ Version: 1, MessageType: ResponseBody, DataLength: uint16(len(data)), }) if err != nil { return err } _, err = conn.Write(data) return err } func SendProxyResponse(conn io.Writer, data any) error { return SendPacket(conn, ResponseBody, func(w io.Writer) error { data, err := json.Marshal(data) if err != nil { return err } w.Write(data) return nil }) } func ReadPacket[V Packet | CartPacket](conn io.Reader, packet *V) error { return binary.Read(conn, binary.LittleEndian, packet) } func GetPacketData(conn io.Reader, len uint16) ([]byte, error) { data := make([]byte, len) _, err := conn.Read(data) return data, err } func ReceivePacket(conn io.Reader) (uint16, []byte, error) { var packet Packet err := ReadPacket(conn, &packet) if err != nil { return packet.MessageType, nil, err } data, err := GetPacketData(conn, packet.DataLength) if err != nil { return packet.MessageType, nil, err } return packet.MessageType, data, nil }