170 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package handlers
 | |
| 
 | |
| import (
 | |
| 	"gralias/broker"
 | |
| 	"gralias/config"
 | |
| 	"gralias/models"
 | |
| 	"gralias/repos"
 | |
| 	"html/template"
 | |
| 	"log/slog"
 | |
| 	"net/http"
 | |
| 	"os"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	log *slog.Logger
 | |
| 	cfg *config.Config
 | |
| 	// memcache cache.Cache
 | |
| 	Notifier *broker.Broker
 | |
| 	repo     repos.AllRepos
 | |
| )
 | |
| 
 | |
| func init() {
 | |
| 	log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
 | |
| 		Level:     slog.LevelDebug,
 | |
| 		AddSource: true,
 | |
| 	}))
 | |
| 	cfg = config.LoadConfigOrDefault("")
 | |
| 	Notifier = broker.Notifier
 | |
| 	// repo = repos.NewRepoProvider("sqlite3://../gralias.db")
 | |
| 	repo = repos.RP
 | |
| 	recoverBots()
 | |
| }
 | |
| 
 | |
| func HandlePing(w http.ResponseWriter, r *http.Request) {
 | |
| 	if _, err := w.Write([]byte("pong")); err != nil {
 | |
| 		log.Error("failed to write ping response", "error", err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func HandleHome(w http.ResponseWriter, r *http.Request) {
 | |
| 	tmpl, err := template.ParseGlob("components/*.html")
 | |
| 	if err != nil {
 | |
| 		abortWithError(w, err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 	fi, err := getFullInfoByCtx(r.Context())
 | |
| 	if err != nil {
 | |
| 		log.Error("failed to fetch fi", "error", err)
 | |
| 	}
 | |
| 	// there must be a better way
 | |
| 	if fi != nil && fi.Room != nil && fi.Room.ID != "" && fi.State != nil {
 | |
| 		fi.Room.UpdateCounter()
 | |
| 		if fi.State.Role == "mime" {
 | |
| 			fi.Room.MimeView() // there must be a better way
 | |
| 		} else {
 | |
| 			fi.Room.GuesserView()
 | |
| 		}
 | |
| 	}
 | |
| 	if fi != nil && fi.Room == nil {
 | |
| 		rooms, err := repo.RoomList(r.Context())
 | |
| 		if err != nil {
 | |
| 			log.Error("failed to list rooms;", "error", err)
 | |
| 		}
 | |
| 		fi.List = rooms
 | |
| 	}
 | |
| 	if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
 | |
| 		log.Error("failed to exec templ;", "error", err, "templ", "base")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func HandleExit(w http.ResponseWriter, r *http.Request) {
 | |
| 	tmpl, err := template.ParseGlob("components/*.html")
 | |
| 	if err != nil {
 | |
| 		abortWithError(w, err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 	fi, err := getFullInfoByCtx(r.Context())
 | |
| 	if err != nil || fi == nil {
 | |
| 		log.Error("failed to fetch fi", "error", err)
 | |
| 		http.Redirect(w, r, "/", 302)
 | |
| 		return
 | |
| 	}
 | |
| 	if fi.Room.IsRunning {
 | |
| 		abortWithError(w, "cannot leave when game is running")
 | |
| 		return
 | |
| 	}
 | |
| 	// if creator leaves, remove all players from room and delete room
 | |
| 	if fi.Room.CreatorName == fi.State.Username {
 | |
| 		players, err := repo.PlayerListByRoom(r.Context(), fi.Room.ID)
 | |
| 		if err != nil {
 | |
| 			log.Error("failed to list players in room", "error", err)
 | |
| 			abortWithError(w, err.Error())
 | |
| 			return
 | |
| 		}
 | |
| 		for _, p := range players {
 | |
| 			if p.IsBot {
 | |
| 				if err := repo.PlayerDelete(r.Context(), p.Username); err != nil {
 | |
| 					log.Error("failed to delete bot", "error", err)
 | |
| 				}
 | |
| 				continue
 | |
| 			}
 | |
| 			if err := repo.PlayerExitRoom(r.Context(), p.Username); err != nil {
 | |
| 				log.Error("failed to exit room", "error", err)
 | |
| 			}
 | |
| 		}
 | |
| 		if err := repo.RoomDeleteByID(r.Context(), fi.Room.ID); err != nil {
 | |
| 			log.Error("failed to remove room", "error", err)
 | |
| 		}
 | |
| 		notify(models.NotifyRoomListUpdate, "")
 | |
| 	} else {
 | |
| 		// if regular player leaves, just exit room
 | |
| 		if err := repo.PlayerExitRoom(r.Context(), fi.State.Username); err != nil {
 | |
| 			log.Error("failed to exit room", "error", err)
 | |
| 			abortWithError(w, err.Error())
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 	fi.Room = nil
 | |
| 	fi.State.RoomID = nil
 | |
| 	fi.List, err = repo.RoomList(r.Context())
 | |
| 	if err != nil {
 | |
| 		abortWithError(w, err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 	if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
 | |
| 		log.Error("failed to exec templ;", "error", err, "templ", "base")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func HandleStats(w http.ResponseWriter, r *http.Request) {
 | |
| 	log.Debug("got stats call")
 | |
| 	tmpl, err := template.ParseGlob("components/*.html")
 | |
| 	if err != nil {
 | |
| 		abortWithError(w, err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 	stats, err := repo.GetAllPlayerStats(r.Context())
 | |
| 	if err != nil {
 | |
| 		log.Error("failed to get all player stats", "error", err)
 | |
| 		abortWithError(w, "failed to retrieve player stats")
 | |
| 		return
 | |
| 	}
 | |
| 	fi, err := getFullInfoByCtx(r.Context())
 | |
| 	if err != nil || fi == nil {
 | |
| 		log.Error("failed to fetch fi", "error", err)
 | |
| 		http.Redirect(w, r, "/", 302)
 | |
| 		return
 | |
| 	}
 | |
| 	// there must be a better way
 | |
| 	if fi != nil && fi.Room != nil && fi.Room.ID != "" && fi.State != nil {
 | |
| 		fi.Room.UpdateCounter()
 | |
| 		if fi.State.Role == "mime" {
 | |
| 			fi.Room.MimeView() // there must be a better way
 | |
| 		} else {
 | |
| 			fi.Room.GuesserView()
 | |
| 		}
 | |
| 	}
 | |
| 	if fi != nil && fi.Room == nil {
 | |
| 		rooms, err := repo.RoomList(r.Context())
 | |
| 		if err != nil {
 | |
| 			log.Error("failed to list rooms;", "error", err)
 | |
| 		}
 | |
| 		fi.List = rooms
 | |
| 	}
 | |
| 	fi.List = nil
 | |
| 	if err := tmpl.ExecuteTemplate(w, "stats", stats); err != nil {
 | |
| 		log.Error("failed to exec templ;", "error", err, "templ", "base")
 | |
| 	}
 | |
| }
 | 
