@@ -438,25 +438,45 @@ func (e *Entity) readFields(r *reader, paths *[]*fieldPath) {
438438 }
439439}
440440
441- // updateFlag is a bitmask representing the type of operation performed on an Entity
442- type updateFlag = uint32
441+ const (
442+ updateFlagDelete = 0b10
443+ updateFlagVisibleInPVS = 0b10000
444+ )
445+
446+ type updateType = uint32
443447
444448const (
445- updateFlagCreate updateFlag = 0b10
446- updateFlagLeave updateFlag = 0b01
447- updateFlagDelete updateFlag = 0b10
448- updateFlagPreserveEnt updateFlag = 0b01000
449- updateFlagVisibleInPVS updateFlag = 0b10000
449+ updateTypeEnter updateType = iota
450+ updateTypeLeave
451+ updateTypeDelta
452+ updateTypePreserve
450453)
451454
455+ func readEntityUpdateType (r * reader , hasVisBits uint32 ) (updateType , uint32 ) {
456+ flags := r .readBits (2 )
457+ if flags & 0x01 != 0 {
458+ return updateTypeLeave , flags
459+ }
460+ if flags & 0x02 != 0 {
461+ return updateTypeEnter , flags
462+ }
463+ if hasVisBits != 0 {
464+ flags = r .readBits (2 ) << 3
465+ if flags & 0x08 != 0 {
466+ return updateTypePreserve , flags
467+ }
468+ }
469+
470+ return updateTypeDelta , flags
471+ }
472+
452473// Internal Callback for OnCSVCMsg_PacketEntities.
453474func (p * Parser ) OnPacketEntities (m * msgs2.CSVCMsg_PacketEntities ) error {
454475 r := newReader (m .GetEntityData ())
455476
456477 var (
457478 index = int32 (- 1 )
458479 updates = int (m .GetUpdatedEntries ())
459- cmd uint32
460480 classId int32
461481 serial int32
462482 )
@@ -478,7 +498,7 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
478498 paths = make ([]* fieldPath , 0 )
479499 )
480500
481- isPvsPacket := m .GetHasPvsVisBits () != 0
501+ hasVisBits := m .GetHasPvsVisBits ()
482502 for ; updates > 0 ; updates -- {
483503 var (
484504 e * Entity
@@ -488,68 +508,62 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
488508 next := index + int32 (r .readUBitVar ()) + 1
489509 index = next
490510
491- cmd = r .readBits (2 )
492- if cmd == 0 && isPvsPacket {
493- cmd = r .readBits (2 ) << 3
494- }
495-
496- if cmd & updateFlagLeave == 0 {
497- if cmd & updateFlagCreate != 0 {
498- classId = int32 (r .readBits (p .classIdSize ))
499- serial = int32 (r .readBits (17 ))
500- r .readVarUint32 ()
501-
502- class := p .classesById [classId ]
503- if class == nil {
504- _panicf ("unable to find new class %d" , classId )
505- }
511+ updateType , flags := readEntityUpdateType (r , hasVisBits )
512+ switch updateType {
513+ case updateTypeEnter :
514+ classId = int32 (r .readBits (p .classIdSize ))
515+ serial = int32 (r .readBits (17 ))
516+ r .readVarUint32 ()
506517
507- baseline := p .classBaselines [classId ]
508- if baseline == nil {
509- _panicf ("unable to find new baseline %d" , classId )
510- }
518+ class := p .classesById [classId ]
519+ if class == nil {
520+ _panicf ("unable to find new class %d" , classId )
521+ }
511522
512- e = newEntity (index , serial , class )
513- p .entities [index ] = e
523+ baseline := p .classBaselines [classId ]
524+ if baseline == nil {
525+ _panicf ("unable to find new baseline %d" , classId )
526+ }
514527
515- e . readFields ( newReader ( baseline ), & paths )
516- paths = paths [: 0 ]
528+ e = newEntity ( index , serial , class )
529+ p . entities [ index ] = e
517530
518- e .readFields (r , & paths )
519- paths = paths [:0 ]
531+ e .readFields (newReader ( baseline ) , & paths )
532+ paths = paths [:0 ]
520533
521- // Fire created-handlers so update-handlers can be registered
522- for _ , h := range class .createdHandlers {
523- h (e )
524- }
534+ e .readFields (r , & paths )
535+ paths = paths [:0 ]
525536
526- // Fire all post-creation actions
527- for _ , f := range e . onCreateFinished {
528- f ( )
529- }
537+ // Fire created-handlers so update-handlers can be registered
538+ for _ , h := range class . createdHandlers {
539+ h ( e )
540+ }
530541
531- op = st .EntityOpCreated | st .EntityOpEntered
532- } else if cmd & updateFlagPreserveEnt != 0 {
533- // todo: handle visibility
534- // visibleInPvs := !isPvsPacket || cmd&updateFlagVisibleInPVS != 0
535- // fmt.Println("preserve visible in pvs", visibleInPvs)
536- } else { // delta update
537- if e = p .entities [index ]; e == nil {
538- _panicf ("unable to find existing entity %d" , index )
539- }
542+ // Fire all post-creation actions
543+ for _ , f := range e .onCreateFinished {
544+ f ()
545+ }
540546
541- op = st .EntityOpUpdated
542- if ! e . active {
543- e . active = true
544- op |= st . EntityOpEntered
545- }
547+ op = st .EntityOpCreated | st . EntityOpEntered
548+ case updateTypeDelta :
549+ if e = p . entities [ index ]; e == nil {
550+ _panicf ( "unable to find existing entity %d" , index )
551+ }
546552
547- e . readFields ( r , & paths )
548- paths = paths [: 0 ]
549- // todo: handle visibility
550- // visibleInPVS := !isPvsPacket || cmd&updateFlagVisibleInPVS != 0
553+ op = st . EntityOpUpdated
554+ if ! e . active {
555+ e . active = true
556+ op |= st . EntityOpEntered
551557 }
552- } else {
558+
559+ e .readFields (r , & paths )
560+ paths = paths [:0 ]
561+ // todo: handle visibility
562+ // visibleInPVS := hasVisBits == 0 || flags&updateFlagVisibleInPVS != 0
563+ // fmt.Println("visible in pvs", visibleInPVS)
564+ case updateTypePreserve :
565+ // visibleInPVS := hasVisBits == 0 || flags&updateFlagVisibleInPVS != 0
566+ case updateTypeLeave :
553567 e = p .entities [index ]
554568 if e == nil {
555569 continue
@@ -561,7 +575,7 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
561575 }
562576
563577 op = st .EntityOpLeft
564- if cmd & updateFlagDelete != 0 {
578+ if flags & updateFlagDelete != 0 {
565579 op |= st .EntityOpDeleted
566580
567581 e .Destroy ()
0 commit comments