package game import ( "sync" "time" "github.com/wonderivan/logger" ) type Room struct { //房间ID,目前没啥用,就是方便打印查看 ID int //入房钥匙 EnterKey string //玩家列表 PlayerList []*Player } var staticRoomMapLocker sync.RWMutex var staticRoomMap = make(map[string]*Room) //进入房间 func EnterRoom(player *Player, enterKey string) { staticRoomMapLocker.Lock() defer staticRoomMapLocker.Unlock() needCreateRoom := false room := staticRoomMap[enterKey] if room == nil { needCreateRoom = true } else if room != nil { needCreateRoom = room.IsFullMembers() } if needCreateRoom { room = &Room{ID: GetUuidInt("Room"), EnterKey: enterKey, PlayerList: []*Player{player, nil}} go room.AutoCheck() staticRoomMap[enterKey] = room logger.Info("roomID:", room.ID, "Create", "EnterKey:", room.EnterKey) player.OnEnterRoom(room) } else { room.PlayerList[1] = player player.OnEnterRoom(room) room.OnRoomReadyComplete() } } //开启检测-主要为了自动销毁 func (room *Room) AutoCheck() { defer room.CloseAllPlayers() defer func() { staticRoomMapLocker.Lock() if staticRoomMap[room.EnterKey] == room { delete(staticRoomMap, room.EnterKey) } staticRoomMapLocker.Unlock() logger.Info("roomID:", room.ID, "Destroy") }() loopInterval := 2 waitTime := 0 for { time.Sleep(time.Duration(loopInterval) * time.Second) if room.IsFullMembers() { if !room.IsAllMembersValid() { break } } else { waitTime += loopInterval if waitTime >= 30 { break } } } } //判断房间的人数是否已满 func (room *Room) IsFullMembers() bool { for _, p := range room.PlayerList { if p == nil { return false } } return true } //判断房间内是由所有玩家都有效 func (room *Room) IsAllMembersValid() bool { for _, p := range room.PlayerList { if !p.IsValid { return false } } return true } //关闭所有玩家连接 func (room *Room) CloseAllPlayers() { for _, p := range room.PlayerList { if p != nil { p.Conn.Close() } } } //广播到其他人 func (room *Room) BroadcastToOthers(player *Player, func_ string, args ...interface{}) { for _, p := range room.PlayerList { if p != nil && p != player { SendPackFunction(p.Conn, func_, args...) } } } //广播到全部人 func (room *Room) BroadcastToAll(func_ string, args ...interface{}) { for _, p := range room.PlayerList { if p != nil { SendPackFunction(p.Conn, func_, args...) } } } //向客户端发送的请求 //房间准备完毕,即房间内的玩家都准备好了,接到该通知就可以开始游戏啦 func (room *Room) OnRoomReadyComplete() { for playerIndexInRoom, p := range room.PlayerList { SendPackFunction(p.Conn, "OnRoomReadyComplete", playerIndexInRoom) } logger.Info("roomID:", room.ID, "OnRoomReadyComplete") }