Skip to content

Commit

Permalink
Merge pull request #460 from markus-wa/s2-fake-CMsgSource1LegacyGameE…
Browse files Browse the repository at this point in the history
…ventList

CS2: fake CMsgSource1LegacyGameEventList if missing
  • Loading branch information
markus-wa authored Feb 5, 2024
2 parents 6c73556 + 7530bcd commit e98a3fa
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 18 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/markus-wa/quickhull-go/v2 v2.2.0
github.com/oklog/ulid/v2 v2.1.0
github.com/pkg/errors v0.9.1
github.com/samber/lo v1.38.1
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
google.golang.org/protobuf v1.31.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ github.com/markus-wa/gobitread v0.2.3 h1:COx7dtYQ7Q+77hgUmD+O4MvOcqG7y17RP3Z7Bbj
github.com/markus-wa/gobitread v0.2.3/go.mod h1:PcWXMH4gx7o2CKslbkFkLyJB/aHW7JVRG3MRZe3PINg=
github.com/markus-wa/godispatch v1.4.1 h1:Cdff5x33ShuX3sDmUbYWejk7tOuoHErFYMhUc2h7sLc=
github.com/markus-wa/godispatch v1.4.1/go.mod h1:tk8L0yzLO4oAcFwM2sABMge0HRDJMdE8E7xm4gK/+xM=
github.com/markus-wa/ice-cipher-go v0.0.0-20220823210642-1fcccd18c6c1 h1:YH4WI14HARrM3C6mKUMFDBz93O25oWSlLEYGeL27G0w=
github.com/markus-wa/ice-cipher-go v0.0.0-20220823210642-1fcccd18c6c1/go.mod h1:JIsht5Oa9P50VnGJTvH2a6nkOqDFJbUeU1YRZYvdplw=
github.com/markus-wa/ice-cipher-go v0.0.0-20230901094113-348096939ba7 h1:aR9pvnlnBxifXBmzidpAiq2prLSGlkhE904qnk2sCz4=
github.com/markus-wa/ice-cipher-go v0.0.0-20230901094113-348096939ba7/go.mod h1:JIsht5Oa9P50VnGJTvH2a6nkOqDFJbUeU1YRZYvdplw=
github.com/markus-wa/quickhull-go/v2 v2.2.0 h1:rB99NLYeUHoZQ/aNRcGOGqjNBGmrOaRxdtqTnsTUPTA=
Expand All @@ -38,6 +36,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand Down
8 changes: 8 additions & 0 deletions pkg/demoinfocs/demoinfocs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import (
"time"

dispatch "github.com/markus-wa/godispatch"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/proto"

demoinfocs "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs"
common "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common"
events "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/events"
msg "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/msg"
"github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/msgs2"
)

