package packets import ( "fmt" "io" "time" ) // Packet is the base struct for all EverQuest packet types type Packet struct { Buffer []byte Opcode uint16 SrcIP uint32 DstIP uint32 SrcPort uint16 DstPort uint16 Priority uint32 Timestamp time.Time Version int16 } // NewPacket creates a new packet with the given opcode and data func NewPacket(opcode uint16, data []byte) *Packet { p := &Packet{ Opcode: opcode, Timestamp: time.Now(), } if len(data) > 0 { p.Buffer = make([]byte, len(data)) copy(p.Buffer, data) } return p } // Size returns the total packet size including opcode func (p *Packet) Size() uint32 { return uint32(len(p.Buffer)) + 2 } // RawOpcode returns the raw opcode value func (p *Packet) RawOpcode() uint16 { return p.Opcode } // SetSrcInfo sets source IP and port func (p *Packet) SetSrcInfo(ip uint32, port uint16) { p.SrcIP = ip p.SrcPort = port } // SetDstInfo sets destination IP and port func (p *Packet) SetDstInfo(ip uint32, port uint16) { p.DstIP = ip p.DstPort = port } // CopyInfo copies network and timing info from another packet func (p *Packet) CopyInfo(other *Packet) { p.SrcIP = other.SrcIP p.SrcPort = other.SrcPort p.DstIP = other.DstIP p.DstPort = other.DstPort p.Timestamp = other.Timestamp p.Version = other.Version } // DumpRaw writes packet contents to writer for debugging func (p *Packet) DumpRaw(w io.Writer) { p.DumpRawHeader(0xffff, w) if len(p.Buffer) > 0 { // TODO: Implement dump_message_column equivalent fmt.Fprintf(w, "[Data: %d bytes]\n", len(p.Buffer)) } } // DumpRawHeader writes packet header info to writer func (p *Packet) DumpRawHeader(seq uint16, w io.Writer) { if p.SrcIP != 0 { fmt.Fprintf(w, "[%s:%d->%s:%d] ", longToIP(p.SrcIP), p.SrcPort, longToIP(p.DstIP), p.DstPort) } if seq != 0xffff { fmt.Fprintf(w, "[Seq=%d] ", seq) } fmt.Fprintf(w, "[OpCode 0x%04x Size=%d]\n", p.Opcode, len(p.Buffer)) }