package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"sync"
"time"
)
type Player struct {
ID int json:"id"
Nickname string json:"nickname"
MMR int json:"mmr"
WinRate float64 json:"winrate"
Hero string json:"favorite_hero"
IsBooster bool json:"is_booster"
LastSeen time.Time json:"last_seen"
}
var (
players = map[int]*Player{
1: {ID: 1, Nickname: "Papich", MMR: 4500, WinRate: 50.1, Hero: "Pudge", IsBooster: false, LastSeen: time.Now()},
2: {ID: 2, Nickname: "Stray228", MMR: 8200, WinRate: 67.3, Hero: "Invoker", IsBooster: true, LastSeen: time.Now()},
3: {ID: 3, Nickname: "NS", MMR: 3200, WinRate: 44.7, Hero: "Crystal Maiden", IsBooster: false, LastSeen: time.Now()},
}
mu sync.Mutex
nextID = 4
)
func getPlayers(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
list := make([]Player, 0, len(players))
for _, p := range players {
list = append(list, *p)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(list)
}
func getPlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
mu.Lock()
p, ok := players[id]
mu.Unlock()
if !ok {
http.Error(w, "Игрок ушёл в AFK", http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(p)
}
func createPlayer(w http.ResponseWriter, r *http.Request) {
var p Player
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, "Кривой JSON, как твой Micro Skill", http.StatusBadRequest)
return
}
mu.Lock()
p.ID = nextID
nextID++
p.LastSeen = time.Now()
players[p.ID] = &p
mu.Unlock()
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(p)
}
func updatePlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
var update struct {
MMR *int `json:"mmr,omitempty"`
WinRate *float64 `json:"winrate,omitempty"`
Hero *string `json:"favorite_hero,omitempty"`
}
if err := json.NewDecoder(r.Body).Decode(&update); err != nil {
http.Error(w, "Невалидные данные", http.StatusBadRequest)
return
}
mu.Lock()
p, ok := players[id]
if !ok {
mu.Unlock()
http.Error(w, "Игрок покинул игру", http.StatusNotFound)
return
}
if update.MMR != nil {
p.MMR = *update.MMR
}
if update.WinRate != nil {
p.WinRate = *update.WinRate
}
if update.Hero != nil {
p.Hero = *update.Hero
}
p.LastSeen = time.Now()
mu.Unlock()
json.NewEncoder(w).Encode(p)
}
func deletePlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
mu.Lock()
delete(players, id)
mu.Unlock()
w.WriteHeader(http.StatusNoContent)
}
func getDashboard(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
total := len(players)
var mmrSum int
var winSum float64
boosters := 0
for _, p := range players {
mmrSum += p.MMR
winSum += p.WinRate
if p.IsBooster {
boosters++
}
}
avgMMR := 0
avgWin := 0.0
if total > 0 {
avgMMR = mmrSum / total
avgWin = winSum / float64(total)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"total_players": total,
"average_mmr": avgMMR,
"average_win": fmt.Sprintf("%.1f%%", avgWin),
"boosters": boosters,
})
}
func main() {
r := mux.NewRouter()
// REST API
r.HandleFunc("/api/players", getPlayers).Methods("GET")
r.HandleFunc("/api/players/{id}", getPlayer).Methods("GET")
r.HandleFunc("/api/players", createPlayer).Methods("POST")
r.HandleFunc("/api/players/{id}", updatePlayer).Methods("PUT")
r.HandleFunc("/api/players/{id}", deletePlayer).Methods("DELETE")
r.HandleFunc("/api/dashboard", getDashboard).Methods("GET")
log.Println("CСервер запущен на :6969")
log.Fatal(http.ListenAndServe(":6969", r))
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"sync"
"time"
)
type Player struct {
ID int
json:"id"Nickname string
json:"nickname"MMR int
json:"mmr"WinRate float64
json:"winrate"Hero string
json:"favorite_hero"IsBooster bool
json:"is_booster"LastSeen time.Time
json:"last_seen"}
var (
players = map[int]*Player{
1: {ID: 1, Nickname: "Papich", MMR: 4500, WinRate: 50.1, Hero: "Pudge", IsBooster: false, LastSeen: time.Now()},
2: {ID: 2, Nickname: "Stray228", MMR: 8200, WinRate: 67.3, Hero: "Invoker", IsBooster: true, LastSeen: time.Now()},
3: {ID: 3, Nickname: "NS", MMR: 3200, WinRate: 44.7, Hero: "Crystal Maiden", IsBooster: false, LastSeen: time.Now()},
}
mu sync.Mutex
nextID = 4
)
func getPlayers(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
}
func getPlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
mu.Lock()
p, ok := players[id]
mu.Unlock()
if !ok {
http.Error(w, "Игрок ушёл в AFK", http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(p)
}
func createPlayer(w http.ResponseWriter, r *http.Request) {
var p Player
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, "Кривой JSON, как твой Micro Skill", http.StatusBadRequest)
return
}
}
func updatePlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
}
func deletePlayer(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(mux.Vars(r)["id"])
mu.Lock()
delete(players, id)
mu.Unlock()
w.WriteHeader(http.StatusNoContent)
}
func getDashboard(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
}
func main() {
r := mux.NewRouter()
}