const (
Expand Down Expand Up @@ -214,6 +216,12 @@ func TestS2(t *testing.T) {

p := demoinfocs.NewParserWithConfig(f, cfg)

if *update {
p.RegisterNetMessageHandler(func(gel *msgs2.CMsgSource1LegacyGameEventList) {
lo.Must0(os.WriteFile("s2_CMsgSource1LegacyGameEventList.pb.bin", lo.Must(proto.Marshal(gel)), 0600))
})
}

t.Log("Parsing header")
_, err = p.ParseHeader()
assertions.NoError(err, "error returned by Parser.ParseHeader()")
Expand Down
19 changes: 19 additions & 0 deletions pkg/demoinfocs/game_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/golang/geo/r3"
"github.com/markus-wa/go-unassert"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"

common "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common"
events "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/events"
Expand Down Expand Up @@ -79,6 +80,24 @@ func (p *parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
}

func (p *parser) handleGameEventS2(ge *msgs2.CMsgSource1LegacyGameEvent) {
if p.gameEventDescs == nil {
p.eventDispatcher.Dispatch(events.ParserWarn{
Message: "received GameEvent but event descriptors are missing",
Type: events.WarnTypeGameEventBeforeDescriptors,
})

list := new(msgs2.CMsgSource1LegacyGameEventList)

err := proto.Unmarshal(p.source2FallbackGameEventListBin, list)
if err != nil {
p.setError(err)

return
}

p.handleGameEventListS2(list)
}

keys := make([]*msg.CSVCMsg_GameEventKeyT, 0, len(ge.Keys))

for _, k := range ge.Keys {
Expand Down
47 changes: 31 additions & 16 deletions pkg/demoinfocs/parser.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package demoinfocs

import (
_ "embed"
"fmt"
"io"
"runtime/debug"
Expand Down Expand Up @@ -66,22 +67,23 @@ Prints out '{A/B} site went BOOM!' when a bomb explodes.
type parser struct {
// Important fields

bitReader *bit.BitReader
stParser sendTableParser
additionalNetMessageCreators map[int]NetMessageCreator // Map of net-message-IDs to NetMessageCreators (for parsing custom net-messages)
msgQueue chan any // Queue of net-messages
msgDispatcher *dp.Dispatcher // Net-message dispatcher
gameEventHandler gameEventHandler
userMessageHandler userMessageHandler
eventDispatcher *dp.Dispatcher
currentFrame int // Demo-frame, not ingame-tick
tickInterval float32 // Duration between ticks in seconds
header *common.DemoHeader // Pointer so we can check for nil
gameState *gameState
demoInfoProvider demoInfoProvider // Provides demo infos to other packages that the core package depends on
err error // Contains a error that occurred during parsing if any
errLock sync.Mutex // Used to sync up error mutations between parsing & handling go-routines
decryptionKey []byte // Stored in `match730_*.dem.info` see MatchInfoDecryptionKey().
bitReader *bit.BitReader
stParser sendTableParser
additionalNetMessageCreators map[int]NetMessageCreator // Map of net-message-IDs to NetMessageCreators (for parsing custom net-messages)
msgQueue chan any // Queue of net-messages
msgDispatcher *dp.Dispatcher // Net-message dispatcher
gameEventHandler gameEventHandler
userMessageHandler userMessageHandler
eventDispatcher *dp.Dispatcher
currentFrame int // Demo-frame, not ingame-tick
tickInterval float32 // Duration between ticks in seconds
header *common.DemoHeader // Pointer so we can check for nil
gameState *gameState
demoInfoProvider demoInfoProvider // Provides demo infos to other packages that the core package depends on
err error // Contains a error that occurred during parsing if any
errLock sync.Mutex // Used to sync up error mutations between parsing & handling go-routines
decryptionKey []byte // Stored in `match730_*.dem.info` see MatchInfoDecryptionKey().
source2FallbackGameEventListBin []byte // sv_hibernate_when_empty bug workaround
/**
* Set to the client slot of the recording player.
* Always -1 for GOTV demos.
Expand Down Expand Up @@ -353,13 +355,21 @@ type ParserConfig struct {
// Unfortunately Source 2 demos *may* not contain Source 1 game events, that's why the parser will try to mimic them.
// It has an impact only with Source 2 demos and is false by default.
DisableMimicSource1Events bool

// Source2FallbackGameEventListBin is a fallback game event list protobuf message for Source 2 demos.
// It's used when the game event list is not found in the demo file.
// This can happen due to a CS2 bug with sv_hibernate_when_empty.
Source2FallbackGameEventListBin []byte
}

// DefaultParserConfig is the default Parser configuration used by NewParser().
var DefaultParserConfig = ParserConfig{
MsgQueueBufferSize: -1,
}

//go:embed s2_CMsgSource1LegacyGameEventList.pb.bin
var defaultSource2FallbackGameEventListBin []byte

// NewParserWithConfig returns a new Parser with a custom configuration.
//
// See also: NewParser() & ParserConfig
Expand All @@ -382,6 +392,11 @@ func NewParserWithConfig(demostream io.Reader, config ParserConfig) Parser {
p.decryptionKey = config.NetMessageDecryptionKey
p.recordingPlayerSlot = -1
p.disableMimicSource1GameEvents = config.DisableMimicSource1Events
p.source2FallbackGameEventListBin = config.Source2FallbackGameEventListBin

if p.source2FallbackGameEventListBin == nil {
p.source2FallbackGameEventListBin = defaultSource2FallbackGameEventListBin
}

dispatcherCfg := dp.Config{
PanicHandler: func(v any) {
Expand Down
1 change: 1 addition & 0 deletions pkg/demoinfocs/parser_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package demoinfocs

import (
_ "embed"
"time"

"github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common"
Expand Down
Binary file not shown.

0 comments on commit e98a3fa

Please sign in to comment.