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.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 room, nil | ||||
| } | ||||
|  | ||||
| func saveRoom(room *models.Room) error { | ||||
| 	key := models.CacheRoomPrefix + room.ID | ||||
| 	data, err := json.Marshal(room) | ||||
| 	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 | ||||
| 	// time.Now().Add(time.Hour).Sub(room.LastActionTS) | ||||
| 	anHour := int64(216000) // 60 * 60 * 60 | ||||
| 	memcache.Expire(key, anHour) | ||||
| 	return nil | ||||
| } | ||||
| // // DEPRECATED | ||||
| // func saveRoom(room *models.Room) error { | ||||
| // 	key := models.CacheRoomPrefix + room.ID | ||||
| // 	data, err := json.Marshal(room) | ||||
| // 	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 | ||||
| // 	// time.Now().Add(time.Hour).Sub(room.LastActionTS) | ||||
| // 	anHour := int64(216000) // 60 * 60 * 60 | ||||
| // 	memcache.Expire(key, anHour) | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| func getRoomByID(roomID string) (*models.Room, error) { | ||||
| 	roomBytes, err := memcache.Get(models.CacheRoomPrefix + roomID) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	resp := &models.Room{} | ||||
| 	if err := json.Unmarshal(roomBytes, &resp); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return resp, nil | ||||
| } | ||||
| // func getRoomByID(roomID string) (*models.Room, error) { | ||||
| // 	roomBytes, err := memcache.Get(models.CacheRoomPrefix + roomID) | ||||
| // 	if err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // 	resp := &models.Room{} | ||||
| // 	if err := json.Unmarshal(roomBytes, &resp); err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // 	return resp, nil | ||||
| // } | ||||
|  | ||||
| func removeRoom(roomID string) { | ||||
| 	key := models.CacheRoomPrefix + roomID | ||||
| 	memcache.RemoveKey(key) | ||||
| } | ||||
| // func removeRoom(roomID string) { | ||||
| // 	key := models.CacheRoomPrefix + roomID | ||||
| // 	memcache.RemoveKey(key) | ||||
| // } | ||||
|  | ||||
| // context | ||||
|  | ||||
| @@ -76,17 +77,17 @@ func getStateByCtx(ctx context.Context) (*models.UserState, error) { | ||||
| // 	repo.CreateRoom() | ||||
| // } | ||||
|  | ||||
| func saveFullInfo(fi *models.FullInfo) error { | ||||
| 	// 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 { | ||||
| 		return err | ||||
| 	} | ||||
| 	log.Debug("saved user state", "state", fi.State) | ||||
| 	if err := saveRoom(fi.Room); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| // func saveFullInfo(fi *models.FullInfo) error { | ||||
| // 	// 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 { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	log.Debug("saved user state", "state", fi.State) | ||||
| // 	if err := saveRoom(fi.Room); err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| func notifyBotIfNeeded(room *models.Room) { | ||||
| 	if botName := room.WhichBotToMove(); botName != "" { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ import ( | ||||
| var ( | ||||
| 	log *slog.Logger | ||||
| 	cfg *config.Config | ||||
| 	memcache cache.Cache | ||||
| 	// memcache cache.Cache | ||||
| 	Notifier *broker.Broker | ||||
| 	repo     repos.AllRepos | ||||
| ) | ||||
| @@ -26,7 +26,7 @@ func init() { | ||||
| 		Level:     slog.LevelDebug, | ||||
| 		AddSource: true, | ||||
| 	})) | ||||
| 	memcache = cache.MemCache | ||||
| 	// memcache = cache.MemCache | ||||
| 	cfg = config.LoadConfigOrDefault("") | ||||
| 	Notifier = broker.Notifier | ||||
| 	cache.MemCache.StartBackupRoutine(15 * time.Second) // Reduced backup interval | ||||
| @@ -91,17 +91,25 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { | ||||
| 		creatorLeft = true | ||||
| 	} | ||||
| 	exitedRoom := fi.ExitRoom() | ||||
| 	if err := saveRoom(exitedRoom); err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	// if err := saveRoom(exitedRoom); err != nil { | ||||
| 	// 	abortWithError(w, err.Error()) | ||||
| 	// 	return | ||||
| 	// } | ||||
| 	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 | ||||
| 		// and throw them away | ||||
| 		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()) | ||||
| 		return | ||||
| 	} | ||||
|   | ||||
| @@ -14,7 +14,7 @@ CREATE TABLE rooms ( | ||||
|     is_running BOOLEAN NOT NULL DEFAULT FALSE, | ||||
|     is_over BOOLEAN NOT NULL DEFAULT FALSE, | ||||
|     team_won TEXT NOT NULL DEFAULT '', | ||||
|     room_pass TEXT NOT NULL DEFAULT '' | ||||
|     room_link TEXT NOT NULL DEFAULT '' | ||||
| ); | ||||
|  | ||||
| CREATE TABLE players ( | ||||
|   | ||||
| @@ -373,11 +373,13 @@ func (r *Room) RevealSpecificWord(word string) { | ||||
| } | ||||
|  | ||||
| type WordCard struct { | ||||
| 	Word     string     `json:"word"` | ||||
| 	Color    WordColor  `json:"color"` | ||||
| 	Revealed bool       `json:"revealed"` | ||||
| 	Mime     bool       `json:"mime"` // user who sees that card is mime | ||||
| 	Mark     []CardMark `json:"marks"` | ||||
| 	ID       uint32     `json:"id" db:"id"` | ||||
| 	RoomID   string     `json:"room_id" db:"room_id"` | ||||
| 	Word     string     `json:"word" db:"word"` | ||||
| 	Color    WordColor  `json:"color" db:"color"` | ||||
| 	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 | ||||
|   | ||||
| @@ -10,6 +10,8 @@ type PlayersRepo interface { | ||||
| 	PlayerAdd(player *models.Player) error | ||||
| 	PlayerUpdate(player *models.Player) error | ||||
| 	PlayerDelete(roomID, username string) error | ||||
| 	PlayerSetRoomID(username, roomID string) error | ||||
| 	PlayerExitRoom(username string) 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 { | ||||
| 	_, 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 | ||||
| } | ||||
|  | ||||
| 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 | ||||
| } | ||||
|  | ||||
| @@ -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) | ||||
| 	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 { | ||||
| 	ListRooms(ctx context.Context) ([]*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 | ||||
| 	DeleteRoomByID(ctx context.Context, id string) 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 { | ||||
| 	_, 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 | ||||
| } | ||||
|  | ||||
| @@ -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 { | ||||
| 	_, 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 | ||||
| } | ||||
|  | ||||
| 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