Initial commit
This commit is contained in:
109
raknet/frame.go
Normal file
109
raknet/frame.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package raknet
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Frame struct {
|
||||
Reliability Reliability
|
||||
Split bool
|
||||
MessageIndex uint32
|
||||
OrderIndex uint32
|
||||
OrderChannel byte
|
||||
SplitCount uint32
|
||||
SplitID uint16
|
||||
SplitIndex uint32
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (f *Frame) Encode(s *Stream) {
|
||||
flags := byte(f.Reliability) << 5
|
||||
if f.Split {
|
||||
flags |= 0x10
|
||||
}
|
||||
s.WriteByte(flags)
|
||||
s.WriteUint16BE(uint16(len(f.Payload) * 8))
|
||||
|
||||
if f.Reliability.IsReliable() {
|
||||
s.WriteUint24LE(f.MessageIndex)
|
||||
}
|
||||
if f.Reliability.IsOrdered() || f.Reliability.IsSequenced() {
|
||||
s.WriteUint24LE(f.OrderIndex)
|
||||
s.WriteByte(f.OrderChannel)
|
||||
}
|
||||
if f.Split {
|
||||
s.WriteUint32BE(f.SplitCount)
|
||||
s.WriteUint16BE(f.SplitID)
|
||||
s.WriteUint32BE(f.SplitIndex)
|
||||
}
|
||||
s.WriteBytes(f.Payload)
|
||||
}
|
||||
|
||||
func DecodeFrame(s *Stream) (*Frame, error) {
|
||||
flags, err := s.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f := &Frame{}
|
||||
f.Reliability = Reliability((flags >> 5) & 0x07)
|
||||
f.Split = (flags & 0x10) != 0
|
||||
|
||||
bitLen, err := s.ReadUint16BE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
length := int(bitLen / 8)
|
||||
|
||||
if f.Reliability.IsReliable() {
|
||||
f.MessageIndex, err = s.ReadUint24LE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if f.Reliability.IsOrdered() || f.Reliability.IsSequenced() {
|
||||
f.OrderIndex, err = s.ReadUint24LE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.OrderChannel, err = s.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if f.Split {
|
||||
sc, err := s.ReadUint32BE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.SplitCount = sc
|
||||
si, err := s.ReadUint16BE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.SplitID = si
|
||||
idx, err := s.ReadUint32BE()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.SplitIndex = idx
|
||||
}
|
||||
|
||||
f.Payload, err = s.ReadBytes(length)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("frame payload: need %d, %w", length, err)
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (f *Frame) Size() int {
|
||||
size := 3
|
||||
if f.Reliability.IsReliable() {
|
||||
size += 3
|
||||
}
|
||||
if f.Reliability.IsOrdered() || f.Reliability.IsSequenced() {
|
||||
size += 4
|
||||
}
|
||||
if f.Split {
|
||||
size += 10
|
||||
}
|
||||
size += len(f.Payload)
|
||||
return size
|
||||
}
|
||||
Reference in New Issue
Block a user