Enha: model update
This commit is contained in:
		| @@ -20,42 +20,43 @@ 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 := saveRoom(room); err != nil { | 	if err := repo.CreateRoom(ctx, room); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return room, nil | 	return room, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func saveRoom(room *models.Room) error { | // // DEPRECATED | ||||||
| 	key := models.CacheRoomPrefix + room.ID | // func saveRoom(room *models.Room) error { | ||||||
| 	data, err := json.Marshal(room) | // 	key := models.CacheRoomPrefix + room.ID | ||||||
| 	if err != nil { | // 	data, err := json.Marshal(room) | ||||||
| 		return err | // 	if err != nil { | ||||||
| 	} | // 		return err | ||||||
| 	memcache.Set(key, data) | // 	} | ||||||
| 	// do I need last action here? since room save is kind of an action on itself | // 	memcache.Set(key, data) | ||||||
| 	// time.Now().Add(time.Hour).Sub(room.LastActionTS) | // 	// do I need last action here? since room save is kind of an action on itself | ||||||
| 	anHour := int64(216000) // 60 * 60 * 60 | // 	// time.Now().Add(time.Hour).Sub(room.LastActionTS) | ||||||
| 	memcache.Expire(key, anHour) | // 	anHour := int64(216000) // 60 * 60 * 60 | ||||||
| 	return nil | // 	memcache.Expire(key, anHour) | ||||||
| } | // 	return nil | ||||||
|  | // } | ||||||
|  |  | ||||||
| func getRoomByID(roomID string) (*models.Room, error) { | // func getRoomByID(roomID string) (*models.Room, error) { | ||||||
| 	roomBytes, err := memcache.Get(models.CacheRoomPrefix + roomID) | // 	roomBytes, err := memcache.Get(models.CacheRoomPrefix + roomID) | ||||||
| 	if err != nil { | // 	if err != nil { | ||||||
| 		return nil, err | // 		return nil, err | ||||||
| 	} | // 	} | ||||||
| 	resp := &models.Room{} | // 	resp := &models.Room{} | ||||||
| 	if err := json.Unmarshal(roomBytes, &resp); err != nil { | // 	if err := json.Unmarshal(roomBytes, &resp); err != nil { | ||||||
| 		return nil, err | // 		return nil, err | ||||||
| 	} | // 	} | ||||||
| 	return resp, nil | // 	return resp, nil | ||||||
| } | // } | ||||||
|  |  | ||||||
| func removeRoom(roomID string) { | // func removeRoom(roomID string) { | ||||||
| 	key := models.CacheRoomPrefix + roomID | // 	key := models.CacheRoomPrefix + roomID | ||||||
| 	memcache.RemoveKey(key) | // 	memcache.RemoveKey(key) | ||||||
| } | // } | ||||||
|  |  | ||||||
| // context | // context | ||||||
|  |  | ||||||
| @@ -76,17 +77,17 @@ func getStateByCtx(ctx context.Context) (*models.UserState, error) { | |||||||
| // 	repo.CreateRoom() | // 	repo.CreateRoom() | ||||||
| // } | // } | ||||||
|  |  | ||||||
| func saveFullInfo(fi *models.FullInfo) error { | // func saveFullInfo(fi *models.FullInfo) error { | ||||||
| 	// INFO: no transactions; so case is possible where first object is updated but the second is not | // 	// INFO: no transactions; so case is possible where first object is updated but the second is not | ||||||
| 	if err := saveState(fi.State.Username, fi.State); err != nil { | // 	if err := saveState(fi.State.Username, fi.State); err != nil { | ||||||
| 		return err | // 		return err | ||||||
| 	} | // 	} | ||||||
| 	log.Debug("saved user state", "state", fi.State) | // 	log.Debug("saved user state", "state", fi.State) | ||||||
| 	if err := saveRoom(fi.Room); err != nil { | // 	if err := saveRoom(fi.Room); err != nil { | ||||||
| 		return err | // 		return err | ||||||
| 	} | // 	} | ||||||
| 	return nil | // 	return nil | ||||||
| } | // } | ||||||
|  |  | ||||||
| func notifyBotIfNeeded(room *models.Room) { | func notifyBotIfNeeded(room *models.Room) { | ||||||
| 	if botName := room.WhichBotToMove(); botName != "" { | 	if botName := room.WhichBotToMove(); botName != "" { | ||||||
|   | |||||||
| @@ -14,9 +14,9 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	log      *slog.Logger | 	log *slog.Logger | ||||||
| 	cfg      *config.Config | 	cfg *config.Config | ||||||
| 	memcache cache.Cache | 	// memcache cache.Cache | ||||||
| 	Notifier *broker.Broker | 	Notifier *broker.Broker | ||||||
| 	repo     repos.AllRepos | 	repo     repos.AllRepos | ||||||
| ) | ) | ||||||
| @@ -26,7 +26,7 @@ func init() { | |||||||
| 		Level:     slog.LevelDebug, | 		Level:     slog.LevelDebug, | ||||||
| 		AddSource: true, | 		AddSource: true, | ||||||
| 	})) | 	})) | ||||||
| 	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 | ||||||
| @@ -91,17 +91,25 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { | |||||||
| 		creatorLeft = true | 		creatorLeft = true | ||||||
| 	} | 	} | ||||||
| 	exitedRoom := fi.ExitRoom() | 	exitedRoom := fi.ExitRoom() | ||||||
| 	if err := saveRoom(exitedRoom); err != nil { | 	// if err := saveRoom(exitedRoom); err != nil { | ||||||
| 		abortWithError(w, err.Error()) | 	// 	abortWithError(w, err.Error()) | ||||||
| 		return | 	// 	return | ||||||
| 	} | 	// } | ||||||
| 	if creatorLeft { | 	if creatorLeft { | ||||||
| 		removeRoom(exitedRoom.ID) | 		if err := repo.DeleteRoomByID(r.Context(), exitedRoom.ID); err != nil { | ||||||
|  | 			log.Error("failed to remove room", "error", err) | ||||||
|  | 		} | ||||||
|  | 		// removeRoom(exitedRoom.ID) | ||||||
| 		// TODO: notify users if creator left | 		// TODO: notify users if creator left | ||||||
| 		// and throw them away | 		// and throw them away | ||||||
| 		notify(models.NotifyRoomListUpdate, "") | 		notify(models.NotifyRoomListUpdate, "") | ||||||
| 	} | 	} | ||||||
| 	if err := saveState(fi.State.Username, fi.State); err != nil { | 	// scary to update the whole room | ||||||
|  | 	if err := repo.UpdateRoom(r.Context(), exitedRoom); err != nil { | ||||||
|  | 		abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if err := repo.PlayerExitRoom(fi.State.Username); err != nil { | ||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ CREATE TABLE rooms ( | |||||||
|     is_running BOOLEAN NOT NULL DEFAULT FALSE, |     is_running BOOLEAN NOT NULL DEFAULT FALSE, | ||||||
|     is_over BOOLEAN NOT NULL DEFAULT FALSE, |     is_over BOOLEAN NOT NULL DEFAULT FALSE, | ||||||
|     team_won TEXT NOT NULL DEFAULT '', |     team_won TEXT NOT NULL DEFAULT '', | ||||||
|     room_pass TEXT NOT NULL DEFAULT '' |     room_link TEXT NOT NULL DEFAULT '' | ||||||
| ); | ); | ||||||
|  |  | ||||||
| CREATE TABLE players ( | CREATE TABLE players ( | ||||||
|   | |||||||
| @@ -373,11 +373,13 @@ func (r *Room) RevealSpecificWord(word string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| type WordCard struct { | type WordCard struct { | ||||||
| 	Word     string     `json:"word"` | 	ID       uint32     `json:"id" db:"id"` | ||||||
| 	Color    WordColor  `json:"color"` | 	RoomID   string     `json:"room_id" db:"room_id"` | ||||||
| 	Revealed bool       `json:"revealed"` | 	Word     string     `json:"word" db:"word"` | ||||||
| 	Mime     bool       `json:"mime"` // user who sees that card is mime | 	Color    WordColor  `json:"color" db:"color"` | ||||||
| 	Mark     []CardMark `json:"marks"` | 	Revealed bool       `json:"revealed" db:"revealed"` | ||||||
|  | 	MimeView bool       `json:"mime_view" db:"mime_view"` // user who sees that card is mime | ||||||
|  | 	Mark     []CardMark `json:"marks" db:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // table: settings | // table: settings | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ type PlayersRepo interface { | |||||||
| 	PlayerAdd(player *models.Player) error | 	PlayerAdd(player *models.Player) error | ||||||
| 	PlayerUpdate(player *models.Player) error | 	PlayerUpdate(player *models.Player) error | ||||||
| 	PlayerDelete(roomID, username string) error | 	PlayerDelete(roomID, username string) error | ||||||
|  | 	PlayerSetRoomID(username, roomID string) error | ||||||
|  | 	PlayerExitRoom(username string) error | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) PlayerGetByName(username string) (*models.Player, error) { | func (p *RepoProvider) PlayerGetByName(username string) (*models.Player, error) { | ||||||
| @@ -22,12 +24,14 @@ func (p *RepoProvider) PlayerGetByName(username string) (*models.Player, error) | |||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) PlayerAdd(player *models.Player) error { | func (p *RepoProvider) PlayerAdd(player *models.Player) error { | ||||||
| 	_, err := p.DB.ExecContext(context.Background(), "INSERT INTO players (room_id, username, team, role, is_bot) VALUES (?, ?, ?, ?, ?)", player.RoomID, player.Username, player.Team, player.Role, player.IsBot) | 	_, err := p.DB.ExecContext(context.Background(), "INSERT INTO players (room_id, username, team, role, is_bot) VALUES (?, ?, ?, ?, ?)", | ||||||
|  | 		player.RoomID, player.Username, player.Team, player.Role, player.IsBot) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) PlayerUpdate(player *models.Player) error { | func (p *RepoProvider) PlayerUpdate(player *models.Player) error { | ||||||
| 	_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = ?, username = ?, team = ?, role = ?, is_bot = ? WHERE id = ?", player.RoomID, player.Username, player.Team, player.Role, player.IsBot, player.ID) | 	_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = ?, username = ?, team = ?, role = ?, is_bot = ? WHERE id = ?", | ||||||
|  | 		player.RoomID, player.Username, player.Team, player.Role, player.IsBot, player.ID) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -35,3 +39,13 @@ func (p *RepoProvider) PlayerDelete(roomID, username string) error { | |||||||
| 	_, err := p.DB.ExecContext(context.Background(), "DELETE FROM players WHERE room_id = ? AND username = ?", roomID, username) | 	_, err := p.DB.ExecContext(context.Background(), "DELETE FROM players WHERE room_id = ? AND username = ?", roomID, username) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (p *RepoProvider) PlayerSetRoomID(username, roomID string) error { | ||||||
|  | 	_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = ? WHERE username = ?", roomID, username) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *RepoProvider) PlayerExitRoom(username string) error { | ||||||
|  | 	_, err := p.DB.ExecContext(context.Background(), "UPDATE players SET room_id = null WHERE username = ?", username) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| type RoomsRepo interface { | type RoomsRepo interface { | ||||||
| 	ListRooms(ctx context.Context) ([]*models.Room, error) | 	ListRooms(ctx context.Context) ([]*models.Room, error) | ||||||
| 	GetRoomByID(ctx context.Context, id string) (*models.Room, error) | 	GetRoomByID(ctx context.Context, id string) (*models.Room, error) | ||||||
|  | 	GetRoomExtended(ctx context.Context, id string) (*models.Room, error) | ||||||
| 	CreateRoom(ctx context.Context, room *models.Room) error | 	CreateRoom(ctx context.Context, room *models.Room) error | ||||||
| 	DeleteRoomByID(ctx context.Context, id string) error | 	DeleteRoomByID(ctx context.Context, id string) error | ||||||
| 	UpdateRoom(ctx context.Context, room *models.Room) error | 	UpdateRoom(ctx context.Context, room *models.Room) error | ||||||
| @@ -32,7 +33,7 @@ func (p *RepoProvider) GetRoomByID(ctx context.Context, id string) (*models.Room | |||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) CreateRoom(ctx context.Context, r *models.Room) error { | func (p *RepoProvider) CreateRoom(ctx context.Context, r *models.Room) error { | ||||||
| 	_, err := p.DB.ExecContext(ctx, `INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, round_time, is_over, team_won, room_pass) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, r.ID, r.CreatedAt, r.CreatorName, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.RoundTime, r.IsOver, r.TeamWon, r.RoomPass) | 	_, err := p.DB.ExecContext(ctx, `INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, , is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, r.ID, r.CreatedAt, r.CreatorName, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.IsOver, r.TeamWon, r.RoomLink) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -42,6 +43,73 @@ func (p *RepoProvider) DeleteRoomByID(ctx context.Context, id string) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) UpdateRoom(ctx context.Context, r *models.Room) error { | func (p *RepoProvider) UpdateRoom(ctx context.Context, r *models.Room) error { | ||||||
| 	_, err := p.DB.ExecContext(ctx, `UPDATE rooms SET team_turn = ?, this_turn_limit = ?, opened_this_turn = ?, blue_counter = ?, red_counter = ?, red_turn = ?, mime_done = ?, is_running = ?, round_time = ?, is_over = ?, team_won = ?, room_pass = ? WHERE id = ?`, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.RoundTime, r.IsOver, r.TeamWon, r.RoomPass, r.ID) | 	_, err := p.DB.ExecContext(ctx, `UPDATE rooms SET team_turn = ?, this_turn_limit = ?, opened_this_turn = ?, blue_counter = ?, red_counter = ?, red_turn = ?, mime_done = ?,  = ?, is_running = ?, is_over = ?, team_won = ?, room_link = ? WHERE id = ?`, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.IsOver, r.TeamWon, r.RoomLink, r.ID) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (p *RepoProvider) GetRoomExtended(ctx context.Context, id string) (*models.Room, error) { | ||||||
|  | 	room := &models.Room{} | ||||||
|  | 	err := p.DB.GetContext(ctx, room, `SELECT * FROM rooms WHERE id = ?`, id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get players | ||||||
|  | 	players := []*models.Player{} | ||||||
|  | 	err = p.DB.SelectContext(ctx, &players, `SELECT * FROM players WHERE room_id = ?`, id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	room.RedTeam.Color = string(models.UserTeamRed) | ||||||
|  | 	room.BlueTeam.Color = string(models.UserTeamBlue) | ||||||
|  | 	for _, player := range players { | ||||||
|  | 		if player.Team == models.UserTeamRed { | ||||||
|  | 			if player.Role == models.UserRoleMime { | ||||||
|  | 				room.RedTeam.Mime = player.Username | ||||||
|  | 			} else { | ||||||
|  | 				room.RedTeam.Guessers = append(room.RedTeam.Guessers, player.Username) | ||||||
|  | 			} | ||||||
|  | 		} else if player.Team == models.UserTeamBlue { | ||||||
|  | 			if player.Role == models.UserRoleMime { | ||||||
|  | 				room.BlueTeam.Mime = player.Username | ||||||
|  | 			} else { | ||||||
|  | 				room.BlueTeam.Guessers = append(room.BlueTeam.Guessers, player.Username) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if player.IsBot { | ||||||
|  | 			if room.BotMap == nil { | ||||||
|  | 				room.BotMap = make(map[string]models.BotPlayer) | ||||||
|  | 			} | ||||||
|  | 			room.BotMap[player.Username] = models.BotPlayer{ | ||||||
|  | 				Role: player.Role, | ||||||
|  | 				Team: player.Team, | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get word cards | ||||||
|  | 	wordCards := []*models.WordCard{} | ||||||
|  | 	err = p.DB.SelectContext(ctx, &wordCards, `SELECT * FROM word_cards WHERE room_id = ?`, id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	room.Cards = wordCards | ||||||
|  |  | ||||||
|  | 	// Get actions | ||||||
|  | 	actions := []*models.Action{} | ||||||
|  | 	err = p.DB.SelectContext(ctx, &actions, `SELECT * FROM actions WHERE room_id = ? ORDER BY created_at ASC`, id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	room.ActionHistory = actions | ||||||
|  |  | ||||||
|  | 	// Get settings | ||||||
|  | 	settings := &models.GameSettings{} | ||||||
|  | 	err = p.DB.GetContext(ctx, settings, `SELECT * FROM settings WHERE room_id = ?`, id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	room.Settings = *settings | ||||||
|  |  | ||||||
|  | 	return room, nil | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder