diff --git a/dissect/header.go b/dissect/header.go index afdc15c..4117ec9 100644 --- a/dissect/header.go +++ b/dissect/header.go @@ -512,6 +512,9 @@ func (r *Reader) deriveTeamRoles() { log.Debug().Interface("player", p).Send() if p.Operator != 0 { players = append(players, p) + r.Scoreboard.Players = append(r.Scoreboard.Players, ScoreboardPlayer{ + ID: p.DissectID, + }) } else { log.Warn().Str("username", p.Username).Msg("operator id was 0, removing from list") } diff --git a/dissect/match.go b/dissect/match.go index b00af2f..f0ed89f 100644 --- a/dissect/match.go +++ b/dissect/match.go @@ -139,7 +139,7 @@ func (m *MatchReader) WriteExcel(out io.Writer) error { c.Right(1).Str("Team Index") c.Right(1).Str("Kills") c.Right(1).Str("Died") - c.Right(1).Str("Assists (TODO)") + c.Right(1).Str("Assists") c.Right(1).Str("Hs%") c.Right(1).Str("Headshots") c.Right(1).Str("1vX") @@ -247,7 +247,7 @@ func (m *MatchReader) WriteExcel(out io.Writer) error { c.Right(1).Str("Rounds") c.Right(1).Str("Kills") c.Right(1).Str("Deaths") - c.Right(1).Str("Assists (TODO)") + c.Right(1).Str("Assists") c.Right(1).Str("Hs%") c.Right(1).Str("Headshots") diff --git a/dissect/reader.go b/dissect/reader.go index e631f93..7cbd33c 100644 --- a/dissect/reader.go +++ b/dissect/reader.go @@ -30,6 +30,7 @@ type Reader struct { playersRead int Header Header `json:"header"` MatchFeedback []MatchUpdate `json:"matchFeedback"` + Scoreboard Scoreboard } // NewReader decompresses in using zstd and @@ -49,7 +50,7 @@ func NewReader(in io.Reader) (r *Reader, err error) { return r, err } } else { - if err = r.readUnchunkedData(br); err != nil { + if err = r.readNonChunkedData(br); err != nil { return r, err } } @@ -65,6 +66,8 @@ func NewReader(in io.Reader) (r *Reader, err error) { } r.Listen([]byte{0x59, 0x34, 0xE5, 0x8B, 0x04}, readMatchFeedback) r.Listen([]byte{0x22, 0xA9, 0xC8, 0x58, 0xD9}, readDefuserTimer) + r.Listen([]byte{0xEC, 0xDA, 0x4F, 0x80}, readScoreboardScore) + r.Listen([]byte{0x4D, 0x73, 0x7F, 0x9E}, readScoreboardAssists) return r, err } @@ -133,7 +136,7 @@ func (r *Reader) readChunkedData(genericReader io.Reader) error { return nil } -func (r *Reader) readUnchunkedData(genericReader io.Reader) error { +func (r *Reader) readNonChunkedData(genericReader io.Reader) error { zstdReader, err := zstd.NewReader(genericReader) if err != nil { return err diff --git a/dissect/scoreboard.go b/dissect/scoreboard.go new file mode 100644 index 0000000..cc41a5c --- /dev/null +++ b/dissect/scoreboard.go @@ -0,0 +1,69 @@ +package dissect + +import "github.com/rs/zerolog/log" + +type Scoreboard struct { + Players []ScoreboardPlayer +} + +type ScoreboardPlayer struct { + ID []byte + Score uint32 + Assists uint32 +} + +func readScoreboardAssists(r *Reader) error { + assists, err := r.Uint32() + if err != nil { + return err + } + if assists == 0 { + return nil + } + if err = r.Skip(30); err != nil { + return err + } + id, err := r.Bytes(4) + if err != nil { + return err + } + idx := r.PlayerIndexByID(id) + username := "N/A" + if idx != -1 { + username = r.Header.Players[idx].Username + r.Scoreboard.Players[idx].Assists = assists + } + log.Debug(). + Uint32("assists", assists). + Str("username", username). + Msg("scoreboard_assists") + return nil +} + +func readScoreboardScore(r *Reader) error { + score, err := r.Uint32() + if err != nil { + return err + } + if score == 0 { + return nil + } + if err = r.Skip(13); err != nil { + return err + } + id, err := r.Bytes(4) + if err != nil { + return err + } + idx := r.PlayerIndexByID(id) + username := "N/A" + if idx != -1 { + username = r.Header.Players[idx].Username + r.Scoreboard.Players[idx].Score = score + } + log.Debug(). + Uint32("score", score). + Str("username", username). + Msg("scoreboard_score") + return nil +} diff --git a/dissect/stats.go b/dissect/stats.go index b28fa45..d7305b0 100644 --- a/dissect/stats.go +++ b/dissect/stats.go @@ -3,6 +3,7 @@ package dissect type PlayerRoundStats struct { Username string `json:"username"` TeamIndex int `json:"-"` + Score int `json:"score"` Operator string `json:"-"` Kills int `json:"kills"` Died bool `json:"died"` @@ -83,10 +84,13 @@ func (r *Reader) PlayerStats() []PlayerRoundStats { winningTeamIndex = 1 } for i, p := range r.Header.Players { + scorePlayer := r.Scoreboard.Players[i] stats = append(stats, PlayerRoundStats{ Username: p.Username, TeamIndex: p.TeamIndex, Operator: p.Operator.String(), + Assists: int(scorePlayer.Assists), + Score: int(scorePlayer.Score), }) index[p.Username] = i }