improved base57 decode and tests

This commit is contained in:
2021-10-16 03:40:49 +02:00
parent 99ec0ad1bc
commit 867e85b007
4 changed files with 57 additions and 26 deletions

View File

@@ -115,7 +115,7 @@ func (d *DemoMatchLoader) getMatchDetails(sharecode string) (*protobuf.CMsgGCCSt
if err != nil {
return nil, err
}
err = d.requestDemoInfo(matchId, outcomeId, tokenId)
err = d.requestDemoInfo(matchId, outcomeId, uint32(tokenId))
if err != nil {
return nil, err
}

View File

@@ -1,7 +1,7 @@
package csgo
import (
"encoding/hex"
"encoding/binary"
"fmt"
"math/big"
"regexp"
@@ -12,13 +12,12 @@ import (
var DICT = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789"
var sharecodeRexEx = regexp.MustCompile("^CSGO(?:-?[\\w]{5}){5}$")
func DecodeSharecode(code string) (uint64, uint64, uint32, error) {
func DecodeSharecode(code string) (uint64, uint64, uint16, error) {
if !sharecodeRexEx.MatchString(code) {
return 0, 0, 0, fmt.Errorf("not a CSGO sharecode: %s", code)
}
cleanCode := strings.ReplaceAll(code, "CSGO", "")
cleanCode = strings.ReplaceAll(cleanCode, "-", "")
cleanCode := strings.ReplaceAll(strings.ReplaceAll(code, "CSGO", ""), "-", "")
chars := ReverseString(strings.Split(cleanCode, ""))
bigInt := new(big.Int)
@@ -29,24 +28,17 @@ func DecodeSharecode(code string) (uint64, uint64, uint32, error) {
bigInt.Add(bigInt, big.NewInt(int64(strings.Index(DICT, c))))
}
if bigInt.BitLen() > 144 {
return 0, 0, 0, fmt.Errorf("invalid sharecode")
}
bytes := make([]byte, 18)
bigInt.FillBytes(bytes)
matchId := new(big.Int)
matchId.SetString(hex.EncodeToString(Reverse(bytes[0:8])), 16)
outcomeId := new(big.Int)
outcomeId.SetString(hex.EncodeToString(Reverse(bytes[8:16])), 16)
tokenId := new(big.Int)
tokenId.SetString(hex.EncodeToString(Reverse(bytes[16:18])), 16)
matchId := binary.LittleEndian.Uint64(bytes[0:8])
outcomeId := binary.LittleEndian.Uint64(bytes[8:16])
tokenId := binary.LittleEndian.Uint16(bytes[16:18])
return matchId.Uint64(), outcomeId.Uint64(), uint32(tokenId.Uint64()), nil
}
func Reverse(numbers []byte) []byte {
for i, j := 0, len(numbers)-1; i < j; i, j = i+1, j-1 {
numbers[i], numbers[j] = numbers[j], numbers[i]
}
return numbers
return matchId, outcomeId, tokenId, nil
}
func ReverseString(numbers []string) []string {

View File

@@ -3,10 +3,10 @@ package csgo
import "testing"
//goland:noinspection SpellCheckingInspection
func TestSharecode(t *testing.T) {
func TestGoodSharecodes(t *testing.T) {
eMatchId := uint64(3505575050994516382)
eOutcomeId := uint64(3505581094013501947)
eTokenId := uint32(12909)
eTokenId := uint16(12909)
matchId, outcomeId, tokenId, err := DecodeSharecode("CSGO-P9k3F-eVL9n-LZLXN-DrBGF-VKD7K")
if err != nil {
@@ -27,3 +27,43 @@ func TestSharecode(t *testing.T) {
t.Fail()
}
}
func TestBadSharecodes(t *testing.T) {
matchId, outcomeId, tokenId, err := 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)
t.Fail()
}
if outcomeId != 0 {
t.Logf("outcomeID should be 0, is %d", outcomeId)
t.Fail()
}
if tokenId != 0 {
t.Logf("tokenID should be 0, is %d", tokenId)
t.Fail()
}
matchId, outcomeId, tokenId, err = 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)
t.Fail()
}
if outcomeId != 0 {
t.Logf("outcomeID should be 0, is %d", outcomeId)
t.Fail()
}
if tokenId != 0 {
t.Logf("tokenID should be 0, is %d", tokenId)
t.Fail()
}
}

View File

@@ -155,7 +155,7 @@ type PlayerResponse struct {
Name string `json:"name"`
Avatar string `json:"avatar"`
VAC bool `json:"vac"`
VACDate *time.Time `json:"vac_date,omitempty"`
VACDate *time.Time `json:"vac_date,omitempty"`
Tracked bool `json:"tracked"`
VanityURL string `json:"vanity_url,omitempty"`
MatchStats MatchStats `json:"match_stats,omitempty"`
@@ -188,11 +188,10 @@ type MatchResponse struct {
}
const (
steamID64Entry = "https://steamcommunity.com/profiles/%d?xml=1"
steamVanityURLEntry = "https://steamcommunity.com/id/%s?xml=1"
shareCodeURLEntry = "https://api.steampowered.com/ICSGOPlayers_730/GetNextMatchSharingCode/v1?key=%s&steamid=%d&steamidkey=%s&knowncode=%s"
shareCodeURLEntry = "https://api.steampowered.com/ICSGOPlayers_730/GetNextMatchSharingCode/v1?key=%s&steamid=%d&steamidkey=%s&knowncode=%s"
)
//goland:noinspection SpellCheckingInspection
var (
SteamId64RegEx = regexp.MustCompile(`^\d{17}$`)
ShareCodeRegEx = regexp.MustCompile(`^CSGO(?:-?[ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789]{5}){5}$`)
@@ -213,7 +212,7 @@ func SendJSON(data interface{}, w http.ResponseWriter) error {
return nil
}
func GetMatchStats(db *ent.Client, lock *sync.RWMutex, dbPlayer *ent.Player) (int, int, int, error) {
func GetMatchStats(dbPlayer *ent.Player, lock *sync.RWMutex) (int, int, int, error) {
var res []struct {
MatchResult int `json:"match_result"`
Count int `json:"count"`