better sharecode api handling, renamed endpoint to /player/id/track
This commit is contained in:
101
main.go
101
main.go
@@ -90,8 +90,22 @@ func housekeeping() {
|
|||||||
for _, tPlayer := range tPlayerNeedShareCodeUpdate {
|
for _, tPlayer := range tPlayerNeedShareCodeUpdate {
|
||||||
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, db.Lock, conf.Steam.APIKey, rL)
|
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, db.Lock, conf.Steam.APIKey, rL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[HK] Error while request sharecodes: %v", err)
|
switch err.(type) {
|
||||||
continue
|
case utils.AuthcodeUnauthorizedError:
|
||||||
|
db.Lock.Lock()
|
||||||
|
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
||||||
|
db.Lock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
case utils.SharecodeNoMatchError:
|
||||||
|
log.Warningf("[HK] last shareCode for player %d does not match player", tPlayer.ID)
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
log.Errorf("[HK] Error while request sharecodes: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, code := range shareCodes {
|
for _, code := range shareCodes {
|
||||||
@@ -256,11 +270,62 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func postPlayerTrackMe(w http.ResponseWriter, r *http.Request) {
|
func deletePlayerTrack(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Access-Control-Allow-Origin", conf.Httpd.CORSAllowDomains)
|
w.Header().Set("Access-Control-Allow-Origin", conf.Httpd.CORSAllowDomains)
|
||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Infof("[PPTM] Unable to parse form data: %v", err)
|
log.Infof("[DPT] Unable to parse form data: %v", err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
id := r.Form.Get("id")
|
||||||
|
authCode := r.Form.Get("authcode")
|
||||||
|
|
||||||
|
if id == "" || authCode == "" || !utils.AuthCodeRegEx.MatchString(authCode) {
|
||||||
|
log.Infof("[PPTM] invalid arguments: %+v, %+v", id, authCode)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tPlayer, err := utils.GetPlayer(db, id, conf.Steam.APIKey, rL)
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("[PPT] player not found: %+v", err)
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = utils.IsAuthCodeValid(tPlayer, db.Lock, conf.Steam.APIKey, "", authCode, rL)
|
||||||
|
if err != nil {
|
||||||
|
switch e := err.(type) {
|
||||||
|
case utils.AuthcodeUnauthorizedError:
|
||||||
|
log.Infof("[DPT] authCode provided for player %s is invalid: %v", id, e)
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
log.Infof("[DPT] Temporary Steam-API problem: %v", e)
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Lock.Lock()
|
||||||
|
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
|
||||||
|
db.Lock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("[PPT] update player failed: %+v", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func postPlayerTrack(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", conf.Httpd.CORSAllowDomains)
|
||||||
|
err := r.ParseForm()
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("[PPT] Unable to parse form data: %v", err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -270,30 +335,41 @@ func postPlayerTrackMe(w http.ResponseWriter, r *http.Request) {
|
|||||||
shareCode := r.Form.Get("sharecode")
|
shareCode := r.Form.Get("sharecode")
|
||||||
|
|
||||||
if id == "" || authCode == "" || !utils.AuthCodeRegEx.MatchString(authCode) {
|
if id == "" || authCode == "" || !utils.AuthCodeRegEx.MatchString(authCode) {
|
||||||
log.Infof("[PPTM] invalid arguments: %+v, %+v, %+v", id, authCode, shareCode)
|
log.Infof("[PPT] invalid arguments: %+v, %+v, %+v", id, authCode, shareCode)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tPlayer, err := utils.GetPlayer(db, id, conf.Steam.APIKey, rL)
|
tPlayer, err := utils.GetPlayer(db, id, conf.Steam.APIKey, rL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Infof("[PPTM] player not found: %+v", err)
|
log.Infof("[PPT] player not found: %+v", err)
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = utils.IsAuthCodeValid(tPlayer, db.Lock, conf.Steam.APIKey, shareCode, authCode, rL)
|
_, err = utils.IsAuthCodeValid(tPlayer, db.Lock, conf.Steam.APIKey, shareCode, authCode, rL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Infof("[PPTM] authCode provided for player %s is invalid: %v", id, err)
|
switch e := err.(type) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
case utils.AuthcodeUnauthorizedError:
|
||||||
return
|
log.Infof("[PPT] authCode provided for player %s is invalid: %v", id, e)
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
case utils.SharecodeNoMatchError:
|
||||||
|
log.Infof("[PPT] shareCode provided for player %s is invalid: %v", id, e)
|
||||||
|
w.WriteHeader(http.StatusPreconditionFailed)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
log.Infof("[PPT] Temporary Steam-API problem: %v", e)
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Lock.Lock()
|
db.Lock.Lock()
|
||||||
err = tPlayer.Update().SetAuthCode(authCode).Exec(context.Background())
|
err = tPlayer.Update().SetAuthCode(authCode).Exec(context.Background())
|
||||||
db.Lock.Unlock()
|
db.Lock.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("[PPTM] update player failed: %+v", err)
|
log.Warningf("[PPT] update player failed: %+v", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -301,7 +377,7 @@ func postPlayerTrackMe(w http.ResponseWriter, r *http.Request) {
|
|||||||
if shareCode != "" && utils.ShareCodeRegEx.MatchString(shareCode) {
|
if shareCode != "" && utils.ShareCodeRegEx.MatchString(shareCode) {
|
||||||
err := demoLoader.LoadDemo(&csgo.Demo{ShareCode: shareCode})
|
err := demoLoader.LoadDemo(&csgo.Demo{ShareCode: shareCode})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("[PPTM] unable to queue match: %v", err)
|
log.Warningf("[PPT] unable to queue match: %v", err)
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -611,7 +687,8 @@ func main() {
|
|||||||
// Define routes
|
// Define routes
|
||||||
router = mux.NewRouter().StrictSlash(true)
|
router = mux.NewRouter().StrictSlash(true)
|
||||||
router.HandleFunc("/player/{id}", getPlayer).Methods(http.MethodGet, http.MethodOptions)
|
router.HandleFunc("/player/{id}", getPlayer).Methods(http.MethodGet, http.MethodOptions)
|
||||||
router.HandleFunc("/player/trackme", postPlayerTrackMe).Methods(http.MethodPost, http.MethodOptions)
|
router.HandleFunc("/player/{id}/track", postPlayerTrack).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
router.HandleFunc("/player/{id}/track", deletePlayerTrack).Methods(http.MethodOptions, http.MethodDelete)
|
||||||
router.HandleFunc("/match/parse/{sharecode}", getMatchParse).Methods(http.MethodGet, http.MethodOptions)
|
router.HandleFunc("/match/parse/{sharecode}", getMatchParse).Methods(http.MethodGet, http.MethodOptions)
|
||||||
router.HandleFunc("/match/{id:[0-9]{19}}", getMatch).Methods(http.MethodGet, http.MethodOptions)
|
router.HandleFunc("/match/{id:[0-9]{19}}", getMatch).Methods(http.MethodGet, http.MethodOptions)
|
||||||
router.HandleFunc("/match/{id:[0-9]{19}}/weapons", getMatchWeapons).Methods(http.MethodGet, http.MethodOptions)
|
router.HandleFunc("/match/{id:[0-9]{19}}/weapons", getMatchWeapons).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"csgowtfd/ent/stats"
|
"csgowtfd/ent/stats"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/an0nfunc/go-steamapi"
|
"github.com/an0nfunc/go-steamapi"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -187,6 +188,18 @@ type MatchResponse struct {
|
|||||||
Stats interface{} `json:"stats,omitempty"`
|
Stats interface{} `json:"stats,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
AuthcodeUnauthorizedError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
AuthcodeRateLimitError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
SharecodeNoMatchError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
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"
|
||||||
)
|
)
|
||||||
@@ -328,10 +341,19 @@ func getNextShareCode(lastCode string, apiKey string, authCode string, steamId u
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.StatusCode == 202 {
|
switch r.StatusCode {
|
||||||
|
case http.StatusAccepted:
|
||||||
return "n/a", nil
|
return "n/a", nil
|
||||||
} else if r.StatusCode != 200 {
|
case http.StatusTooManyRequests, http.StatusServiceUnavailable:
|
||||||
return "", fmt.Errorf("bad response from steam api (HTTP %d)", r.StatusCode)
|
return "", AuthcodeRateLimitError{errors.New("api temp. ratelimited")}
|
||||||
|
case http.StatusPreconditionFailed:
|
||||||
|
return "", SharecodeNoMatchError{errors.New("sharecode not from player history")}
|
||||||
|
case http.StatusForbidden:
|
||||||
|
return "", AuthcodeUnauthorizedError{errors.New("authcode unauthorized")}
|
||||||
|
case http.StatusOK:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return "", errors.New("temporary steamapi error")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func(Body io.ReadCloser) {
|
defer func(Body io.ReadCloser) {
|
||||||
|
Reference in New Issue
Block a user