FILE / ScuroNeko/mtg

wrappers/packetack/client_intermediate.go

Исходный файл и его история в репозитории.
FILE 9d67414db633dded5f11d549eb80617dc6abb2c3
Files
mtg/wrappers/packetack/client_intermediate.go
T
2022-03-19 14:36:04 +03:00

90 lines
2.0 KiB
Go

package packetack
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"net"
"github.com/9seconds/mtg/conntypes"
"go.uber.org/zap"
)
const clientIntermediateQuickAckLength = 0x80000000
type wrapperClientIntermediate struct {
parent conntypes.StreamReadWriteCloser
}
func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
buf := bytes.Buffer{}
buf.Grow(4) // nolint: gomnd
if _, err := io.CopyN(&buf, w.parent, 4); err != nil { // nolint: gomnd
return nil, fmt.Errorf("cannot read message length: %w", err)
}
length := binary.LittleEndian.Uint32(buf.Bytes())
if length > clientIntermediateQuickAckLength {
acks.Quick = true
length -= clientIntermediateQuickAckLength
}
buf.Reset()
buf.Grow(int(length))
if _, err := io.CopyN(&buf, w.parent, int64(length)); err != nil {
return nil, fmt.Errorf("cannot read the message: %w", err)
}
return buf.Bytes(), nil
}
func (w *wrapperClientIntermediate) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
if acks.Simple {
if _, err := w.parent.Write(packet); err != nil {
return fmt.Errorf("cannot send simpleacked packet: %w", err)
}
return nil
}
length := [4]byte{}
binary.LittleEndian.PutUint32(length[:], uint32(len(packet)))
if _, err := w.parent.Write(append(length[:], packet...)); err != nil {
return fmt.Errorf("cannot send packet: %w", err)
}
return nil
}
func (w *wrapperClientIntermediate) Close() error {
return w.parent.Close() // nolint: wrapcheck
}
func (w *wrapperClientIntermediate) Conn() net.Conn {
return w.parent.Conn()
}
func (w *wrapperClientIntermediate) LocalAddr() *net.TCPAddr {
return w.parent.LocalAddr()
}
func (w *wrapperClientIntermediate) RemoteAddr() *net.TCPAddr {
return w.parent.RemoteAddr()
}
func (w *wrapperClientIntermediate) Logger() *zap.SugaredLogger {
return w.parent.Logger().Named("client-intermediate")
}
func NewClientIntermediate(parent conntypes.StreamReadWriteCloser) conntypes.PacketAckFullReadWriteCloser {
return &wrapperClientIntermediate{
parent: parent,
}
}