forked from markus-wa/demoinfocs-golang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
entities.go
77 lines (63 loc) · 1.98 KB
/
entities.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
package demoinfocs
import (
"bytes"
bit "github.com/markus-wa/demoinfocs-golang/bitread"
msg "github.com/markus-wa/demoinfocs-golang/msg"
st "github.com/markus-wa/demoinfocs-golang/sendtables"
)
const entitySentinel = 9999
func (p *Parser) handlePacketEntities(pe *msg.CSVCMsg_PacketEntities) {
defer func() {
p.setError(recoverFromUnexpectedEOF(recover()))
}()
r := bit.NewSmallBitReader(bytes.NewReader(pe.EntityData))
currentEntity := -1
for i := 0; i < int(pe.UpdatedEntries); i++ {
currentEntity += 1 + int(r.ReadUBitInt())
if currentEntity > entitySentinel {
break
}
if r.ReadBit() {
// Leave PVS
// FIXME: Might have to destroy the entities contents first, not sure yet
// Could do weird stuff with event handlers otherwise
p.entities[currentEntity] = nil
// TODO: Force Delete if this is true??
r.ReadBit()
} else {
if r.ReadBit() {
// Enter PVS
e := p.readEnterPVS(r, currentEntity)
p.entities[currentEntity] = e
e.ApplyUpdate(r)
} else {
// Delta Update
p.entities[currentEntity].ApplyUpdate(r)
}
}
}
r.Pool()
}
func (p *Parser) readEnterPVS(reader *bit.BitReader, entityID int) *st.Entity {
scID := int(reader.ReadInt(p.stParser.ClassBits()))
reader.Skip(10) // Serial Number
newEntity := st.NewEntity(entityID, p.stParser.ServerClasses()[scID])
newEntity.ServerClass.FireEntityCreatedEvent(newEntity)
if p.preprocessedBaselines[scID] != nil {
for idx, val := range p.preprocessedBaselines[scID] {
newEntity.Props()[idx].FirePropertyUpdate(val)
}
} else {
ppBase := make(map[int]st.PropValue)
if p.instanceBaselines[scID] != nil {
newEntity.CollectProperties(&ppBase)
r := bit.NewSmallBitReader(bytes.NewReader(p.instanceBaselines[scID]))
newEntity.ApplyUpdate(r)
r.Pool()
// TODO: Unregister PropertyUpdateHandlers from CollectProperties()
// PropertyUpdateHandlers would have to be registered as pointers for that to work
}
p.preprocessedBaselines[scID] = ppBase
}
return newEntity
}