update to new go-steam version
This commit is contained in:
@@ -3,6 +3,11 @@ package csgo
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/an0nfunc/go-steam/v3"
|
||||
"github.com/an0nfunc/go-steam/v3/csgo/protocol/protobuf"
|
||||
"github.com/an0nfunc/go-steam/v3/protocol/gamecoordinator"
|
||||
@@ -13,12 +18,8 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/time/rate"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"os"
|
||||
"somegit.dev/csgowtf/csgowtfd/ent"
|
||||
"somegit.dev/csgowtf/csgowtfd/utils"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,24 +62,38 @@ type DemoMatchLoader struct {
|
||||
LoggedIn bool
|
||||
}
|
||||
|
||||
type PlayerRoundStats struct {
|
||||
Kills int32
|
||||
Deaths int32
|
||||
Assists int32
|
||||
Headshots int32
|
||||
Score int32
|
||||
MPVs int32
|
||||
}
|
||||
|
||||
func AccountID2SteamID(accID uint32) uint64 {
|
||||
return uint64(accID) + 76561197960265728 //nolint:gomnd
|
||||
}
|
||||
|
||||
func SteamID2AccountID(steamID uint64) uint32 {
|
||||
return uint32(steamID - 76561197960265728) //nolint:gomnd
|
||||
return uint32(steamID - 76561197960265728) //nolint:gosec,gomnd
|
||||
}
|
||||
|
||||
func playerStatsFromRound(round *protobuf.CMsgGCCStrike15V2_MatchmakingServerRoundStats, p *ent.Player) (kills int32,
|
||||
deaths int32, assists int32, headshots int32, score int32, mvps int32) {
|
||||
func playerStatsFromRound(round *protobuf.CMsgGCCStrike15V2_MatchmakingServerRoundStats, p *ent.Player) PlayerRoundStats {
|
||||
for i, acc := range round.GetReservation().GetAccountIds() {
|
||||
if AccountID2SteamID(acc) == p.ID {
|
||||
return round.GetKills()[i], round.GetDeaths()[i], round.GetAssists()[i], round.GetEnemyHeadshots()[i],
|
||||
round.GetScores()[i], round.GetMvps()[i]
|
||||
return PlayerRoundStats{
|
||||
Kills: round.GetKills()[i],
|
||||
Deaths: round.GetDeaths()[i],
|
||||
Assists: round.GetAssists()[i],
|
||||
Headshots: round.GetEnemyHeadshots()[i],
|
||||
Score: round.GetScores()[i],
|
||||
MPVs: round.GetMvps()[i],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, 0, 0, 0, 0, 0
|
||||
return PlayerRoundStats{}
|
||||
}
|
||||
|
||||
func (dml *DemoMatchLoader) IsLoading(demo *Demo) bool {
|
||||
@@ -146,7 +161,7 @@ func (dml *DemoMatchLoader) HandleGCPacket(pkg *gamecoordinator.GCPacket) {
|
||||
|
||||
func (dml *DemoMatchLoader) getMatchDetails(sharecode string) (*protobuf.CMsgGCCStrike15V2_MatchList, error) {
|
||||
if !dml.GCReady {
|
||||
return nil, fmt.Errorf("gc not ready")
|
||||
return nil, errors.New("gc not ready")
|
||||
}
|
||||
|
||||
matchID, outcomeID, tokenID, err := DecodeSharecode(sharecode)
|
||||
@@ -159,7 +174,7 @@ func (dml *DemoMatchLoader) getMatchDetails(sharecode string) (*protobuf.CMsgGCC
|
||||
}
|
||||
|
||||
for matchDetails := range dml.matchRecv {
|
||||
if *matchDetails.Matches[0].Matchid == matchID {
|
||||
if matchDetails.GetMatches()[0].GetMatchid() == matchID {
|
||||
return matchDetails, nil
|
||||
}
|
||||
dml.matchRecv <- matchDetails
|
||||
@@ -228,7 +243,7 @@ func (dml *DemoMatchLoader) Setup(config *DemoMatchLoaderConfig) error {
|
||||
go dml.steamEventHandler()
|
||||
go dml.demoWorker()
|
||||
|
||||
for i := 0; i < config.Worker; i++ {
|
||||
for range config.Worker {
|
||||
go dml.gcWorker(config.APIKey, config.RateLimit)
|
||||
}
|
||||
|
||||
@@ -249,7 +264,7 @@ func (dml *DemoMatchLoader) LoadDemo(demo *Demo) error {
|
||||
return nil
|
||||
default:
|
||||
dml.unlockDemo(demo)
|
||||
return fmt.Errorf("queue full")
|
||||
return errors.New("queue full")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +288,8 @@ func (dml *DemoMatchLoader) connectLoop() {
|
||||
case LoginSuccess:
|
||||
log.Info("[DL] Steam login successfully restored")
|
||||
dml.connectionWait = dml.connectionWaitTmpl
|
||||
default:
|
||||
panic("unhandled default case")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,7 +302,7 @@ func (dml *DemoMatchLoader) steamEventHandler() {
|
||||
dml.client.Auth.LogOn(dml.steamLogin)
|
||||
case *steam.MachineAuthUpdateEvent:
|
||||
log.Debug("[DL] Got sentry!")
|
||||
err := os.WriteFile(dml.sentryFile, e.Hash, os.ModePerm)
|
||||
err := os.WriteFile(dml.sentryFile, e.Hash, os.ModePerm) //nolint:gosec
|
||||
if err != nil {
|
||||
log.Errorf("[DL] Unable write sentry file: %v", err)
|
||||
}
|
||||
@@ -316,7 +333,7 @@ func (dml *DemoMatchLoader) steamEventHandler() {
|
||||
dml.connectFeedback <- LoginFailed
|
||||
case *steam.LoginKeyEvent:
|
||||
log.Debug("Got login_key!")
|
||||
err := os.WriteFile(dml.loginKey, []byte(e.LoginKey), os.ModePerm)
|
||||
err := os.WriteFile(dml.loginKey, []byte(e.LoginKey), os.ModePerm) //nolint:gosec
|
||||
if err != nil {
|
||||
log.Errorf("[DL] Unable write login_key: %v", err)
|
||||
}
|
||||
@@ -350,7 +367,7 @@ func (dml *DemoMatchLoader) greetGC() {
|
||||
|
||||
func (dml *DemoMatchLoader) requestDemoInfo(matchID, conclusionID uint64, tokenID uint32) error {
|
||||
if !dml.GCReady {
|
||||
return fmt.Errorf("gc not ready")
|
||||
return errors.New("gc not ready")
|
||||
}
|
||||
|
||||
msg := protobuf.CMsgGCCStrike15V2_MatchListRequestFullGameInfo{
|
||||
@@ -423,7 +440,7 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
||||
}
|
||||
|
||||
matchZero := matchDetails.GetMatches()[0]
|
||||
lastRound := matchZero.GetRoundstatsall()[len(matchZero.Roundstatsall)-1]
|
||||
lastRound := matchZero.GetRoundstatsall()[len(matchZero.GetRoundstatsall())-1]
|
||||
var players []*ent.Player //nolint:prealloc
|
||||
|
||||
for _, accountID := range lastRound.GetReservation().GetAccountIds() {
|
||||
@@ -471,9 +488,9 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
||||
|
||||
var oldKills int32
|
||||
for _, round := range matchZero.GetRoundstatsall() {
|
||||
kills, _, _, _, _, _ := playerStatsFromRound(round, mPlayer)
|
||||
roundStats := playerStatsFromRound(round, mPlayer)
|
||||
|
||||
switch kills - oldKills {
|
||||
switch roundStats.Kills - oldKills {
|
||||
case 2:
|
||||
mk2++
|
||||
case 3:
|
||||
@@ -483,20 +500,20 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
||||
case 5:
|
||||
mk5++
|
||||
}
|
||||
oldKills = kills
|
||||
oldKills = roundStats.Kills
|
||||
}
|
||||
|
||||
kills, deaths, assists, hs, score, mvp := playerStatsFromRound(lastRound, mPlayer)
|
||||
roundStats := playerStatsFromRound(lastRound, mPlayer)
|
||||
err = tx.MatchPlayer.Create().
|
||||
SetMatches(tMatch).
|
||||
SetPlayers(mPlayer).
|
||||
SetTeamID(teamID).
|
||||
SetKills(int(kills)).
|
||||
SetDeaths(int(deaths)).
|
||||
SetAssists(int(assists)).
|
||||
SetMvp(uint(mvp)).
|
||||
SetScore(int(score)).
|
||||
SetHeadshot(int(hs)).
|
||||
SetKills(int(roundStats.Kills)).
|
||||
SetDeaths(int(roundStats.Deaths)).
|
||||
SetAssists(int(roundStats.Assists)).
|
||||
SetMvp(uint(roundStats.MPVs)). //nolint:gosec
|
||||
SetScore(int(roundStats.Score)).
|
||||
SetHeadshot(int(roundStats.Headshots)).
|
||||
SetMk2(mk2).
|
||||
SetMk3(mk3).
|
||||
SetMk4(mk4).
|
||||
|
||||
@@ -7,19 +7,21 @@ import (
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/aclements/go-moremath/stats"
|
||||
"github.com/golang/geo/r2"
|
||||
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs"
|
||||
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs/common"
|
||||
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs/events"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aclements/go-moremath/stats"
|
||||
"github.com/golang/geo/r2"
|
||||
"github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs"
|
||||
"github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs/common"
|
||||
"github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs/events"
|
||||
"github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs/msg"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"somegit.dev/csgowtf/csgowtfd/ent"
|
||||
"somegit.dev/csgowtf/csgowtfd/ent/matchplayer"
|
||||
"somegit.dev/csgowtf/csgowtfd/utils"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Demo struct {
|
||||
@@ -112,7 +114,7 @@ func (dp *DemoParser) Setup(db *ent.Client, worker, sprayTimeout int) error {
|
||||
dp.db = db
|
||||
dp.sprayTimeout = sprayTimeout
|
||||
dp.Done = make(chan *Demo, worker)
|
||||
for i := 0; i < worker; i++ {
|
||||
for range worker {
|
||||
go dp.parseWorker()
|
||||
}
|
||||
return nil
|
||||
@@ -123,14 +125,14 @@ func (dp *DemoParser) ParseDemo(demo *Demo) error {
|
||||
case dp.demoQueue <- demo:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("queue full")
|
||||
return errors.New("queue full")
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Demo) download() (io.Reader, error) {
|
||||
log.Debugf("[DP] Downloading replay for %d", d.MatchID)
|
||||
|
||||
r, err := http.Get(d.URL) //nolint:bodyclose,noctx
|
||||
r, err := http.Get(d.URL) //nolint:bodyclose
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -152,7 +154,7 @@ func (dp *DemoParser) MatchPlayerBySteamID(mStats []*ent.MatchPlayer, steamID ui
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("player not found")
|
||||
return nil, errors.New("player not found")
|
||||
}
|
||||
|
||||
func setMatchPlayerColor(matchPlayer *ent.MatchPlayer, demoPlayer *common.Player) {
|
||||
@@ -255,9 +257,6 @@ workloop:
|
||||
pingMap := make(map[uint64][]float64)
|
||||
|
||||
cfg := demoinfocs.DefaultParserConfig
|
||||
if len(demo.DecryptionKey) == 16 { //nolint:gomnd
|
||||
cfg.NetMessageDecryptionKey = demo.DecryptionKey
|
||||
}
|
||||
demoParser := demoinfocs.NewParserWithConfig(fDemo, cfg)
|
||||
|
||||
// onChatMessage
|
||||
@@ -327,9 +326,9 @@ workloop:
|
||||
return
|
||||
}
|
||||
if e.Attacker.Team == e.Player.Team {
|
||||
tAttacker.DmgTeam += uint(e.HealthDamageTaken)
|
||||
tAttacker.DmgTeam += uint(e.HealthDamageTaken) //nolint:gosec
|
||||
} else {
|
||||
tAttacker.DmgEnemy += uint(e.HealthDamageTaken)
|
||||
tAttacker.DmgEnemy += uint(e.HealthDamageTaken) //nolint:gosec
|
||||
}
|
||||
|
||||
if _, ok := eqMap[e.Attacker.SteamID64]; !ok {
|
||||
@@ -344,7 +343,7 @@ workloop:
|
||||
found := false
|
||||
for _, di := range eqMap[e.Attacker.SteamID64] {
|
||||
if di.Eq == int(e.Weapon.Type) && di.HitGroup == int(e.HitGroup) {
|
||||
di.Dmg += uint(e.HealthDamageTaken)
|
||||
di.Dmg += uint(e.HealthDamageTaken) //nolint:gosec
|
||||
found = true
|
||||
}
|
||||
}
|
||||
@@ -355,12 +354,12 @@ workloop:
|
||||
HitGroup int
|
||||
Dmg uint
|
||||
To uint64
|
||||
}{Eq: int(e.Weapon.Type), HitGroup: int(e.HitGroup), Dmg: uint(e.HealthDamageTaken), To: e.Player.SteamID64})
|
||||
}{Eq: int(e.Weapon.Type), HitGroup: int(e.HitGroup), Dmg: uint(e.HealthDamageTaken), To: e.Player.SteamID64}) //nolint:gosec
|
||||
}
|
||||
})
|
||||
|
||||
// onRoundEnd
|
||||
demoParser.RegisterEventHandler(func(e events.RoundEnd) {
|
||||
demoParser.RegisterEventHandler(func(_ events.RoundEnd) {
|
||||
gs := demoParser.GameState()
|
||||
if !gs.IsMatchStarted() {
|
||||
return
|
||||
@@ -423,7 +422,7 @@ workloop:
|
||||
})
|
||||
|
||||
// onMatchStart
|
||||
demoParser.RegisterEventHandler(func(e events.MatchStart) {
|
||||
demoParser.RegisterEventHandler(func(_ events.MatchStart) {
|
||||
gs := demoParser.GameState()
|
||||
|
||||
for _, demoPlayer := range gs.Participants().Playing() {
|
||||
@@ -460,8 +459,13 @@ workloop:
|
||||
continue
|
||||
}
|
||||
|
||||
var mapName string
|
||||
demoParser.RegisterNetMessageHandler(func(m *msg.CDemoFileHeader) {
|
||||
mapName = m.GetMapName()
|
||||
})
|
||||
|
||||
err = tMatch.Update().
|
||||
SetMap(demoParser.Header().MapName).
|
||||
SetMap(mapName).
|
||||
SetDemoParsed(true).
|
||||
SetTickRate(demoParser.TickRate()).
|
||||
Exec(context.Background())
|
||||
@@ -526,10 +530,10 @@ workloop:
|
||||
for _, eco := range ecoMap[tMatchPlayer.PlayerStats] {
|
||||
err := tx.RoundStats.Create().
|
||||
SetMatchPlayer(nMatchPLayer).
|
||||
SetRound(uint(eco.Round)).
|
||||
SetBank(uint(eco.Bank)).
|
||||
SetEquipment(uint(eco.EqV)).
|
||||
SetSpent(uint(eco.Spent)).
|
||||
SetRound(uint(eco.Round)). //nolint:gosec
|
||||
SetBank(uint(eco.Bank)). //nolint:gosec
|
||||
SetEquipment(uint(eco.EqV)). //nolint:gosec
|
||||
SetSpent(uint(eco.Spent)). //nolint:gosec
|
||||
Exec(context.Background())
|
||||
if err != nil {
|
||||
err = utils.Rollback(tx, err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package csgo
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"regexp"
|
||||
@@ -29,10 +30,10 @@ func DecodeSharecode(code string) (matchID, outcomeID uint64, tokenID uint16, er
|
||||
bigInt.Add(bigInt, big.NewInt(int64(strings.Index(Base57Chars, c))))
|
||||
}
|
||||
|
||||
if bigInt.BitLen() > 144 { //nolint:gomnd
|
||||
return 0, 0, 0, fmt.Errorf("invalid sharecode")
|
||||
if bigInt.BitLen() > 144 {
|
||||
return 0, 0, 0, errors.New("invalid sharecode")
|
||||
}
|
||||
bytes := make([]byte, 18) //nolint:gomnd
|
||||
bytes := make([]byte, 18)
|
||||
bigInt.FillBytes(bytes)
|
||||
|
||||
matchID = binary.LittleEndian.Uint64(bytes[0:8])
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
package csgo
|
||||
package csgo_test
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
func TestGoodSharecodes(t *testing.T) {
|
||||
eMatchId := uint64(3505575050994516382)
|
||||
eOutcomeId := uint64(3505581094013501947)
|
||||
eTokenId := uint16(12909)
|
||||
"somegit.dev/csgowtf/csgowtfd/csgo"
|
||||
)
|
||||
|
||||
matchId, outcomeId, tokenId, err := DecodeSharecode("CSGO-P9k3F-eVL9n-LZLXN-DrBGF-VKD7K")
|
||||
func TestGoodSharecodes(t *testing.T) { //nolint:paralleltest
|
||||
eMatchID := uint64(3505575050994516382)
|
||||
eOutcomeID := uint64(3505581094013501947)
|
||||
eTokenID := uint16(12909)
|
||||
|
||||
matchID, outcomeId, tokenId, err := csgo.DecodeSharecode("CSGO-P9k3F-eVL9n-LZLXN-DrBGF-VKD7K")
|
||||
if err != nil {
|
||||
t.Log("error should be nil", err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if matchId != eMatchId {
|
||||
t.Logf("matchID should be %d, is %d", eMatchId, matchId)
|
||||
if matchID != eMatchID {
|
||||
t.Logf("matchID should be %d, is %d", eMatchID, matchID)
|
||||
t.Fail()
|
||||
}
|
||||
if outcomeId != eOutcomeId {
|
||||
t.Logf("outcomeID should be %d, is %d", eOutcomeId, outcomeId)
|
||||
if outcomeId != eOutcomeID {
|
||||
t.Logf("outcomeID should be %d, is %d", eOutcomeID, outcomeId)
|
||||
t.Fail()
|
||||
}
|
||||
if tokenId != eTokenId {
|
||||
t.Logf("tokenID should be %d, is %d", eTokenId, tokenId)
|
||||
if tokenId != eTokenID {
|
||||
t.Logf("tokenID should be %d, is %d", eTokenID, tokenId)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadSharecodes(t *testing.T) {
|
||||
matchId, outcomeId, tokenId, err := DecodeSharecode("CSGO-AAAAA-AAAAA-AAAAA-AAAAA-AAAAA")
|
||||
matchID, outcomeId, tokenId, err := csgo.DecodeSharecode("CSGO-AAAAA-AAAAA-AAAAA-AAAAA-AAAAA")
|
||||
if err != nil {
|
||||
t.Log("error should not be set", err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if matchId != 0 {
|
||||
t.Logf("matchID should be 0, is %d", matchId)
|
||||
if matchID != 0 {
|
||||
t.Logf("matchID should be 0, is %d", matchID)
|
||||
t.Fail()
|
||||
}
|
||||
if outcomeId != 0 {
|
||||
@@ -47,14 +51,14 @@ func TestBadSharecodes(t *testing.T) {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
matchId, outcomeId, tokenId, err = DecodeSharecode("CSGO-99999-99999-99999-99999-99999")
|
||||
matchID, outcomeId, tokenId, err = csgo.DecodeSharecode("CSGO-99999-99999-99999-99999-99999")
|
||||
if err == nil {
|
||||
t.Log("error should be set", err)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if matchId != 0 {
|
||||
t.Logf("matchID should be 0, is %d", matchId)
|
||||
if matchID != 0 {
|
||||
t.Logf("matchID should be 0, is %d", matchID)
|
||||
t.Fail()
|
||||
}
|
||||
if outcomeId != 0 {
|
||||
|
||||
Reference in New Issue
Block a user