Skip to content

Доманин Д.А. 3/147 #16

Description

@FallingAngel0101

package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"sync"
"time"

"github.com/gorilla/mux"

)

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))

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions