updated deps, added golangci linter
This commit is contained in:
73
.golangci.yaml
Normal file
73
.golangci.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
linters-settings:
|
||||||
|
dupl:
|
||||||
|
threshold: 100
|
||||||
|
goconst:
|
||||||
|
min-len: 3
|
||||||
|
min-occurrences: 4
|
||||||
|
gocritic:
|
||||||
|
enabled-tags:
|
||||||
|
- diagnostic
|
||||||
|
- experimental
|
||||||
|
- opinionated
|
||||||
|
- performance
|
||||||
|
- style
|
||||||
|
disabled-checks:
|
||||||
|
- whyNoLint
|
||||||
|
gomnd:
|
||||||
|
checks:
|
||||||
|
- argument
|
||||||
|
- case
|
||||||
|
- condition
|
||||||
|
- return
|
||||||
|
ignored-numbers:
|
||||||
|
- '0'
|
||||||
|
- '1'
|
||||||
|
- '2'
|
||||||
|
- '3'
|
||||||
|
- '4'
|
||||||
|
- '5'
|
||||||
|
ignored-functions:
|
||||||
|
- strings.SplitN
|
||||||
|
govet:
|
||||||
|
check-shadowing: false
|
||||||
|
lll:
|
||||||
|
line-length: 140
|
||||||
|
misspell:
|
||||||
|
locale: US
|
||||||
|
nolintlint:
|
||||||
|
allow-unused: false # report any unused nolint directives
|
||||||
|
require-explanation: false # don't require an explanation for nolint directives
|
||||||
|
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- bodyclose
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- exportloopref
|
||||||
|
- gochecknoinits
|
||||||
|
- gocritic
|
||||||
|
- gofmt
|
||||||
|
- gomnd
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- lll
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- staticcheck
|
||||||
|
- stylecheck
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- whitespace
|
||||||
|
|
||||||
|
run:
|
||||||
|
go: '1.18'
|
@@ -7,7 +7,6 @@ import (
|
|||||||
"git.harting.dev/csgowtf/csgowtfd/utils"
|
"git.harting.dev/csgowtf/csgowtfd/utils"
|
||||||
"github.com/an0nfunc/go-steam/v3"
|
"github.com/an0nfunc/go-steam/v3"
|
||||||
"github.com/an0nfunc/go-steam/v3/csgo/protocol/protobuf"
|
"github.com/an0nfunc/go-steam/v3/csgo/protocol/protobuf"
|
||||||
"github.com/an0nfunc/go-steam/v3/netutil"
|
|
||||||
"github.com/an0nfunc/go-steam/v3/protocol/gamecoordinator"
|
"github.com/an0nfunc/go-steam/v3/protocol/gamecoordinator"
|
||||||
"github.com/an0nfunc/go-steam/v3/protocol/steamlang"
|
"github.com/an0nfunc/go-steam/v3/protocol/steamlang"
|
||||||
"github.com/go-redis/cache/v8"
|
"github.com/go-redis/cache/v8"
|
||||||
@@ -34,9 +33,9 @@ type DemoMatchLoaderConfig struct {
|
|||||||
AuthCode string
|
AuthCode string
|
||||||
Sentry string
|
Sentry string
|
||||||
LoginKey string
|
LoginKey string
|
||||||
Db *ent.Client
|
DB *ent.Client
|
||||||
Worker int
|
Worker int
|
||||||
ApiKey string
|
APIKey string
|
||||||
RateLimit *rate.Limiter
|
RateLimit *rate.Limiter
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
SprayTimeout int
|
SprayTimeout int
|
||||||
@@ -48,7 +47,6 @@ type DemoMatchLoader struct {
|
|||||||
GCReady bool
|
GCReady bool
|
||||||
steamLogin *steam.LogOnDetails
|
steamLogin *steam.LogOnDetails
|
||||||
matchRecv chan *protobuf.CMsgGCCStrike15V2_MatchList
|
matchRecv chan *protobuf.CMsgGCCStrike15V2_MatchList
|
||||||
cmList []*netutil.PortAddr
|
|
||||||
sentryFile string
|
sentryFile string
|
||||||
loginKey string
|
loginKey string
|
||||||
db *ent.Client
|
db *ent.Client
|
||||||
@@ -63,18 +61,20 @@ type DemoMatchLoader struct {
|
|||||||
LoggedIn bool
|
LoggedIn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func AccountId2SteamId(accId uint32) uint64 {
|
func AccountID2SteamID(accID uint32) uint64 {
|
||||||
return uint64(accId) + 76561197960265728
|
return uint64(accID) + 76561197960265728 //nolint:gomnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func SteamId2AccountId(steamId uint64) uint32 {
|
func SteamID2AccountID(steamID uint64) uint32 {
|
||||||
return uint32(steamId - 76561197960265728)
|
return uint32(steamID - 76561197960265728) //nolint: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) (kills int32,
|
||||||
|
deaths int32, assists int32, headshots int32, score int32, mvps int32) {
|
||||||
for i, acc := range round.GetReservation().GetAccountIds() {
|
for i, acc := range round.GetReservation().GetAccountIds() {
|
||||||
if AccountId2SteamId(acc) == p.ID {
|
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 round.GetKills()[i], round.GetDeaths()[i], round.GetAssists()[i], round.GetEnemyHeadshots()[i],
|
||||||
|
round.GetScores()[i], round.GetMvps()[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,25 +149,23 @@ func (dml *DemoMatchLoader) getMatchDetails(sharecode string) (*protobuf.CMsgGCC
|
|||||||
return nil, fmt.Errorf("gc not ready")
|
return nil, fmt.Errorf("gc not ready")
|
||||||
}
|
}
|
||||||
|
|
||||||
matchId, outcomeId, tokenId, err := DecodeSharecode(sharecode)
|
matchID, outcomeID, tokenID, err := DecodeSharecode(sharecode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = dml.requestDemoInfo(matchId, outcomeId, uint32(tokenId))
|
err = dml.requestDemoInfo(matchID, outcomeID, uint32(tokenID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for matchDetails := range dml.matchRecv {
|
||||||
select {
|
if *matchDetails.Matches[0].Matchid == matchID {
|
||||||
case matchDetails := <-dml.matchRecv:
|
|
||||||
if *matchDetails.Matches[0].Matchid == matchId {
|
|
||||||
return matchDetails, nil
|
return matchDetails, nil
|
||||||
} else {
|
} else {
|
||||||
dml.matchRecv <- matchDetails
|
dml.matchRecv <- matchDetails
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dml *DemoMatchLoader) connectToSteam() error {
|
func (dml *DemoMatchLoader) connectToSteam() error {
|
||||||
@@ -185,15 +183,15 @@ func (dml *DemoMatchLoader) connectToSteam() error {
|
|||||||
func (dml *DemoMatchLoader) Setup(config *DemoMatchLoaderConfig) error {
|
func (dml *DemoMatchLoader) Setup(config *DemoMatchLoaderConfig) error {
|
||||||
dml.loginKey = config.LoginKey
|
dml.loginKey = config.LoginKey
|
||||||
dml.sentryFile = config.Sentry
|
dml.sentryFile = config.Sentry
|
||||||
dml.db = config.Db
|
dml.db = config.DB
|
||||||
dml.dp = &DemoParser{}
|
dml.dp = &DemoParser{}
|
||||||
dml.parseMap = map[string]bool{}
|
dml.parseMap = map[string]bool{}
|
||||||
dml.parseMapL = new(sync.RWMutex)
|
dml.parseMapL = new(sync.RWMutex)
|
||||||
dml.cache = config.Cache
|
dml.cache = config.Cache
|
||||||
dml.connectFeedback = make(chan int, 10)
|
dml.connectFeedback = make(chan int, 10) //nolint:gomnd
|
||||||
dml.connectionWait = retry.WithCappedDuration(time.Minute*time.Duration(config.RetryTimeout), retry.NewExponential(time.Minute))
|
dml.connectionWait = retry.WithCappedDuration(time.Minute*time.Duration(config.RetryTimeout), retry.NewExponential(time.Minute))
|
||||||
dml.connectionWaitTmpl = retry.WithCappedDuration(time.Minute*time.Duration(config.RetryTimeout), retry.NewExponential(time.Minute))
|
dml.connectionWaitTmpl = retry.WithCappedDuration(time.Minute*time.Duration(config.RetryTimeout), retry.NewExponential(time.Minute))
|
||||||
err := dml.dp.Setup(config.Db, config.Worker, config.SprayTimeout)
|
err := dml.dp.Setup(config.DB, config.Worker, config.SprayTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -225,15 +223,15 @@ func (dml *DemoMatchLoader) Setup(config *DemoMatchLoaderConfig) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dml.matchRecv = make(chan *protobuf.CMsgGCCStrike15V2_MatchList, 1000)
|
dml.matchRecv = make(chan *protobuf.CMsgGCCStrike15V2_MatchList, 1000) //nolint:gomnd
|
||||||
dml.parseDemo = make(chan *Demo, 1000)
|
dml.parseDemo = make(chan *Demo, 1000) //nolint:gomnd
|
||||||
|
|
||||||
go dml.connectLoop()
|
go dml.connectLoop()
|
||||||
go dml.steamEventHandler()
|
go dml.steamEventHandler()
|
||||||
go dml.demoWorker()
|
go dml.demoWorker()
|
||||||
|
|
||||||
for i := 0; i < config.Worker; i++ {
|
for i := 0; i < config.Worker; i++ {
|
||||||
go dml.gcWorker(config.ApiKey, config.RateLimit)
|
go dml.gcWorker(config.APIKey, config.RateLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
dml.connectFeedback <- LoginFailed
|
dml.connectFeedback <- LoginFailed
|
||||||
@@ -258,9 +256,7 @@ func (dml *DemoMatchLoader) LoadDemo(demo *Demo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dml *DemoMatchLoader) connectLoop() {
|
func (dml *DemoMatchLoader) connectLoop() {
|
||||||
for {
|
for res := range dml.connectFeedback {
|
||||||
select {
|
|
||||||
case res := <-dml.connectFeedback:
|
|
||||||
switch res {
|
switch res {
|
||||||
case LoginFailed:
|
case LoginFailed:
|
||||||
if sleep, ok := dml.connectionWait.Next(); !ok {
|
if sleep, ok := dml.connectionWait.Next(); !ok {
|
||||||
@@ -282,7 +278,6 @@ func (dml *DemoMatchLoader) connectLoop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (dml *DemoMatchLoader) steamEventHandler() {
|
func (dml *DemoMatchLoader) steamEventHandler() {
|
||||||
for event := range dml.client.Events() {
|
for event := range dml.client.Events() {
|
||||||
@@ -355,16 +350,19 @@ func (dml *DemoMatchLoader) greetGC() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dml *DemoMatchLoader) requestDemoInfo(matchId uint64, conclusionId uint64, tokenId uint32) error {
|
func (dml *DemoMatchLoader) requestDemoInfo(matchID, conclusionID uint64, tokenID uint32) error {
|
||||||
if !dml.GCReady {
|
if !dml.GCReady {
|
||||||
return fmt.Errorf("gc not ready")
|
return fmt.Errorf("gc not ready")
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := protobuf.CMsgGCCStrike15V2_MatchListRequestFullGameInfo{Matchid: &matchId,
|
msg := protobuf.CMsgGCCStrike15V2_MatchListRequestFullGameInfo{
|
||||||
Outcomeid: &conclusionId,
|
Matchid: &matchID,
|
||||||
Token: &tokenId}
|
Outcomeid: &conclusionID,
|
||||||
|
Token: &tokenID,
|
||||||
|
}
|
||||||
|
|
||||||
dml.client.GC.Write(gamecoordinator.NewGCMsgProtobuf(APPID, uint32(protobuf.ECsgoGCMsg_k_EMsgGCCStrike15_v2_MatchListRequestFullGameInfo), &msg))
|
dml.client.GC.Write(gamecoordinator.NewGCMsgProtobuf(APPID,
|
||||||
|
uint32(protobuf.ECsgoGCMsg_k_EMsgGCCStrike15_v2_MatchListRequestFullGameInfo), &msg))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -379,46 +377,46 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
|||||||
defer dml.unlockDemo(demo)
|
defer dml.unlockDemo(demo)
|
||||||
|
|
||||||
if !dml.GCReady {
|
if !dml.GCReady {
|
||||||
log.Infof("[DL] Postponing match %d (%s): GC not ready", demo.MatchId, demo.ShareCode)
|
log.Infof("[DL] Postponing match %d (%s): GC not ready", demo.MatchID, demo.ShareCode)
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
dml.parseDemo <- demo
|
dml.parseDemo <- demo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
matchId, _, _, err := DecodeSharecode(demo.ShareCode)
|
matchID, _, _, err := DecodeSharecode(demo.ShareCode)
|
||||||
if err != nil || matchId == 0 {
|
if err != nil || matchID == 0 {
|
||||||
return fmt.Errorf("error decoding sharecode %s: %w", demo.ShareCode, err)
|
return fmt.Errorf("error decoding sharecode %s: %w", demo.ShareCode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
iMatch, err := dml.db.Match.Get(context.Background(), matchId)
|
iMatch, err := dml.db.Match.Get(context.Background(), matchID)
|
||||||
if err != nil && !ent.IsNotFound(err) {
|
if err != nil && !ent.IsNotFound(err) {
|
||||||
return fmt.Errorf("error looking up match: %w", err)
|
return fmt.Errorf("error looking up match: %w", err)
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
if iMatch.DemoParsed == false && iMatch.Date.After(time.Now().UTC().AddDate(0, 0, -30)) {
|
if !iMatch.DemoParsed && iMatch.Date.After(time.Now().UTC().AddDate(0, 0, -30)) {
|
||||||
log.Infof("[DL] Match %d is loaded, but not parsed. Try parsing.", iMatch.ID)
|
log.Infof("[DL] Match %d is loaded, but not parsed. Try parsing.", iMatch.ID)
|
||||||
demo.MatchId = matchId
|
demo.MatchID = matchID
|
||||||
demo.Url = iMatch.ReplayURL
|
demo.URL = iMatch.ReplayURL
|
||||||
demo.DecryptionKey = iMatch.DecryptionKey
|
demo.DecryptionKey = iMatch.DecryptionKey
|
||||||
err := dml.dp.ParseDemo(demo)
|
err := dml.dp.ParseDemo(demo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing match %d: %w", demo.MatchId, err)
|
return fmt.Errorf("error parsing match %d: %w", demo.MatchID, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[DL] Skipped match %d: already loaded", matchId)
|
log.Infof("[DL] Skipped match %d: already loaded", matchID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[DL] Requesting match %d from GC", matchId)
|
log.Infof("[DL] Requesting match %d from GC", matchID)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
|
|
||||||
matchDetails, err := dml.getMatchDetails(demo.ShareCode)
|
matchDetails, err := dml.getMatchDetails(demo.ShareCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting match-details for %d: %w", demo.MatchId, err)
|
return fmt.Errorf("error getting match-details for %d: %w", demo.MatchID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[DL] Recieved matchdetails for match %d (%s)", matchId, time.Since(t))
|
log.Infof("[DL] Received matchdetails for match %d (%s)", matchID, time.Since(t))
|
||||||
|
|
||||||
// init tx
|
// init tx
|
||||||
tx, err := dml.db.Tx(context.Background())
|
tx, err := dml.db.Tx(context.Background())
|
||||||
@@ -430,17 +428,17 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
|||||||
lastRound := matchZero.GetRoundstatsall()[len(matchZero.Roundstatsall)-1]
|
lastRound := matchZero.GetRoundstatsall()[len(matchZero.Roundstatsall)-1]
|
||||||
var players []*ent.Player
|
var players []*ent.Player
|
||||||
|
|
||||||
for _, accountId := range lastRound.GetReservation().GetAccountIds() {
|
for _, accountID := range lastRound.GetReservation().GetAccountIds() {
|
||||||
tPlayer, err := utils.Player(tx.Client(), AccountId2SteamId(accountId), apiKey, rl)
|
tPlayer, err := utils.Player(tx.Client(), AccountID2SteamID(accountID), apiKey, rl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
return fmt.Errorf("error getting player for steamid %d: %w", AccountId2SteamId(accountId), err)
|
return fmt.Errorf("error getting player for steamid %d: %w", AccountID2SteamID(accountID), err)
|
||||||
}
|
}
|
||||||
players = append(players, tPlayer)
|
players = append(players, tPlayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
demo.Url = lastRound.GetMap()
|
demo.URL = lastRound.GetMap()
|
||||||
demo.MatchId = matchZero.GetMatchid()
|
demo.MatchID = matchZero.GetMatchid()
|
||||||
demo.DecryptionKey = []byte(strings.ToUpper(fmt.Sprintf("%016x", matchZero.GetWatchablematchinfo().GetClDecryptdataKeyPub())))
|
demo.DecryptionKey = []byte(strings.ToUpper(fmt.Sprintf("%016x", matchZero.GetWatchablematchinfo().GetClDecryptdataKeyPub())))
|
||||||
|
|
||||||
tMatch, err := tx.Match.Create().
|
tMatch, err := tx.Match.Create().
|
||||||
@@ -463,14 +461,14 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
|||||||
|
|
||||||
for i, mPlayer := range players {
|
for i, mPlayer := range players {
|
||||||
var (
|
var (
|
||||||
teamId int
|
teamID int
|
||||||
mk2, mk3, mk4, mk5 uint
|
mk2, mk3, mk4, mk5 uint
|
||||||
)
|
)
|
||||||
|
|
||||||
if i > 4 {
|
if i > 4 {
|
||||||
teamId = 2
|
teamID = 2
|
||||||
} else {
|
} else {
|
||||||
teamId = 1
|
teamID = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldKills int32
|
var oldKills int32
|
||||||
@@ -494,7 +492,7 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
|||||||
err = tx.MatchPlayer.Create().
|
err = tx.MatchPlayer.Create().
|
||||||
SetMatches(tMatch).
|
SetMatches(tMatch).
|
||||||
SetPlayers(mPlayer).
|
SetPlayers(mPlayer).
|
||||||
SetTeamID(teamId).
|
SetTeamID(teamID).
|
||||||
SetKills(int(kills)).
|
SetKills(int(kills)).
|
||||||
SetDeaths(int(deaths)).
|
SetDeaths(int(deaths)).
|
||||||
SetAssists(int(assists)).
|
SetAssists(int(assists)).
|
||||||
@@ -539,7 +537,7 @@ func (dml *DemoMatchLoader) handleDemo(demo *Demo, apiKey string, rl *rate.Limit
|
|||||||
|
|
||||||
err = dml.dp.ParseDemo(demo)
|
err = dml.dp.ParseDemo(demo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error queueing demo %d for parsing: %w", demo.MatchId, err)
|
return fmt.Errorf("error queueing demo %d for parsing: %w", demo.MatchID, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.harting.dev/csgowtf/csgowtfd/ent"
|
"git.harting.dev/csgowtf/csgowtfd/ent"
|
||||||
"git.harting.dev/csgowtf/csgowtfd/ent/match"
|
|
||||||
"git.harting.dev/csgowtf/csgowtfd/ent/matchplayer"
|
"git.harting.dev/csgowtf/csgowtfd/ent/matchplayer"
|
||||||
"git.harting.dev/csgowtf/csgowtfd/ent/player"
|
|
||||||
"git.harting.dev/csgowtf/csgowtfd/utils"
|
"git.harting.dev/csgowtf/csgowtfd/utils"
|
||||||
"github.com/golang/geo/r2"
|
"github.com/golang/geo/r2"
|
||||||
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs"
|
"github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs"
|
||||||
@@ -24,14 +22,13 @@ import (
|
|||||||
|
|
||||||
type Demo struct {
|
type Demo struct {
|
||||||
ShareCode string
|
ShareCode string
|
||||||
MatchId uint64
|
MatchID uint64
|
||||||
Url string
|
URL string
|
||||||
DecryptionKey []byte
|
DecryptionKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type DemoParser struct {
|
type DemoParser struct {
|
||||||
demoQueue chan *Demo
|
demoQueue chan *Demo
|
||||||
tempDir string
|
|
||||||
db *ent.Client
|
db *ent.Client
|
||||||
sprayTimeout int
|
sprayTimeout int
|
||||||
Done chan *Demo
|
Done chan *Demo
|
||||||
@@ -108,8 +105,8 @@ func (s *Sprays) Avg() (avg [][]float32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dp *DemoParser) Setup(db *ent.Client, worker int, sprayTimeout int) error {
|
func (dp *DemoParser) Setup(db *ent.Client, worker, sprayTimeout int) error {
|
||||||
dp.demoQueue = make(chan *Demo, 1000)
|
dp.demoQueue = make(chan *Demo, 1000) //nolint:gomnd
|
||||||
dp.db = db
|
dp.db = db
|
||||||
dp.sprayTimeout = sprayTimeout
|
dp.sprayTimeout = sprayTimeout
|
||||||
dp.Done = make(chan *Demo, worker)
|
dp.Done = make(chan *Demo, worker)
|
||||||
@@ -129,9 +126,12 @@ func (dp *DemoParser) ParseDemo(demo *Demo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Demo) download() (io.Reader, error) {
|
func (d *Demo) download() (io.Reader, error) {
|
||||||
log.Debugf("[DP] Downloading replay for %d", d.MatchId)
|
log.Debugf("[DP] Downloading replay for %d", d.MatchID)
|
||||||
|
|
||||||
r, err := http.Get(d.Url)
|
r, err := http.Get(d.URL)
|
||||||
|
defer func(Body io.ReadCloser) {
|
||||||
|
_ = Body.Close()
|
||||||
|
}(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -142,26 +142,13 @@ func (d *Demo) download() (io.Reader, error) {
|
|||||||
return bzip2.NewReader(r.Body), nil
|
return bzip2.NewReader(r.Body), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dp *DemoParser) getDBPlayer(demo *Demo, demoPlayer *common.Player) (*ent.MatchPlayer, error) {
|
func (dp *DemoParser) MatchPlayerBySteamID(stats []*ent.MatchPlayer, steamID uint64) (*ent.MatchPlayer, error) {
|
||||||
tMatchPlayer, err := dp.db.MatchPlayer.Query().WithMatches(func(q *ent.MatchQuery) {
|
|
||||||
q.Where(match.ID(demo.MatchId))
|
|
||||||
}).WithPlayers(func(q *ent.PlayerQuery) {
|
|
||||||
q.Where(player.ID(demoPlayer.SteamID64))
|
|
||||||
}).Only(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tMatchPlayer, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dp *DemoParser) MatchPlayerBySteamID(stats []*ent.MatchPlayer, steamId uint64) (*ent.MatchPlayer, error) {
|
|
||||||
for _, tStats := range stats {
|
for _, tStats := range stats {
|
||||||
tPLayer, err := tStats.Edges.PlayersOrErr()
|
tPLayer, err := tStats.Edges.PlayersOrErr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to get stats from statList: %w", err)
|
return nil, fmt.Errorf("unable to get stats from statList: %w", err)
|
||||||
}
|
}
|
||||||
if tPLayer.ID == steamId {
|
if tPLayer.ID == steamID {
|
||||||
return tStats, nil
|
return tStats, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,19 +166,14 @@ func setMatchPlayerColor(matchPlayer *ent.MatchPlayer, demoPlayer *common.Player
|
|||||||
switch color {
|
switch color {
|
||||||
case common.Yellow:
|
case common.Yellow:
|
||||||
matchPlayer.Color = matchplayer.ColorYellow
|
matchPlayer.Color = matchplayer.ColorYellow
|
||||||
break
|
|
||||||
case common.Green:
|
case common.Green:
|
||||||
matchPlayer.Color = matchplayer.ColorGreen
|
matchPlayer.Color = matchplayer.ColorGreen
|
||||||
break
|
|
||||||
case common.Purple:
|
case common.Purple:
|
||||||
matchPlayer.Color = matchplayer.ColorPurple
|
matchPlayer.Color = matchplayer.ColorPurple
|
||||||
break
|
|
||||||
case common.Blue:
|
case common.Blue:
|
||||||
matchPlayer.Color = matchplayer.ColorBlue
|
matchPlayer.Color = matchplayer.ColorBlue
|
||||||
break
|
|
||||||
case common.Orange:
|
case common.Orange:
|
||||||
matchPlayer.Color = matchplayer.ColorOrange
|
matchPlayer.Color = matchplayer.ColorOrange
|
||||||
break
|
|
||||||
case common.Grey:
|
case common.Grey:
|
||||||
matchPlayer.Color = matchplayer.ColorGrey
|
matchPlayer.Color = matchplayer.ColorGrey
|
||||||
}
|
}
|
||||||
@@ -200,7 +182,7 @@ func setMatchPlayerColor(matchPlayer *ent.MatchPlayer, demoPlayer *common.Player
|
|||||||
func (dp *DemoParser) parseWorker() {
|
func (dp *DemoParser) parseWorker() {
|
||||||
workloop:
|
workloop:
|
||||||
for demo := range dp.demoQueue {
|
for demo := range dp.demoQueue {
|
||||||
if demo.MatchId == 0 {
|
if demo.MatchID == 0 {
|
||||||
log.Warningf("[DP] can't parse match %s: no matchid found", demo.ShareCode)
|
log.Warningf("[DP] can't parse match %s: no matchid found", demo.ShareCode)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
@@ -214,17 +196,17 @@ workloop:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tMatch, err := tx.Match.Get(context.Background(), demo.MatchId)
|
tMatch, err := tx.Match.Get(context.Background(), demo.MatchID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Unable to get match %d: %v", demo.MatchId, err)
|
log.Errorf("[DP] Unable to get match %d: %v", demo.MatchID, err)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if tMatch.DemoParsed {
|
if tMatch.DemoParsed {
|
||||||
err = utils.Rollback(tx, err)
|
_ = utils.Rollback(tx, err)
|
||||||
log.Infof("[DP] skipped already parsed %d", demo.MatchId)
|
log.Infof("[DP] skipped already parsed %d", demo.MatchID)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -233,17 +215,17 @@ workloop:
|
|||||||
fDemo, err := demo.download()
|
fDemo, err := demo.download()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, DemoNotFoundError{}) {
|
if errors.Is(err, DemoNotFoundError{}) {
|
||||||
err = utils.Rollback(tx, err)
|
_ = utils.Rollback(tx, err)
|
||||||
if tMatch.Date.Before(time.Now().UTC().AddDate(0, 0, -30)) {
|
if tMatch.Date.Before(time.Now().UTC().AddDate(0, 0, -30)) {
|
||||||
log.Infof("[DP] demo expired for match %d", tMatch.ID)
|
log.Infof("[DP] demo expired for match %d", tMatch.ID)
|
||||||
} else {
|
} else {
|
||||||
log.Infof("[DP] demo 404 not found for match %d. Retrying later.", demo.MatchId)
|
log.Infof("[DP] demo 404 not found for match %d. Retrying later.", demo.MatchID)
|
||||||
}
|
}
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Unable to download demo for %d: %v", demo.MatchId, err)
|
log.Errorf("[DP] Unable to download demo for %d: %v", demo.MatchID, err)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -253,7 +235,7 @@ workloop:
|
|||||||
tStats, err := tMatch.QueryStats().WithPlayers().All(context.Background())
|
tStats, err := tMatch.QueryStats().WithPlayers().All(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Failed to find players for match %d: %v", demo.MatchId, err)
|
log.Errorf("[DP] Failed to find players for match %d: %v", demo.MatchID, err)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -274,7 +256,7 @@ workloop:
|
|||||||
spays := make([]*Sprays, 0)
|
spays := make([]*Sprays, 0)
|
||||||
|
|
||||||
cfg := demoinfocs.DefaultParserConfig
|
cfg := demoinfocs.DefaultParserConfig
|
||||||
if len(demo.DecryptionKey) == 16 {
|
if len(demo.DecryptionKey) == 16 { //nolint:gomnd
|
||||||
cfg.NetMessageDecryptionKey = demo.DecryptionKey
|
cfg.NetMessageDecryptionKey = demo.DecryptionKey
|
||||||
}
|
}
|
||||||
demoParser := demoinfocs.NewParserWithConfig(fDemo, cfg)
|
demoParser := demoinfocs.NewParserWithConfig(fDemo, cfg)
|
||||||
@@ -484,7 +466,7 @@ workloop:
|
|||||||
Exec(context.Background())
|
Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Unable to update match %d in database: %v", demo.MatchId, err)
|
log.Errorf("[DP] Unable to update match %d in database: %v", demo.MatchID, err)
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -522,7 +504,13 @@ workloop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, eqDmg := range eqMap[tMatchPlayer.PlayerStats] {
|
for _, eqDmg := range eqMap[tMatchPlayer.PlayerStats] {
|
||||||
err = tx.Weapon.Create().SetStat(nMatchPLayer).SetDmg(eqDmg.Dmg).SetVictim(eqDmg.To).SetHitGroup(eqDmg.HitGroup).SetEqType(eqDmg.Eq).Exec(context.Background())
|
err = tx.Weapon.Create().
|
||||||
|
SetStat(nMatchPLayer).
|
||||||
|
SetDmg(eqDmg.Dmg).
|
||||||
|
SetVictim(eqDmg.To).
|
||||||
|
SetHitGroup(eqDmg.HitGroup).
|
||||||
|
SetEqType(eqDmg.Eq).
|
||||||
|
Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Unable to create WeaponStat: %v", err)
|
log.Errorf("[DP] Unable to create WeaponStat: %v", err)
|
||||||
@@ -532,7 +520,13 @@ workloop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, eco := range ecoMap[tMatchPlayer.PlayerStats] {
|
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)).Exec(context.Background())
|
err := tx.RoundStats.Create().
|
||||||
|
SetMatchPlayer(nMatchPLayer).
|
||||||
|
SetRound(uint(eco.Round)).
|
||||||
|
SetBank(uint(eco.Bank)).
|
||||||
|
SetEquipment(uint(eco.EqV)).
|
||||||
|
SetSpent(uint(eco.Spent)).
|
||||||
|
Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Errorf("[DP] Unable to create RoundStat: %v", err)
|
log.Errorf("[DP] Unable to create RoundStat: %v", err)
|
||||||
@@ -554,7 +548,11 @@ workloop:
|
|||||||
continue workloop
|
continue workloop
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tx.Spray.Create().SetMatchPlayers(nMatchPLayer).SetWeapon(spray.Weapon).SetSpray(sprayBuf.Bytes()).Exec(context.Background())
|
err = tx.Spray.Create().
|
||||||
|
SetMatchPlayers(nMatchPLayer).
|
||||||
|
SetWeapon(spray.Weapon).
|
||||||
|
SetSpray(sprayBuf.Bytes()).
|
||||||
|
Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = utils.Rollback(tx, err)
|
err = utils.Rollback(tx, err)
|
||||||
log.Warningf("[DP] Failure adding spray to database: %v", err)
|
log.Warningf("[DP] Failure adding spray to database: %v", err)
|
||||||
@@ -567,7 +565,11 @@ workloop:
|
|||||||
|
|
||||||
var bulk []*ent.MessagesCreate
|
var bulk []*ent.MessagesCreate
|
||||||
for _, msg := range tMatchPlayer.Edges.Messages {
|
for _, msg := range tMatchPlayer.Edges.Messages {
|
||||||
bulk = append(bulk, tx.Messages.Create().SetMessage(msg.Message).SetAllChat(msg.AllChat).SetTick(msg.Tick).SetMatchPlayer(tMatchPlayer))
|
bulk = append(bulk, tx.Messages.Create().
|
||||||
|
SetMessage(msg.Message).
|
||||||
|
SetAllChat(msg.AllChat).
|
||||||
|
SetTick(msg.Tick).
|
||||||
|
SetMatchPlayer(tMatchPlayer))
|
||||||
}
|
}
|
||||||
if len(bulk) > 0 {
|
if len(bulk) > 0 {
|
||||||
err = tx.Messages.CreateBulk(bulk...).Exec(context.Background())
|
err = tx.Messages.CreateBulk(bulk...).Exec(context.Background())
|
||||||
@@ -587,11 +589,11 @@ workloop:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("[DP] parsed match %d (took %s/%s)", demo.MatchId, downloadTime, time.Since(startTime))
|
log.Infof("[DP] parsed match %d (took %s/%s)", demo.MatchID, downloadTime, time.Since(startTime))
|
||||||
|
|
||||||
err = demoParser.Close()
|
err = demoParser.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[DP] Unable close demo file for match %d: %v", demo.MatchId, err)
|
log.Errorf("[DP] Unable close demo file for match %d: %v", demo.MatchID, err)
|
||||||
}
|
}
|
||||||
dp.Done <- demo
|
dp.Done <- demo
|
||||||
}
|
}
|
||||||
|
@@ -10,9 +10,9 @@ import (
|
|||||||
|
|
||||||
//goland:noinspection SpellCheckingInspection
|
//goland:noinspection SpellCheckingInspection
|
||||||
var DICT = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789"
|
var DICT = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789"
|
||||||
var sharecodeRexEx = regexp.MustCompile("^CSGO(?:-?\\w{5}){5}$")
|
var sharecodeRexEx = regexp.MustCompile(`^CSGO(?:-?\w{5}){5}$`)
|
||||||
|
|
||||||
func DecodeSharecode(code string) (uint64, uint64, uint16, error) {
|
func DecodeSharecode(code string) (matchID, outcomeID uint64, tokenID uint16, err error) {
|
||||||
if !sharecodeRexEx.MatchString(code) {
|
if !sharecodeRexEx.MatchString(code) {
|
||||||
return 0, 0, 0, fmt.Errorf("not a CSGO sharecode: %s", code)
|
return 0, 0, 0, fmt.Errorf("not a CSGO sharecode: %s", code)
|
||||||
}
|
}
|
||||||
@@ -28,17 +28,17 @@ func DecodeSharecode(code string) (uint64, uint64, uint16, error) {
|
|||||||
bigInt.Add(bigInt, big.NewInt(int64(strings.Index(DICT, c))))
|
bigInt.Add(bigInt, big.NewInt(int64(strings.Index(DICT, c))))
|
||||||
}
|
}
|
||||||
|
|
||||||
if bigInt.BitLen() > 144 {
|
if bigInt.BitLen() > 144 { //nolint:gomnd
|
||||||
return 0, 0, 0, fmt.Errorf("invalid sharecode")
|
return 0, 0, 0, fmt.Errorf("invalid sharecode")
|
||||||
}
|
}
|
||||||
bytes := make([]byte, 18)
|
bytes := make([]byte, 18) //nolint:gomnd
|
||||||
bigInt.FillBytes(bytes)
|
bigInt.FillBytes(bytes)
|
||||||
|
|
||||||
matchId := binary.LittleEndian.Uint64(bytes[0:8])
|
matchID = binary.LittleEndian.Uint64(bytes[0:8])
|
||||||
outcomeId := binary.LittleEndian.Uint64(bytes[8:16])
|
outcomeID = binary.LittleEndian.Uint64(bytes[8:16])
|
||||||
tokenId := binary.LittleEndian.Uint16(bytes[16:18])
|
tokenID = binary.LittleEndian.Uint16(bytes[16:18])
|
||||||
|
|
||||||
return matchId, outcomeId, tokenId, nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReverseString(numbers []string) []string {
|
func ReverseString(numbers []string) []string {
|
||||||
|
4
go.mod
4
go.mod
@@ -59,13 +59,13 @@ require (
|
|||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||||
github.com/vmihailenco/go-tinylfu v0.2.2 // indirect
|
github.com/vmihailenco/go-tinylfu v0.2.2 // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.12.1 // indirect
|
github.com/zclconf/go-cty v1.12.1 // indirect
|
||||||
golang.org/x/crypto v0.2.0 // indirect
|
golang.org/x/crypto v0.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20221114191408-850992195362 // indirect
|
golang.org/x/exp v0.0.0-20221114191408-850992195362 // indirect
|
||||||
golang.org/x/mod v0.7.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/net v0.2.0 // indirect
|
golang.org/x/net v0.2.0 // indirect
|
||||||
|
14
go.sum
14
go.sum
@@ -360,8 +360,8 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw
|
|||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
@@ -430,8 +430,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
@@ -439,8 +440,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||||
@@ -499,8 +501,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||||
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||||
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
|
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
|
||||||
|
28
main.go
28
main.go
@@ -138,7 +138,7 @@ func housekeeping() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range tMatches {
|
for _, m := range tMatches {
|
||||||
demo := &csgo.Demo{MatchId: m.ID, ShareCode: m.ShareCode}
|
demo := &csgo.Demo{MatchID: m.ID, ShareCode: m.ShareCode}
|
||||||
if demoLoader.IsLoading(demo) {
|
if demoLoader.IsLoading(demo) {
|
||||||
log.Infof("[HK] Skipping %s: parsing in progress", m.ShareCode)
|
log.Infof("[HK] Skipping %s: parsing in progress", m.ShareCode)
|
||||||
continue
|
continue
|
||||||
@@ -216,24 +216,25 @@ func housekeeping() {
|
|||||||
for _, tPlayer := range tPlayerNeedShareCodeUpdate {
|
for _, tPlayer := range tPlayerNeedShareCodeUpdate {
|
||||||
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, conf.Steam.APIKey, rL)
|
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, conf.Steam.APIKey, rL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utils.AuthcodeUnauthorizedError) {
|
switch {
|
||||||
|
case errors.Is(err, utils.AuthcodeUnauthorizedError):
|
||||||
log.Infof("[HK] authCode for player %d is no longer valid", tPlayer.ID)
|
log.Infof("[HK] authCode for player %d is no longer valid", tPlayer.ID)
|
||||||
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
|
log.Errorf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else if errors.Is(err, utils.SharecodeNoMatchError) {
|
case errors.Is(err, utils.SharecodeNoMatchError):
|
||||||
log.Warningf("[HK] last shareCode for player %d does not match player", tPlayer.ID)
|
log.Warningf("[HK] last shareCode for player %d does not match player", tPlayer.ID)
|
||||||
continue
|
continue
|
||||||
} else if errors.Is(err, utils.NoMatchError) {
|
case errors.Is(err, utils.NoMatchError):
|
||||||
log.Infof("[HK] tracked player %d with no matches found, untracked", tPlayer.ID)
|
log.Infof("[HK] tracked player %d with no matches found, untracked", tPlayer.ID)
|
||||||
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
|
log.Errorf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else {
|
default:
|
||||||
log.Errorf("[HK] Error while requesting sharecodes for %d: %v", tPlayer.ID, err)
|
log.Errorf("[HK] Error while requesting sharecodes for %d: %v", tPlayer.ID, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -533,15 +534,16 @@ func postPlayerTrack(c *gin.Context) {
|
|||||||
|
|
||||||
_, err = utils.IsAuthCodeValid(tPlayer, conf.Steam.APIKey, shareCode, authCode, rL)
|
_, err = utils.IsAuthCodeValid(tPlayer, conf.Steam.APIKey, shareCode, authCode, rL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utils.AuthcodeUnauthorizedError) {
|
switch {
|
||||||
|
case errors.Is(err, utils.AuthcodeUnauthorizedError):
|
||||||
log.Infof("[PPT] authCode provided for player %s is invalid: %v", id, err)
|
log.Infof("[PPT] authCode provided for player %s is invalid: %v", id, err)
|
||||||
c.Status(http.StatusUnauthorized)
|
c.Status(http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
} else if errors.Is(err, utils.SharecodeNoMatchError) {
|
case errors.Is(err, utils.SharecodeNoMatchError):
|
||||||
log.Infof("[PPT] shareCode provided for player %s (%s) is invalid: %v", id, shareCode, err)
|
log.Infof("[PPT] shareCode provided for player %s (%s) is invalid: %v", id, shareCode, err)
|
||||||
c.Status(http.StatusPreconditionFailed)
|
c.Status(http.StatusPreconditionFailed)
|
||||||
return
|
return
|
||||||
} else {
|
default:
|
||||||
log.Infof("[PPT] problem with request: %v", err)
|
log.Infof("[PPT] problem with request: %v", err)
|
||||||
c.Status(http.StatusServiceUnavailable)
|
c.Status(http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
@@ -1093,7 +1095,7 @@ func main() {
|
|||||||
migrate.WithDropIndex(true),
|
migrate.WithDropIndex(true),
|
||||||
migrate.WithDropColumn(true),
|
migrate.WithDropColumn(true),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.Fatalf("Automigrate failed: %v", err)
|
log.Panicf("Automigrate failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rdb = redis.NewClient(&redis.Options{
|
rdb = redis.NewClient(&redis.Options{
|
||||||
@@ -1116,16 +1118,16 @@ func main() {
|
|||||||
AuthCode: conf.Steam.AuthCode,
|
AuthCode: conf.Steam.AuthCode,
|
||||||
Sentry: conf.Steam.Sentry,
|
Sentry: conf.Steam.Sentry,
|
||||||
LoginKey: conf.Steam.LoginKey,
|
LoginKey: conf.Steam.LoginKey,
|
||||||
Db: db,
|
DB: db,
|
||||||
Worker: conf.Parser.Worker,
|
Worker: conf.Parser.Worker,
|
||||||
ApiKey: conf.Steam.APIKey,
|
APIKey: conf.Steam.APIKey,
|
||||||
RateLimit: rL,
|
RateLimit: rL,
|
||||||
Cache: rdc,
|
Cache: rdc,
|
||||||
SprayTimeout: conf.Csgowtfd.SprayTimeout,
|
SprayTimeout: conf.Csgowtfd.SprayTimeout,
|
||||||
RetryTimeout: conf.Steam.MaxRetryWait,
|
RetryTimeout: conf.Steam.MaxRetryWait,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error setting up DemoLoader: %v", err)
|
log.Panicf("Error setting up DemoLoader: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// start housekeeper
|
// start housekeeper
|
||||||
@@ -1174,7 +1176,7 @@ func main() {
|
|||||||
sL, err := net.Listen("unix", l.Socket)
|
sL, err := net.Listen("unix", l.Socket)
|
||||||
log.Infof("Listening on %s", l.Socket)
|
log.Infof("Listening on %s", l.Socket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failure listing on socket %s: %v", l.Socket, err)
|
log.Panicf("Failure listing on socket %s: %v", l.Socket, err)
|
||||||
}
|
}
|
||||||
sockets = append(sockets, sL)
|
sockets = append(sockets, sL)
|
||||||
go func() {
|
go func() {
|
||||||
|
@@ -690,11 +690,12 @@ func TranslateWithDeepL(text string, language string, baseURL string, apiKey str
|
|||||||
v.Set("text", text)
|
v.Set("text", text)
|
||||||
v.Set("target_lang", language)
|
v.Set("target_lang", language)
|
||||||
dlResp, err := c.PostForm("https://"+baseURL+"/v2/translate", v)
|
dlResp, err := c.PostForm("https://"+baseURL+"/v2/translate", v)
|
||||||
if err != nil {
|
switch {
|
||||||
|
case err != nil:
|
||||||
return "", "", fmt.Errorf("deepl response: %w", err)
|
return "", "", fmt.Errorf("deepl response: %w", err)
|
||||||
} else if dlResp.StatusCode != http.StatusOK {
|
case dlResp.StatusCode != http.StatusOK:
|
||||||
return "", "", fmt.Errorf("deepl response %d", dlResp.StatusCode)
|
return "", "", fmt.Errorf("deepl response %d", dlResp.StatusCode)
|
||||||
} else {
|
default:
|
||||||
respBytes, err := io.ReadAll(dlResp.Body)
|
respBytes, err := io.ReadAll(dlResp.Body)
|
||||||
defer func(Body io.ReadCloser) {
|
defer func(Body io.ReadCloser) {
|
||||||
_ = Body.Close()
|
_ = Body.Close()
|
||||||
@@ -707,7 +708,6 @@ func TranslateWithDeepL(text string, language string, baseURL string, apiKey str
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("error decoding json from deepl: %w", err)
|
return "", "", fmt.Errorf("error decoding json from deepl: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return dlRespJSON.Translations[0].Text, strings.ToLower(dlRespJSON.Translations[0].DetectedSourceLanguage), nil
|
return dlRespJSON.Translations[0].Text, strings.ToLower(dlRespJSON.Translations[0].DetectedSourceLanguage), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user