added rounds endpoint
This commit is contained in:
102
main.go
102
main.go
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
|
"github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/common"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/wercker/journalhook"
|
"github.com/wercker/journalhook"
|
||||||
@@ -409,6 +410,58 @@ func getMatchParse(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusAccepted)
|
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) {
|
func getMatchWeapons(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)
|
||||||
id := mux.Vars(r)["id"]
|
id := mux.Vars(r)["id"]
|
||||||
@@ -425,8 +478,6 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mResponse := make([]*utils.WeaponResponse, 0)
|
|
||||||
|
|
||||||
db.Lock.RLock()
|
db.Lock.RLock()
|
||||||
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
|
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
|
||||||
db.Lock.RUnlock()
|
db.Lock.RUnlock()
|
||||||
@@ -436,28 +487,39 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
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 {
|
for _, stat := range tStats {
|
||||||
db.Lock.RLock()
|
db.Lock.RLock()
|
||||||
mWs, err := stat.QueryWeaponStats().All(context.Background())
|
mWs, err := stat.QueryWeaponStats().All(context.Background())
|
||||||
db.Lock.RUnlock()
|
db.Lock.RUnlock()
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
mWr := &utils.WeaponResponse{
|
mWr := map[string]map[string][][]int{}
|
||||||
Player: &utils.PlayerResponse{SteamID64: stat.PlayerStats},
|
playerId := strconv.FormatUint(stat.PlayerStats, 10)
|
||||||
}
|
|
||||||
|
|
||||||
for _, wr := range mWs {
|
for _, wr := range mWs {
|
||||||
mWr.Eq = append(mWr.Eq, &utils.EqResponse{
|
if _, exists := mWr[strconv.FormatUint(stat.PlayerStats, 10)]; !exists {
|
||||||
Victim: wr.Victim,
|
mWr[playerId] = map[string][][]int{}
|
||||||
Type: wr.EqType,
|
}
|
||||||
HitGroup: wr.HitGroup,
|
|
||||||
Dmg: wr.Dmg,
|
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 = append(mResponse, mWr)
|
mResponse.Stats = append(mResponse.Stats, mWr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utils.SendJSON(mResponse, w)
|
err = utils.SendJSON(mResponse, w)
|
||||||
@@ -478,7 +540,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
matchId, err := strconv.ParseUint(id, 10, 64)
|
matchId, err := strconv.ParseUint(id, 10, 64)
|
||||||
if err != nil {
|
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)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
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/<id> GET player details (last 10 matches)
|
||||||
/player/trackme POST id, authcode, [sharecode]
|
/player/<id>/track POST Track player FORM_DATA: authcode, [sharecode]
|
||||||
/match/<id> GET CSGO-GC response + internal data if parsed <- may be big (ALL RELEVANT DATA)
|
/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
|
/match/parse/<sharecode> GET parses sharecode provided
|
||||||
*/
|
*/
|
||||||
func main() {
|
func main() {
|
||||||
@@ -685,7 +750,7 @@ func main() {
|
|||||||
// start housekeeper
|
// start housekeeper
|
||||||
go housekeeping()
|
go housekeeping()
|
||||||
|
|
||||||
// Define routes
|
// 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/{id}/track", postPlayerTrack).Methods(http.MethodPost, 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/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)
|
||||||
|
router.HandleFunc("/match/{id:[0-9]{19}}/rounds", getMatchRounds).Methods(http.MethodGet, http.MethodOptions)
|
||||||
router.Use(mux.CORSMethodMiddleware(router))
|
router.Use(mux.CORSMethodMiddleware(router))
|
||||||
loggedRouter := handlers.LoggingHandler(os.Stdout, router)
|
loggedRouter := handlers.LoggingHandler(os.Stdout, router)
|
||||||
proxyRouter := handlers.ProxyHeaders(loggedRouter)
|
proxyRouter := handlers.ProxyHeaders(loggedRouter)
|
||||||
|
@@ -153,26 +153,19 @@ type StatsResponse struct {
|
|||||||
|
|
||||||
type PlayerResponse struct {
|
type PlayerResponse struct {
|
||||||
SteamID64 uint64 `json:"steamid64,string"`
|
SteamID64 uint64 `json:"steamid64,string"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name,omitempty"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar,omitempty"`
|
||||||
VAC bool `json:"vac"`
|
VAC bool `json:"vac"`
|
||||||
VACDate *time.Time `json:"vac_date,omitempty"`
|
VACDate *time.Time `json:"vac_date,omitempty"`
|
||||||
Tracked bool `json:"tracked"`
|
Tracked bool `json:"tracked"`
|
||||||
VanityURL string `json:"vanity_url,omitempty"`
|
VanityURL string `json:"vanity_url,omitempty"`
|
||||||
MatchStats MatchStats `json:"match_stats,omitempty"`
|
MatchStats *MatchStats `json:"match_stats,omitempty"`
|
||||||
Matches []*MatchResponse `json:"matches,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 {
|
type WeaponResponse struct {
|
||||||
Player *PlayerResponse `json:"player"`
|
Player *PlayerResponse `json:"player"`
|
||||||
Eq []*EqResponse `json:"eq,omitempty"`
|
Eq map[string][][]int `json:"eq,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MatchResponse struct {
|
type MatchResponse struct {
|
||||||
|
Reference in New Issue
Block a user