Skip to content

Commit

Permalink
Merge pull request #105 from linycken013127/feature/game-event
Browse files Browse the repository at this point in the history
Feat: Refine the SSE information and logic, as well as the games and player databases.
  • Loading branch information
linycken013127 committed Jan 16, 2024
2 parents 8f5a83d + 0678caf commit 0ae3767
Show file tree
Hide file tree
Showing 23 changed files with 283 additions and 100 deletions.
8 changes: 6 additions & 2 deletions Backend/cmd/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func main() {
playerService := service.NewPlayerService(&service.PlayerServiceOptions{
PlayerRepo: playerRepo,
PlayerCardRepo: playerCardRepo,
GameRepo: gameRepo,
})

gameService := service.NewGameService(
Expand All @@ -52,6 +53,7 @@ func main() {
DeckService: deckService,
},
)
playerService.GameServ = &gameService

http.RegisterGameHandler(
&http.GameHandlerOptions{
Expand All @@ -76,8 +78,10 @@ func main() {

http.RegisterPlayerHandler(
&http.PlayerHandlerOptions{
Engine: engine,
Service: playerService,
Engine: engine,
Service: playerService,
GameService: gameService,
SSE: sse,
},
)
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
Expand Down
12 changes: 7 additions & 5 deletions Backend/database/migrations/000001_create_games_table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ BEGIN;

CREATE TABLE games
(
id INT AUTO_INCREMENT PRIMARY KEY,
token LONGTEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
id INT AUTO_INCREMENT PRIMARY KEY,
token LONGTEXT NOT NULL,
status VARCHAR(10) NOT NULL,
current_player_id INT,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
18 changes: 10 additions & 8 deletions Backend/database/migrations/000002_create_players_table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ BEGIN;

CREATE TABLE players
(
id INT AUTO_INCREMENT PRIMARY KEY,
game_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
identity_card VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME,
FOREIGN KEY (game_id) REFERENCES games (id)
id INT AUTO_INCREMENT PRIMARY KEY,
game_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
order_number INT NOT NULL,
identity_card VARCHAR(255) NOT NULL,
status VARCHAR(10) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME,
FOREIGN KEY (game_id) REFERENCES games (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
12 changes: 6 additions & 6 deletions Backend/database/migrations/000003_create_cards_table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ BEGIN;

CREATE TABLE cards
(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
color VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
color VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
12 changes: 6 additions & 6 deletions Backend/database/migrations/000004_create_decks_table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ BEGIN;

CREATE TABLE decks
(
id INT AUTO_INCREMENT PRIMARY KEY,
game_id INT NOT NULL,
card_id INT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
id INT AUTO_INCREMENT PRIMARY KEY,
game_id INT NOT NULL,
card_id INT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
22 changes: 11 additions & 11 deletions Backend/database/migrations/000005_create_player_cards_table.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ BEGIN;

CREATE TABLE player_cards
(
id INT AUTO_INCREMENT PRIMARY KEY,
player_id INT NOT NULL,
game_id INT NOT NULL,
card_id INT NOT NULL,
type VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME,
FOREIGN KEY (player_id) REFERENCES players (id),
FOREIGN KEY (game_id) REFERENCES games (id),
FOREIGN KEY (card_id) REFERENCES cards (id)
id INT AUTO_INCREMENT PRIMARY KEY,
player_id INT NOT NULL,
game_id INT NOT NULL,
card_id INT NOT NULL,
type VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME,
FOREIGN KEY (player_id) REFERENCES players (id),
FOREIGN KEY (game_id) REFERENCES games (id),
FOREIGN KEY (card_id) REFERENCES cards (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BEGIN;

DROP TABLE IF EXISTS game_progresses;

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
BEGIN;

CREATE TABLE game_progresses
(
id INT AUTO_INCREMENT PRIMARY KEY,
player_id INT NOT NULL,
game_id INT NOT NULL,
card_id INT NOT NULL,
action VARCHAR(255) NOT NULL,
target_player_id INT,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME,
FOREIGN KEY (player_id) REFERENCES players (id),
FOREIGN KEY (game_id) REFERENCES games (id),
FOREIGN KEY (card_id) REFERENCES cards (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

COMMIT;
8 changes: 8 additions & 0 deletions Backend/enums/game_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package enums

const (
GameStart = "開始遊戲"
ActionCardStage = "功能牌階段"
TransmitIntelligenceStage = "情報牌階段"
GameEnd = "結束遊戲"
)
6 changes: 6 additions & 0 deletions Backend/enums/player_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package enums

const (
PlayerStatusAlive = "生存"
PlayerStatusDead = "死亡"
)
8 changes: 0 additions & 8 deletions Backend/service/delivery/http/v1/card_handler.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package http

import (
"encoding/json"
"fmt"
"net/http"
"strconv"

Expand Down Expand Up @@ -53,12 +51,6 @@ func (p *CardHandler) GetPlayerCards(c *gin.Context) {
}
playerCardsInfo = append(playerCardsInfo, dict)
}
jsonData, err := json.Marshal(playerCardsInfo)
fmt.Println(jsonData)
if err != nil {
fmt.Println("Error encoding JSON:", err)
return
}

c.JSON(http.StatusOK, gin.H{"player_cards": playerCardsInfo})
}
34 changes: 29 additions & 5 deletions Backend/service/delivery/http/v1/game_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package http

import (
"encoding/json"
"github.com/Game-as-a-Service/The-Message/enums"
"io"
"log"
"net/http"
Expand Down Expand Up @@ -56,11 +57,16 @@ func (g *GameHandler) StartGame(c *gin.Context) {
return
}

// TODO 這邊可以優化 https://gorm.io/zh_CN/docs/associations.html
if err := g.gameService.PlayerService.InitPlayers(c, game, req); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
return
}

game, _ = g.gameService.GetGameById(c, game.Id)
g.gameService.UpdateCurrentPlayer(c, game, game.Players[0].Id)
g.gameService.UpdateStatus(c, game, enums.ActionCardStage)

if err := g.gameService.InitDeck(c, game); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
return
Expand All @@ -71,11 +77,16 @@ func (g *GameHandler) StartGame(c *gin.Context) {
return
}

game, err = g.gameService.GetGameById(c, game.Id)
if err != nil {
return
}

g.SSE.Message <- gin.H{
"message": "Game started",
"status": "started",
"gameId": strconv.Itoa(game.Id),
//"game": game,
"message": "Game started",
"status": "started",
"game_id": game.Id,
"next_player": game.Players[0].Id,
}

c.JSON(http.StatusOK, gin.H{
Expand Down Expand Up @@ -138,8 +149,21 @@ func (g *GameHandler) GameEvent(c *gin.Context) {
return
}

game, err := g.gameService.GetGameById(c, gameId)
if err != nil {
return
}

g.SSE.Message <- gin.H{
"message": game.Status,
"status": game.Status,
"game_id": gameId,
"current_player": game.CurrentPlayerId,
}

c.Stream(func(w io.Writer) bool {
if msg, ok := <-clientChan; ok {
log.Printf("msg: %+v", msg)
data := GameSSERequest{}
err := json.Unmarshal([]byte(msg), &data)
if err != nil {
Expand All @@ -156,7 +180,7 @@ func (g *GameHandler) GameEvent(c *gin.Context) {
}

type GameSSERequest struct {
GameId int `json:"gameId,string"`
GameId int `json:"game_id,int"`
Message string `json:"message"`
Status string `json:"status"`
}
27 changes: 21 additions & 6 deletions Backend/service/delivery/http/v1/player_handler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package http

import (
"fmt"
"github.com/Game-as-a-Service/The-Message/service/request"
"net/http"
"strconv"
Expand All @@ -11,16 +12,22 @@ import (

type PlayerHandler struct {
playerService service.PlayerService
gameService service.GameService
SSE *Event
}

type PlayerHandlerOptions struct {
Engine *gin.Engine
Service service.PlayerService
Engine *gin.Engine
Service service.PlayerService
GameService service.GameService
SSE *Event
}

func RegisterPlayerHandler(opts *PlayerHandlerOptions) {
handler := &PlayerHandler{
playerService: opts.Service,
gameService: opts.GameService,
SSE: opts.SSE,
}

opts.Engine.POST("/api/v1/players/:playerId/player-cards", handler.PlayCard)
Expand All @@ -39,19 +46,27 @@ func RegisterPlayerHandler(opts *PlayerHandlerOptions) {
func (p *PlayerHandler) PlayCard(c *gin.Context) {
playerId, _ := strconv.Atoi(c.Param("playerId"))
var req request.PlayCardRequest

if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

result, err := p.playerService.PlayCard(c, playerId, req.CardID)
game, card, err := p.playerService.PlayCard(c, playerId, req.CardID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
return
}

// TODO to Service
p.SSE.Message <- gin.H{
"game_id": game.Id,
"status": game.Status,
"message": fmt.Sprintf("玩家: %d 已出牌", playerId),
"card": card.Name,
"next_player": game.CurrentPlayerId,
}

c.JSON(http.StatusOK, gin.H{
"result": result,
"result": true,
})
}
1 change: 0 additions & 1 deletion Backend/service/delivery/http/v1/sse_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ func (stream *Event) listen() {
case eventMsg := <-stream.Message:
jsonMsg, err := json.Marshal(eventMsg)
if err != nil {
// 处理错误
continue
}

Expand Down
15 changes: 9 additions & 6 deletions Backend/service/repository/game_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ import (

type Game struct {
gorm.Model
Id int `gorm:"primaryKey;auto_increment"`
Token string
Players []Player
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoCreateTime"`
DeletedAt gorm.DeletedAt
Id int `gorm:"primaryKey;auto_increment"`
Token string
Status string
CurrentPlayerId int
Players []Player
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoCreateTime"`
DeletedAt gorm.DeletedAt
}

type GameRepository interface {
GetGameById(ctx context.Context, id int) (*Game, error)
CreateGame(ctx context.Context, game *Game) (*Game, error)
DeleteGame(ctx context.Context, id int) error
GetGameWithPlayers(ctx context.Context, id int) (*Game, error)
UpdateGame(ctx context.Context, game *Game) error
}
Loading

0 comments on commit 0ae3767

Please sign in to comment.