added rounds endpoint

This commit is contained in:
2021-10-17 17:44:57 +02:00
parent 4c23d49a22
commit f8579f9768
2 changed files with 89 additions and 30 deletions

102
main.go
View File

@@ -17,6 +17,7 @@ import (
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/common"
_ "github.com/mattn/go-sqlite3"
log "github.com/sirupsen/logrus"
"github.com/wercker/journalhook"
@@ -409,6 +410,58 @@ func getMatchParse(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusAccepted)
}
func getMatchRounds(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", conf.Httpd.CORSAllowDomains)
id := mux.Vars(r)["id"]
if id == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
matchId, err := strconv.ParseUint(id, 10, 64)
if err != nil {
log.Infof("[GMR] Error parsing matchID %s: %v", id, err)
w.WriteHeader(http.StatusBadRequest)
return
}
db.Lock.RLock()
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Infof("[GMR] match %d not found: %+v", matchId, err)
w.WriteHeader(http.StatusNotFound)
return
}
resp := map[uint]map[string][]uint{}
for _, stat := range tStats {
db.Lock.RLock()
tRoundStats, err := stat.QueryRoundStats().All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Warningf("[GMR] Unable to get RoundStats for player %d: %v", stat.PlayerStats, err)
continue
}
for _, rStat := range tRoundStats {
if _, ok := resp[rStat.Round]; !ok {
resp[rStat.Round] = map[string][]uint{}
}
resp[rStat.Round][strconv.FormatUint(stat.PlayerStats, 10)] = []uint{rStat.Equipment, rStat.Spent, rStat.Bank}
}
}
err = utils.SendJSON(resp, w)
if err != nil {
log.Errorf("[GMR] JSON: %+v", err)
w.WriteHeader(http.StatusInternalServerError)
}
}
func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", conf.Httpd.CORSAllowDomains)
id := mux.Vars(r)["id"]
@@ -425,8 +478,6 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
return
}
mResponse := make([]*utils.WeaponResponse, 0)
db.Lock.RLock()
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
db.Lock.RUnlock()
@@ -436,28 +487,39 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
return
}
mResponse := struct {
EquipmentMap map[int]string `json:"equipment_map,omitempty"`
Stats []map[string]map[string][][]int `json:"stats,omitempty"`
}{
EquipmentMap: map[int]string{},
Stats: []map[string]map[string][][]int{},
}
for _, stat := range tStats {
db.Lock.RLock()
mWs, err := stat.QueryWeaponStats().All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Warningf("[GMW] Unbale to get WeaponStats for player %d: %v", stat.PlayerStats, err)
log.Warningf("[GMW] Unable to get WeaponStats for player %d: %v", stat.PlayerStats, err)
continue
}
mWr := &utils.WeaponResponse{
Player: &utils.PlayerResponse{SteamID64: stat.PlayerStats},
}
mWr := map[string]map[string][][]int{}
playerId := strconv.FormatUint(stat.PlayerStats, 10)
for _, wr := range mWs {
mWr.Eq = append(mWr.Eq, &utils.EqResponse{
Victim: wr.Victim,
Type: wr.EqType,
HitGroup: wr.HitGroup,
Dmg: wr.Dmg,
})
if _, exists := mWr[strconv.FormatUint(stat.PlayerStats, 10)]; !exists {
mWr[playerId] = map[string][][]int{}
}
mResponse = append(mResponse, mWr)
victim := strconv.FormatUint(wr.Victim, 10)
mWr[playerId][victim] = append(mWr[playerId][victim], []int{wr.EqType, wr.HitGroup, int(wr.Dmg)})
if _, exist := mResponse.EquipmentMap[wr.EqType]; !exist {
mResponse.EquipmentMap[wr.EqType] = common.EquipmentType(wr.EqType).String()
}
}
mResponse.Stats = append(mResponse.Stats, mWr)
}
err = utils.SendJSON(mResponse, w)
@@ -478,7 +540,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
matchId, err := strconv.ParseUint(id, 10, 64)
if err != nil {
log.Infof("[GM] Unbale to parse matchID %s: %v", id, err)
log.Infof("[GM] Unable to parse matchID %s: %v", id, err)
w.WriteHeader(http.StatusBadRequest)
return
}
@@ -601,9 +663,12 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
}
/*
/player/<id> GET player internal or if not found: steamAPI data + overall stats
/player/trackme POST id, authcode, [sharecode]
/match/<id> GET CSGO-GC response + internal data if parsed <- may be big (ALL RELEVANT DATA)
/player/<id> GET player details (last 10 matches)
/player/<id>/track POST Track player FORM_DATA: authcode, [sharecode]
/player/<id>/track DELETE Stop tracking player FORM_DATA: authcode
/match/<id> GET details for match <id>
/match/<id>/weapons GET weapon-stats for match <id>
/match/<id>/rounds GET round-stats for match <id>
/match/parse/<sharecode> GET parses sharecode provided
*/
func main() {
@@ -685,7 +750,7 @@ func main() {
// start housekeeper
go housekeeping()
// Define routes
// routes
router = mux.NewRouter().StrictSlash(true)
router.HandleFunc("/player/{id}", getPlayer).Methods(http.MethodGet, http.MethodOptions)
router.HandleFunc("/player/{id}/track", postPlayerTrack).Methods(http.MethodPost, http.MethodOptions)
@@ -693,6 +758,7 @@ func main() {
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}}/weapons", getMatchWeapons).Methods(http.MethodGet, http.MethodOptions)
router.HandleFunc("/match/{id:[0-9]{19}}/rounds", getMatchRounds).Methods(http.MethodGet, http.MethodOptions)
router.Use(mux.CORSMethodMiddleware(router))
loggedRouter := handlers.LoggingHandler(os.Stdout, router)
proxyRouter := handlers.ProxyHeaders(loggedRouter)

View File

@@ -153,26 +153,19 @@ type StatsResponse struct {
type PlayerResponse struct {
SteamID64 uint64 `json:"steamid64,string"`
Name string `json:"name"`
Avatar string `json:"avatar"`
Name string `json:"name,omitempty"`
Avatar string `json:"avatar,omitempty"`
VAC bool `json:"vac"`
VACDate *time.Time `json:"vac_date,omitempty"`
Tracked bool `json:"tracked"`
VanityURL string `json:"vanity_url,omitempty"`
MatchStats MatchStats `json:"match_stats,omitempty"`
MatchStats *MatchStats `json:"match_stats,omitempty"`
Matches []*MatchResponse `json:"matches,omitempty"`
}
type EqResponse struct {
Victim uint64 `json:"victim"`
Type int `json:"type"`
HitGroup int `json:"hit_group"`
Dmg uint `json:"dmg"`
}
type WeaponResponse struct {
Player *PlayerResponse `json:"player"`
Eq []*EqResponse `json:"eq,omitempty"`
Eq map[string][][]int `json:"eq,omitempty"`
}
type MatchResponse struct {