9 "github.com/dragonfireclient/mt/rudp"
12 // A Pkt is a deserialized rudp.Pkt.
18 // Peer wraps rudp.Conn, adding (de)serialization.
23 func SerializePkt(pkt Cmd, w io.WriteCloser, toSrv bool, wg *sync.WaitGroup) bool {
26 cmdNo = pkt.(ToSrvCmd).toSrvCmdNo()
28 cmdNo = pkt.(ToCltCmd).toCltCmdNo()
36 go func() (err error) {
38 // defer w.CloseWithError(err)
41 buf := make([]byte, 2)
42 be.PutUint16(buf, cmdNo)
43 if _, err := w.Write(buf); err != nil {
46 return serialize(w, pkt)
52 func (p Peer) Send(pkt Pkt) (ack <-chan struct{}, err error) {
54 if !SerializePkt(pkt.Cmd, w, p.IsSrv(), &sync.WaitGroup{}) {
58 return p.Conn.Send(rudp.Pkt{r, pkt.PktInfo})
61 // SendCmd is equivalent to Send(Pkt{cmd, cmd.DefaultPktInfo()}).
62 func (p Peer) SendCmd(cmd Cmd) (ack <-chan struct{}, err error) {
63 return p.Send(Pkt{cmd, cmd.DefaultPktInfo()})
66 func DeserializePkt(pkt io.Reader, fromSrv bool) (*Cmd, error) {
67 buf := make([]byte, 2)
68 if _, err := io.ReadFull(pkt, buf); err != nil {
71 cmdNo := be.Uint16(buf)
75 newCmd = newToCltCmd[cmdNo]
77 newCmd = newToSrvCmd[cmdNo]
81 return nil, fmt.Errorf("unknown cmd: %d", cmdNo)
85 if err := deserialize(pkt, cmd); err != nil {
86 return nil, fmt.Errorf("%T: %w", cmd, err)
89 extra, err := io.ReadAll(pkt)
91 err = fmt.Errorf("%T: %w", cmd, rudp.TrailingDataError(extra))
97 func (p Peer) Recv() (_ Pkt, rerr error) {
98 pkt, err := p.Conn.Recv()
103 cmd, err := DeserializePkt(pkt, p.IsSrv())
108 return Pkt{*cmd, pkt.PktInfo}, err
112 func Connect(conn net.Conn) Peer {
113 return Peer{rudp.Connect(conn)}
116 type Listener struct {
120 func Listen(conn net.PacketConn) Listener {
121 return Listener{rudp.Listen(conn)}
124 func (l Listener) Accept() (Peer, error) {
125 rpeer, err := l.Listener.Accept()
126 return Peer{rpeer}, err