-
Notifications
You must be signed in to change notification settings - Fork 16
/
SplitPackets.go
134 lines (110 loc) · 4.18 KB
/
SplitPackets.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package peer
import (
"bytes"
"log"
"strings"
)
// SplitPacketBuffer represents a structure that accumulates every
// layer that is used to transmit the split packet.
type SplitPacketBuffer struct {
// All ReliabilityLayer packets for this packet received so far
ReliablePackets []*ReliablePacket
// All RakNet layers for this packet received so far
// IN RECEIVE ORDER, NOT SPLIT ORDER!!
// Use ReliablePackets[i].RakNetLayer to access them in that order.
RakNetPackets []*RakNetLayer
// Next expected index
NextExpectedPacket uint32
// Number of _ordered_ splits we have received so far
NumReceivedSplits uint32
// Has received packet type yet? Set to true when the first split of this packet
// is received
HasPacketType bool
PacketType byte
byteReader *bytes.Reader
dataReader *extendedReader
Data []byte
// Have all splits been received?
IsFinal bool
// Unique ID given to each packet. Splits of the same packet have the same ID.
UniqueID uint32
// Total length received so far, in bytes
RealLength uint32
logBuffer *strings.Builder // must be a pointer because it may be copied!
Logger *log.Logger
}
type splitPacketList map[uint16](*SplitPacketBuffer)
func newSplitPacketBuffer(packet *ReliablePacket, context *CommunicationContext) *SplitPacketBuffer {
reliables := make([]*ReliablePacket, int(packet.SplitPacketCount))
raknets := make([]*RakNetLayer, 0, int(packet.SplitPacketCount))
list := &SplitPacketBuffer{
ReliablePackets: reliables,
RakNetPackets: raknets,
}
list.UniqueID = context.uniqueID
context.uniqueID++
list.logBuffer = new(strings.Builder)
list.Logger = log.New(list.logBuffer, "", log.Lmicroseconds|log.Ltime)
return list
}
func (list *SplitPacketBuffer) addPacket(packet *ReliablePacket, rakNetPacket *RakNetLayer, index uint32) {
// Packets may be duplicated. At least I think so. Thanks UDP
list.ReliablePackets[index] = packet
list.RakNetPackets = append(list.RakNetPackets, rakNetPacket)
}
func (list splitPacketList) delete(layers *PacketLayers) {
delete(list, layers.Reliability.SplitPacketID)
}
func (reader *DefaultPacketReader) addSplitPacket(layers *PacketLayers) *SplitPacketBuffer {
packet := layers.Reliability
splitPacketID := packet.SplitPacketID
splitPacketIndex := packet.SplitPacketIndex
if !packet.HasSplitPacket {
buffer := newSplitPacketBuffer(packet, reader.context)
buffer.addPacket(packet, layers.RakNet, 0)
return buffer
}
var buffer *SplitPacketBuffer
if reader.splitPackets == nil {
buffer = newSplitPacketBuffer(packet, reader.context)
reader.splitPackets = map[uint16]*SplitPacketBuffer{splitPacketID: buffer}
} else if reader.splitPackets[splitPacketID] == nil {
buffer = newSplitPacketBuffer(packet, reader.context)
reader.splitPackets[splitPacketID] = buffer
} else {
buffer = reader.splitPackets[splitPacketID]
}
buffer.addPacket(packet, layers.RakNet, splitPacketIndex)
packet.SplitBuffer = buffer
return buffer
}
func (reader *DefaultPacketReader) handleSplitPacket(layers *PacketLayers) (*SplitPacketBuffer, error) {
reliablePacket := layers.Reliability
packetBuffer := reader.addSplitPacket(layers)
expectedPacket := packetBuffer.NextExpectedPacket
packetBuffer.RealLength += uint32(len(reliablePacket.SelfData))
var shouldClose bool
for len(packetBuffer.ReliablePackets) > int(expectedPacket) && packetBuffer.ReliablePackets[expectedPacket] != nil {
packetBuffer.Data = append(packetBuffer.Data, packetBuffer.ReliablePackets[expectedPacket].SelfData...)
expectedPacket++
shouldClose = len(packetBuffer.ReliablePackets) == int(expectedPacket)
packetBuffer.NextExpectedPacket = expectedPacket
}
if shouldClose {
packetBuffer.IsFinal = true
packetBuffer.byteReader = bytes.NewReader(packetBuffer.Data)
packetBuffer.dataReader = &extendedReader{packetBuffer.byteReader}
if reliablePacket.HasSplitPacket {
// TODO: Use a linked list
reader.splitPackets.delete(layers)
}
}
packetBuffer.NumReceivedSplits = expectedPacket
if reliablePacket.SplitPacketIndex == 0 {
packetBuffer.PacketType = reliablePacket.SelfData[0]
packetBuffer.HasPacketType = true
}
layers.Root.Logger = packetBuffer.Logger
layers.Root.logBuffer = packetBuffer.logBuffer
return packetBuffer, nil
}