8 "github.com/dragonfireclient/mt/rudp"
11 // A Pkt is a deserialized rudp.Pkt.
17 // Peer wraps rudp.Conn, adding (de)serialization.
22 func SerializePkt(pkt Cmd, w io.WriteCloser, toSrv bool) bool {
25 cmdNo = pkt.(ToSrvCmd).toSrvCmdNo()
27 cmdNo = pkt.(ToCltCmd).toCltCmdNo()
34 go func() (err error) {
35 // defer w.CloseWithError(err)
38 buf := make([]byte, 2)
39 be.PutUint16(buf, cmdNo)
40 if _, err := w.Write(buf); err != nil {
43 return serialize(w, pkt)
49 func (p Peer) Send(pkt Pkt) (ack <-chan struct{}, err error) {
51 if !SerializePkt(pkt.Cmd, w, p.IsSrv()) {
55 return p.Conn.Send(rudp.Pkt{r, pkt.PktInfo})
58 // SendCmd is equivalent to Send(Pkt{cmd, cmd.DefaultPktInfo()}).
59 func (p Peer) SendCmd(cmd Cmd) (ack <-chan struct{}, err error) {
60 return p.Send(Pkt{cmd, cmd.DefaultPktInfo()})
63 func DeserializePkt(pkt io.Reader, fromSrv bool) (*Cmd, error) {
64 buf := make([]byte, 2)
65 if _, err := io.ReadFull(pkt, buf); err != nil {
68 cmdNo := be.Uint16(buf)
72 newCmd = newToCltCmd[cmdNo]
74 newCmd = newToSrvCmd[cmdNo]
78 return nil, fmt.Errorf("unknown cmd: %d", cmdNo)
82 if err := deserialize(pkt, cmd); err != nil {
83 return nil, fmt.Errorf("%T: %w", cmd, err)
86 extra, err := io.ReadAll(pkt)
88 err = fmt.Errorf("%T: %w", cmd, rudp.TrailingDataError(extra))
94 func (p Peer) Recv() (_ Pkt, rerr error) {
95 pkt, err := p.Conn.Recv()
100 cmd, err := DeserializePkt(pkt, p.IsSrv())
105 return Pkt{*cmd, pkt.PktInfo}, err
109 func Connect(conn net.Conn) Peer {
110 return Peer{rudp.Connect(conn)}
113 type Listener struct {
117 func Listen(conn net.PacketConn) Listener {
118 return Listener{rudp.Listen(conn)}
121 func (l Listener) Accept() (Peer, error) {
122 rpeer, err := l.Listener.Accept()
123 return Peer{rpeer}, err