improved base57 decode and tests
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
|
@@ -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"`
|
||||
|
Reference in New Issue
Block a user