Feature: destroy room after user disconnected
This commit is contained in:
@@ -19,16 +19,21 @@ type ConnManager struct {
|
||||
getReadyCh chan message.GetReadyMsg
|
||||
chatCh chan message.ChatMsg
|
||||
exitCh chan bool
|
||||
destroyCh chan int
|
||||
|
||||
roomID int
|
||||
}
|
||||
|
||||
func NewConnManager(playersCount int,
|
||||
func NewConnManager(roomID int,
|
||||
playersCount int,
|
||||
gameRecvCh chan message.GameMsgRecv,
|
||||
gameSendCh chan message.GameMsgSend,
|
||||
tableOrderCh chan int,
|
||||
gameResultCh chan message.GameResultMsg,
|
||||
getReadyCh chan message.GetReadyMsg,
|
||||
chatCh chan message.ChatMsg,
|
||||
exitCh chan bool) *ConnManager {
|
||||
exitCh chan bool,
|
||||
destroyCh chan int) *ConnManager {
|
||||
connManager := ConnManager{playersCount: playersCount,
|
||||
conns: make([]*websocket.Conn, 0),
|
||||
gameRecvCh: gameRecvCh,
|
||||
@@ -38,13 +43,15 @@ func NewConnManager(playersCount int,
|
||||
getReadyCh: getReadyCh,
|
||||
chatCh: chatCh,
|
||||
exitCh: exitCh,
|
||||
destroyCh: destroyCh,
|
||||
roomID: roomID,
|
||||
}
|
||||
go connManager.Broadcaster()
|
||||
return &connManager
|
||||
}
|
||||
|
||||
func (m *ConnManager) AddConn(conn *websocket.Conn) {
|
||||
index:= len(m.conns)
|
||||
index := len(m.conns)
|
||||
msg := message.TableOrderMsg{
|
||||
MsgType: config.TableOrderMsgType,
|
||||
TableOrder: index,
|
||||
@@ -83,6 +90,8 @@ func (m *ConnManager) Broadcaster() {
|
||||
}
|
||||
case msg := <-m.exitCh:
|
||||
if msg {
|
||||
log.Println("broadcaster exit")
|
||||
m.destroyCh <- m.roomID
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -109,16 +118,19 @@ func (m *ConnManager) checkConn(c *websocket.Conn) {
|
||||
for _, conn := range m.conns {
|
||||
conn.Close()
|
||||
}
|
||||
m.exitCh <- true
|
||||
}
|
||||
|
||||
func (m *ConnManager) connListener(conn *websocket.Conn, gameRecvCh chan message.GameMsgRecv, chatCh chan message.ChatMsg) {
|
||||
for {
|
||||
log.Println("waiting msg")
|
||||
commonMsg := message.CommonMsg{}
|
||||
_, msg, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
//TODO: handle when user force exit
|
||||
m.checkConn(conn)
|
||||
log.Println("failed to read message")
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(msg, &commonMsg)
|
||||
if err != nil {
|
||||
|
||||
+12
-2
@@ -19,6 +19,7 @@ type Hall struct {
|
||||
players map[int]int
|
||||
|
||||
maxRoomSize int
|
||||
destroyCh chan int
|
||||
}
|
||||
|
||||
var hall *Hall = nil
|
||||
@@ -33,13 +34,15 @@ func GetHall() *Hall {
|
||||
}
|
||||
|
||||
func NewHall(maxRoomSize int) *Hall {
|
||||
return &Hall{maxRoomSize: maxRoomSize, rooms: map[int]*Room{}, players: map[int]int{}}
|
||||
hall:=Hall{maxRoomSize: maxRoomSize, rooms: map[int]*Room{}, players: map[int]int{}, destroyCh: make(chan int)}
|
||||
go hall.roomController()
|
||||
return &hall
|
||||
}
|
||||
|
||||
func (h *Hall) CreateRoom(userID int, passwd string) int {
|
||||
for i := 0; i < h.maxRoomSize; i++ {
|
||||
if !h.hasRoom(i) {
|
||||
room := NewRoom(rule.NewJinzhouRule())
|
||||
room := NewRoom(i, rule.NewJinzhouRule(), h.destroyCh)
|
||||
room.Start()
|
||||
room.password = passwd
|
||||
room.playerCount = 1
|
||||
@@ -97,3 +100,10 @@ func (h *Hall) hasRoom(roomID int) bool {
|
||||
func (h *Hall) destroyRoom(roomID int) {
|
||||
delete(h.rooms, roomID)
|
||||
}
|
||||
|
||||
func (h *Hall) roomController() {
|
||||
for {
|
||||
roomID := <-h.destroyCh
|
||||
h.destroyRoom(roomID)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
roomID int
|
||||
connManager *ConnManager
|
||||
mahjongManager *game.MahjongManager
|
||||
|
||||
@@ -18,11 +19,13 @@ type Room struct {
|
||||
getReadyCh chan message.GetReadyMsg
|
||||
chatCh chan message.ChatMsg
|
||||
|
||||
destroyCh chan int
|
||||
|
||||
password string
|
||||
playerCount int
|
||||
}
|
||||
|
||||
func NewRoom(rule rule.MahjongRule) *Room {
|
||||
func NewRoom(roomID int, rule rule.MahjongRule, destroyCh chan int) *Room {
|
||||
gameRecvChannel := make(chan message.GameMsgRecv)
|
||||
gameSendChannel := make(chan message.GameMsgSend)
|
||||
tableOrderChannel := make(chan int)
|
||||
@@ -31,14 +34,16 @@ func NewRoom(rule rule.MahjongRule) *Room {
|
||||
chatChannel := make(chan message.ChatMsg)
|
||||
exitChannel := make(chan bool)
|
||||
return &Room{
|
||||
roomID: roomID,
|
||||
gameRecvCh: gameRecvChannel,
|
||||
gameSendCh: gameSendChannel,
|
||||
tableOrderCh: tableOrderChannel,
|
||||
gameResultCh: gameResultChannel,
|
||||
getReadyCh: getReadyChannel,
|
||||
chatCh: chatChannel,
|
||||
connManager: NewConnManager(4, gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel, chatChannel, exitChannel),
|
||||
mahjongManager: game.NewMahjongManager(gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel, chatChannel, rule),
|
||||
destroyCh: destroyCh,
|
||||
connManager: NewConnManager(roomID, 4, gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel, chatChannel, exitChannel, destroyCh),
|
||||
mahjongManager: game.NewMahjongManager(gameRecvChannel, gameSendChannel, tableOrderChannel, gameResultChannel, getReadyChannel, chatChannel, exitChannel, rule),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-25
@@ -20,6 +20,7 @@ type MahjongManager struct {
|
||||
gameResultCh chan message.GameResultMsg
|
||||
getReadyCh chan message.GetReadyMsg
|
||||
chatCh chan message.ChatMsg
|
||||
exitCh chan bool
|
||||
|
||||
lastTableOrder int
|
||||
currentTableOrder int
|
||||
@@ -38,6 +39,7 @@ func NewMahjongManager(gameRecvCh chan message.GameMsgRecv,
|
||||
gameResultCh chan message.GameResultMsg,
|
||||
getReadyCh chan message.GetReadyMsg,
|
||||
chatCh chan message.ChatMsg,
|
||||
exitCh chan bool,
|
||||
r rule.MahjongRule) *MahjongManager {
|
||||
mahjong := MahjongManager{}
|
||||
mahjong.rules = r
|
||||
@@ -50,6 +52,7 @@ func NewMahjongManager(gameRecvCh chan message.GameMsgRecv,
|
||||
mahjong.gameResultCh = gameResultCh
|
||||
mahjong.getReadyCh = getReadyCh
|
||||
mahjong.chatCh = chatCh
|
||||
mahjong.exitCh = exitCh
|
||||
return &mahjong
|
||||
}
|
||||
|
||||
@@ -64,31 +67,38 @@ func (m MahjongManager) GetFirstPlayer() {
|
||||
|
||||
func (m *MahjongManager) gameLoop(gameRecvCh chan message.GameMsgRecv, gameSendCh chan message.GameMsgSend) {
|
||||
for {
|
||||
msg := <-gameRecvCh
|
||||
log.Printf("player:[%d], action:[%d] ", msg.TableOrder, msg.Action)
|
||||
switch msg.Action {
|
||||
case config.Start:
|
||||
//inform each player their order
|
||||
m.tableOrderCh <- m.firstPlayer
|
||||
m.handleStart()
|
||||
case config.Ready:
|
||||
m.handleReady(msg)
|
||||
case config.Discard:
|
||||
m.handleDiscard(msg, false)
|
||||
case config.Chow:
|
||||
m.handleChow(msg)
|
||||
case config.Pong:
|
||||
m.handlePong(msg)
|
||||
case config.ExposedKong:
|
||||
m.handleExposedKong(msg)
|
||||
case config.ConcealedKong:
|
||||
m.handleConcealedKong(msg)
|
||||
case config.AddedKong:
|
||||
m.handleAddedKong(msg)
|
||||
case config.Win:
|
||||
m.handleWin(msg)
|
||||
case config.Cancel:
|
||||
m.handleCancel(msg)
|
||||
select {
|
||||
case e := <-m.exitCh:
|
||||
if e {
|
||||
return
|
||||
}
|
||||
case msg := <-gameRecvCh:
|
||||
log.Printf("player:[%d], action:[%d] ", msg.TableOrder, msg.Action)
|
||||
switch msg.Action {
|
||||
case config.Start:
|
||||
//inform each player their order
|
||||
m.tableOrderCh <- m.firstPlayer
|
||||
m.handleStart()
|
||||
case config.Ready:
|
||||
m.handleReady(msg)
|
||||
case config.Discard:
|
||||
m.handleDiscard(msg, false)
|
||||
case config.Chow:
|
||||
m.handleChow(msg)
|
||||
case config.Pong:
|
||||
m.handlePong(msg)
|
||||
case config.ExposedKong:
|
||||
m.handleExposedKong(msg)
|
||||
case config.ConcealedKong:
|
||||
m.handleConcealedKong(msg)
|
||||
case config.AddedKong:
|
||||
m.handleAddedKong(msg)
|
||||
case config.Win:
|
||||
m.handleWin(msg)
|
||||
case config.Cancel:
|
||||
m.handleCancel(msg)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/c-my/MahjongServer/container"
|
||||
"github.com/c-my/MahjongServer/controller"
|
||||
"github.com/c-my/MahjongServer/rule"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"io/ioutil"
|
||||
@@ -30,8 +29,8 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func main() {
|
||||
configure := readConfig()
|
||||
room = container.NewRoom(rule.NewJinzhouRule())
|
||||
room.Start()
|
||||
//room = container.NewRoom(rule.NewJinzhouRule())
|
||||
//room.Start()
|
||||
|
||||
router := mux.NewRouter()
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@ type RoomInfoMsg struct {
|
||||
}
|
||||
|
||||
type GameResultMsg struct {
|
||||
MsgType int `json:"msg_type"`
|
||||
Winner int `json:"winner"`
|
||||
FinalTile model.Tile `json:"final_tile"`
|
||||
PlayerTile []model.PlayerTile `json:"player_tile"`
|
||||
UserList []UserInfo `json:"user_list"`
|
||||
|
||||
MsgType int `json:"msg_type"`
|
||||
Winner int `json:"winner"`
|
||||
FinalTile model.Tile `json:"final_tile"`
|
||||
PlayerTile []model.PlayerTile `json:"player_tile"`
|
||||
UserList []UserInfo `json:"user_list"`
|
||||
}
|
||||
|
||||
type GetReadyMsg struct {
|
||||
|
||||
Reference in New Issue
Block a user