Fix: buildable
This commit is contained in:
@ -2,14 +2,12 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gralias/broker"
|
"gralias/broker"
|
||||||
"gralias/llmapi"
|
"gralias/llmapi"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
"gralias/wordloader"
|
"gralias/wordloader"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) {
|
func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) {
|
||||||
@ -20,7 +18,7 @@ func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error)
|
|||||||
}
|
}
|
||||||
room := req.CreateRoom(creator)
|
room := req.CreateRoom(creator)
|
||||||
room.RoomLink = cfg.BaseURL + "/room-join?id=" + room.ID
|
room.RoomLink = cfg.BaseURL + "/room-join?id=" + room.ID
|
||||||
if err := repo.CreateRoom(ctx, room); err != nil {
|
if err := repo.RoomCreate(ctx, room); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return room, nil
|
return room, nil
|
||||||
@ -109,25 +107,24 @@ func notifyBotIfNeeded(room *models.Room) {
|
|||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func getAllNames() []string {
|
// func getAllNames() []string {
|
||||||
names := []string{}
|
// names := []string{}
|
||||||
// will not scale
|
// // will not scale
|
||||||
wholeMemStore := memcache.GetAll()
|
// session := &models.Session{}
|
||||||
session := &models.Session{}
|
// // filter by key size only sessions
|
||||||
// filter by key size only sessions
|
// for _, name := range wholeMemStore {
|
||||||
for k, v := range wholeMemStore {
|
// // xid is 20 in len
|
||||||
// xid is 20 in len
|
// if len(k) != 20 {
|
||||||
if len(k) != 20 {
|
// continue
|
||||||
continue
|
// }
|
||||||
}
|
// if err := json.Unmarshal(v, &session); err != nil {
|
||||||
if err := json.Unmarshal(v, &session); err != nil {
|
// log.Error("failed to unmarshal", "error", err)
|
||||||
log.Error("failed to unmarshal", "error", err)
|
// continue
|
||||||
continue
|
// }
|
||||||
}
|
// names = append(names, session.Username)
|
||||||
names = append(names, session.Username)
|
// }
|
||||||
}
|
// return names
|
||||||
return names
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
// can room exists without state? I think no
|
// can room exists without state? I think no
|
||||||
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
||||||
@ -142,7 +139,7 @@ func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
// room, err := getRoomByID(state.RoomID)
|
// room, err := getRoomByID(state.RoomID)
|
||||||
room, err := repo.GetRoomByID(ctx, state.RoomID)
|
room, err := repo.RoomGetByID(ctx, state.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("failed to find room despite knowing room_id;",
|
log.Warn("failed to find room despite knowing room_id;",
|
||||||
"room_id", state.RoomID)
|
"room_id", state.RoomID)
|
||||||
@ -158,7 +155,7 @@ func getPlayerByCtx(ctx context.Context) (*models.Player, error) {
|
|||||||
log.Debug("no username in ctx")
|
log.Debug("no username in ctx")
|
||||||
return &models.Player{}, errors.New("no username in ctx")
|
return &models.Player{}, errors.New("no username in ctx")
|
||||||
}
|
}
|
||||||
return repo.GetPlayerByName(username)
|
return repo.PlayerGetByName(username)
|
||||||
}
|
}
|
||||||
|
|
||||||
// // DEPRECATED
|
// // DEPRECATED
|
||||||
@ -249,41 +246,15 @@ func joinTeam(ctx context.Context, role, team string) (*models.FullInfo, error)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// get bots
|
// get bots
|
||||||
func listBots() map[string]map[string]string {
|
func listBots() []models.Player {
|
||||||
cacheMap := memcache.GetAll()
|
bots, err := repo.PlayerList(true)
|
||||||
resp := make(map[string]map[string]string)
|
if err != nil {
|
||||||
// no way to know if room is public until unmarshal -_-;
|
log.Error("failed to fetch bots from db", "error", err)
|
||||||
for key, value := range cacheMap {
|
|
||||||
if strings.HasPrefix(key, models.CacheBotPredix) {
|
|
||||||
botMap := make(map[string]string)
|
|
||||||
if err := json.Unmarshal(value, &botMap); err != nil {
|
|
||||||
log.Warn("failed to unmarshal bot", "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
resp[botMap["bot_name"]] = botMap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return resp
|
return bots
|
||||||
}
|
}
|
||||||
|
|
||||||
// get players
|
// get players
|
||||||
func listPlayers() map[string]map[string]string {
|
|
||||||
cacheMap := memcache.GetAll()
|
|
||||||
resp := make(map[string]map[string]string)
|
|
||||||
// no way to know if room is public until unmarshal -_-;
|
|
||||||
for key, value := range cacheMap {
|
|
||||||
if strings.HasPrefix(key, models.CacheStatePrefix) {
|
|
||||||
playerMap := make(map[string]string)
|
|
||||||
if err := json.Unmarshal(value, &playerMap); err != nil {
|
|
||||||
log.Warn("failed to unmarshal player", "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
resp[playerMap["Username"]] = playerMap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
|
|
||||||
func notify(event, msg string) {
|
func notify(event, msg string) {
|
||||||
Notifier.Notifier <- broker.NotificationEvent{
|
Notifier.Notifier <- broker.NotificationEvent{
|
||||||
EventName: event,
|
EventName: event,
|
||||||
@ -312,54 +283,54 @@ func loadCards(room *models.Room) {
|
|||||||
|
|
||||||
func recoverBots() {
|
func recoverBots() {
|
||||||
bots := listBots()
|
bots := listBots()
|
||||||
for botName, botMap := range bots {
|
for _, bot := range bots {
|
||||||
if err := recoverBot(botMap); err != nil {
|
if err := recoverBot(bot); err != nil {
|
||||||
log.Warn("failed to recover bot", "botName", botName, "error", err)
|
log.Warn("failed to recover bot", "botName", bot.Username, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func recoverBot(bm map[string]string) error {
|
func recoverBot(bm models.Player) error {
|
||||||
// check if room still exists
|
// check if room still exists
|
||||||
if _, err := getRoomByID(bm["room_id"]); err != nil {
|
if _, err := repo.RoomGetByID(context.Background(), bm.RoomID); err != nil {
|
||||||
return fmt.Errorf("no such room: %s; err: %w", bm["room_id"], err)
|
return fmt.Errorf("no such room: %s; err: %w", bm.RoomID, err)
|
||||||
}
|
}
|
||||||
log.Debug("recovering bot", "bot", bm)
|
log.Debug("recovering bot", "bot", bm)
|
||||||
_, err := llmapi.NewBot(bm["role"], bm["team"], bm["bot_name"], bm["room_id"], cfg, true)
|
_, err := llmapi.NewBot(string(bm.Role), string(bm.Team), bm.Username, bm.RoomID, cfg, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func recoverPlayers() {
|
// func recoverPlayers() {
|
||||||
players := listPlayers()
|
// players := listPlayers()
|
||||||
for playerName, playerMap := range players {
|
// for playerName, playerMap := range players {
|
||||||
if err := recoverPlayer(playerMap); err != nil {
|
// if err := recoverPlayer(playerMap); err != nil {
|
||||||
log.Warn("failed to recover player", "playerName", playerName, "error", err)
|
// log.Warn("failed to recover player", "playerName", playerName, "error", err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func recoverPlayer(pm map[string]string) error {
|
// func recoverPlayer(pm map[string]string) error {
|
||||||
// check if room still exists
|
// // check if room still exists
|
||||||
room, err := getRoomByID(pm["RoomID"])
|
// room, err := repo.RoomGetByID(context.Background(), pm["RoomID"])
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return fmt.Errorf("no such room: %s; err: %w", pm["RoomID"], err)
|
// return fmt.Errorf("no such room: %s; err: %w", pm["RoomID"], err)
|
||||||
}
|
// }
|
||||||
log.Debug("recovering player", "player", pm)
|
// log.Debug("recovering player", "player", pm)
|
||||||
role, team, ok := room.GetPlayerByName(pm["Username"])
|
// role, team, ok := room.GetPlayerByName(pm["Username"])
|
||||||
if !ok {
|
// if !ok {
|
||||||
return fmt.Errorf("failed to find player %s in the room %v", pm["Username"], room)
|
// return fmt.Errorf("failed to find player %s in the room %v", pm["Username"], room)
|
||||||
}
|
// }
|
||||||
us := &models.UserState{
|
// us := &models.Player{
|
||||||
Username: pm["Username"],
|
// Username: pm["Username"],
|
||||||
RoomID: pm["RoomID"],
|
// RoomID: pm["RoomID"],
|
||||||
Team: team,
|
// Team: team,
|
||||||
Role: role,
|
// Role: role,
|
||||||
}
|
// }
|
||||||
return saveState(pm["Username"], us)
|
// return saveState(pm["Username"], us)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// validateMove checks if it is players turn
|
// validateMove checks if it is players turn
|
||||||
func validateMove(fi *models.FullInfo, ur models.UserRole) error {
|
func validateMove(fi *models.FullInfo, ur models.UserRole) error {
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
|
"gralias/pkg/cache"
|
||||||
"gralias/utils"
|
"gralias/utils"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -36,7 +37,12 @@ func HandleNameCheck(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
cleanName := utils.RemoveSpacesFromStr(username)
|
cleanName := utils.RemoveSpacesFromStr(username)
|
||||||
allNames := getAllNames()
|
// allNames := getAllNames()
|
||||||
|
allNames, err := repo.PlayerListNames()
|
||||||
|
if err != nil {
|
||||||
|
abortWithError(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Info("names check", "taken_names", allNames, "trying_name", cleanName)
|
log.Info("names check", "taken_names", allNames, "trying_name", cleanName)
|
||||||
tmpl, err := template.ParseGlob("components/*.html")
|
tmpl, err := template.ParseGlob("components/*.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -175,7 +181,7 @@ func makeCookie(username string, remote string) (*http.Cookie, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cacheGetSession(key string) (*models.Session, error) {
|
func cacheGetSession(key string) (*models.Session, error) {
|
||||||
userSessionB, err := memcache.Get(key)
|
userSessionB, err := cache.MemCache.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -191,7 +197,7 @@ func cacheSetSession(key string, session *models.Session) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
memcache.Set(key, sesb)
|
cache.MemCache.Set(key, sesb)
|
||||||
memcache.Expire(key, cfg.SessionLifetime)
|
cache.MemCache.Expire(key, cfg.SessionLifetime)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,11 @@ import (
|
|||||||
"gralias/broker"
|
"gralias/broker"
|
||||||
"gralias/config"
|
"gralias/config"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
"gralias/pkg/cache"
|
|
||||||
"gralias/repos"
|
"gralias/repos"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -29,13 +27,13 @@ func init() {
|
|||||||
// memcache = cache.MemCache
|
// memcache = cache.MemCache
|
||||||
cfg = config.LoadConfigOrDefault("")
|
cfg = config.LoadConfigOrDefault("")
|
||||||
Notifier = broker.Notifier
|
Notifier = broker.Notifier
|
||||||
cache.MemCache.StartBackupRoutine(15 * time.Second) // Reduced backup interval
|
// cache.MemCache.StartBackupRoutine(15 * time.Second) // Reduced backup interval
|
||||||
// bot loader
|
// bot loader
|
||||||
// check the rooms if it has bot_{digits} in them, create bots if have
|
// check the rooms if it has bot_{digits} in them, create bots if have
|
||||||
repo = repos.NewRepoProvider("sqlite3://../gralias.db")
|
repo = repos.NewRepoProvider("sqlite3://../gralias.db")
|
||||||
recoverBots()
|
recoverBots()
|
||||||
// if player has a roomID, but no team and role, try to recover
|
// if player has a roomID, but no team and role, try to recover
|
||||||
recoverPlayers()
|
// recoverPlayers()
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandlePing(w http.ResponseWriter, r *http.Request) {
|
func HandlePing(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
|
"gralias/pkg/cache"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ func GetSession(next http.Handler) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if userSession.IsExpired() {
|
if userSession.IsExpired() {
|
||||||
memcache.RemoveKey(sessionToken)
|
cache.MemCache.RemoveKey(sessionToken)
|
||||||
msg := "session is expired"
|
msg := "session is expired"
|
||||||
log.Debug(msg, "error", err, "token", sessionToken)
|
log.Debug(msg, "error", err, "token", sessionToken)
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
"sync"
|
"sync"
|
||||||
@ -35,7 +36,7 @@ func StartTurnTimer(roomID string, duration time.Duration) {
|
|||||||
case <-done:
|
case <-done:
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
room, err := getRoomByID(roomID)
|
room, err := repo.RoomGetByID(context.Background(), roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get room by id", "error", err)
|
log.Error("failed to get room by id", "error", err)
|
||||||
StopTurnTimer(roomID)
|
StopTurnTimer(roomID)
|
||||||
@ -45,7 +46,7 @@ func StartTurnTimer(roomID string, duration time.Duration) {
|
|||||||
log.Info("turn time is over", "room_id", roomID)
|
log.Info("turn time is over", "room_id", roomID)
|
||||||
room.ChangeTurn()
|
room.ChangeTurn()
|
||||||
room.MimeDone = false
|
room.MimeDone = false
|
||||||
if err := saveRoom(room); err != nil {
|
if err := repo.RoomUpdate(context.Background(), room); err != nil {
|
||||||
log.Error("failed to save room", "error", err)
|
log.Error("failed to save room", "error", err)
|
||||||
}
|
}
|
||||||
notify(models.NotifyTurnTimerPrefix+room.ID, fmt.Sprintf("%d", room.Settings.TurnSecondsLeft))
|
notify(models.NotifyTurnTimerPrefix+room.ID, fmt.Sprintf("%d", room.Settings.TurnSecondsLeft))
|
||||||
@ -72,4 +73,3 @@ func StopTurnTimer(roomID string) {
|
|||||||
delete(timers, roomID)
|
delete(timers, roomID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ type WordCard struct {
|
|||||||
Word string `json:"word" db:"word"`
|
Word string `json:"word" db:"word"`
|
||||||
Color WordColor `json:"color" db:"color"`
|
Color WordColor `json:"color" db:"color"`
|
||||||
Revealed bool `json:"revealed" db:"revealed"`
|
Revealed bool `json:"revealed" db:"revealed"`
|
||||||
MimeView bool `json:"mime_view" db:"mime_view"` // user who sees that card is mime
|
Mime bool `json:"mime" db:"mime"` // user who sees that card is mime
|
||||||
Mark []CardMark `json:"marks" db:"-"`
|
Mark []CardMark `json:"marks" db:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,13 +402,16 @@ type RoomReq struct {
|
|||||||
|
|
||||||
func (rr *RoomReq) CreateRoom(creator string) *Room {
|
func (rr *RoomReq) CreateRoom(creator string) *Room {
|
||||||
roomID := xid.New().String()
|
roomID := xid.New().String()
|
||||||
|
settings := GameSettings{
|
||||||
|
Language: rr.Language,
|
||||||
|
RoundTime: rr.RoundTime,
|
||||||
|
RoomPass: rr.RoomPass,
|
||||||
|
}
|
||||||
return &Room{
|
return &Room{
|
||||||
ID: roomID,
|
ID: roomID,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
CreatorName: creator,
|
CreatorName: creator,
|
||||||
Language: rr.Language,
|
Settings: settings,
|
||||||
RoundTime: rr.RoundTime,
|
|
||||||
RoomPass: rr.RoomPass,
|
|
||||||
BotMap: make(map[string]BotPlayer),
|
BotMap: make(map[string]BotPlayer),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,17 @@ type PlayersRepo interface {
|
|||||||
PlayerDelete(roomID, username string) error
|
PlayerDelete(roomID, username string) error
|
||||||
PlayerSetRoomID(username, roomID string) error
|
PlayerSetRoomID(username, roomID string) error
|
||||||
PlayerExitRoom(username string) error
|
PlayerExitRoom(username string) error
|
||||||
|
PlayerListNames() ([]string, error)
|
||||||
|
PlayerList(isBot bool) ([]models.Player, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) PlayerListNames() ([]string, error) {
|
||||||
|
var names []string
|
||||||
|
err := p.DB.SelectContext(context.Background(), &names, "SELECT username FROM players;")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return names, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) PlayerGetByName(username string) (*models.Player, error) {
|
func (p *RepoProvider) PlayerGetByName(username string) (*models.Player, error) {
|
||||||
@ -49,3 +60,18 @@ func (p *RepoProvider) PlayerExitRoom(username string) error {
|
|||||||
_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = null WHERE username = ?", username)
|
_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = null WHERE username = ?", username)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) PlayerList(isBot bool) ([]models.Player, error) {
|
||||||
|
var players []models.Player
|
||||||
|
var query string
|
||||||
|
if isBot {
|
||||||
|
query = "SELECT id, room_id, username, team, role, is_bot FROM players WHERE is_bot = true;"
|
||||||
|
} else {
|
||||||
|
query = "SELECT id, room_id, username, team, role, is_bot FROM players WHERE is_bot = false;"
|
||||||
|
}
|
||||||
|
err := p.DB.SelectContext(context.Background(), &players, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return players, nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user