package Module

import (
	"Server-Core/Server/GameServer/Server/PlaneGame/Utils"
	message "Server-Core/Server/Message"
	"encoding/json"

	"strconv"
	"sync"
	"time"

	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/golang/protobuf/proto"
	"github.com/gorilla/websocket"
	log "github.com/sirupsen/logrus"

	rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
)

type GamePlayer struct {
	Ticker         *time.Ticker
	Id             string
	Name           string
	HeadImg        string
	Uid            string
	GamePlane      []*GamePlane
	GamePlaneIndex []int
	GameRoom       *GameRoom
	GameRoomId     int    //上一把的房间id
	Status         uint32 // 玩家的当前状态, 0、大厅，1 表示匹配，2: 进入房间已落座, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开，7: 组队逃跑，8: 逃跑,9托管状态,10观战,11进房未落座,12已建房，未拉取房间信息,13结算待退出,14已开游戏未进房
	Num            int    //代表当前第几轮
	SeatId         uint32
	NumberOfRounds []*GameNumberOfRounds
	Money          uint32    //金额
	Kick           uint32    //撞棋数
	BeKick         uint32    //被撞棋数
	FinishNum      uint32    //到达终点数
	LastHeartbeat  time.Time //最后一次心跳时间
	PlayerNum      uint32    //玩家人数
	//Status2        uint32    // 玩家的当前状态, 1代表没有开启任何房间，2在匹配中，3是在房间内
	MaxNum       int    //最大房间人数
	Mode         int    //游戏模式
	AdmissionFee uint32 //入场费
	RoomType     int
}

// 根据uid查询websocket连接信息
var UserClientIds map[string]*websocket.Conn = make(map[string]*websocket.Conn)

// 根据websocket连接信息查询uid
var ClientUserIds map[*websocket.Conn]string = make(map[*websocket.Conn]string)
var GamePlayers = make(map[string]*GamePlayer)

// 飞机
type GamePlane struct {
	Id          string
	CurPosIndex uint32
	IsFly       int //0代表未起飞,1已经起飞，2到达终点
	Uid         string
}
type GameNumberOfRounds struct {
	Num            int
	NumberOfRounds []*uint32
}
type RequestUserData struct {
	Data []GamePlayer `json:"data"`
}

// 根据seatId获取房间内对应玩家
func getPlayerBySeatId(seatId uint32, room *GameRoom) *GamePlayer {
	//	uid := clientUserIds[ws]
	for _, value := range room.Players {
		log.Info("每一个人的seatId", value.SeatId)
		if seatId == value.SeatId {
			return value
		}
	}
	return nil
	//return room.Players[int(seatId)]
}

// 根据uid获取房间内对应玩家
func getPlayer(uid string) *GamePlayer {
	return GamePlayers[uid]
}

func getNextSeatId(seatId uint32, room *GameRoom) uint32 {
	// if seatId < uint32(room.StartPlayerNum-1) {
	// 	seatId = seatId + 1
	// } else {
	// 	seatId = 0
	// }
	// for _, value := range room.Players {

	// 	if value.SeatId == seatId {
	// 		if value.Status == uint32(message.GameStatus_Player_Status_5) || value.Status == uint32(message.GameStatus_Player_Status_6) || value.Status == uint32(message.GameStatus_Player_Status_8) || value.Status == 0 {
	// 			seatId = getNextSeatId(seatId, room)
	// 			break
	// 		} else {
	// 			{
	// 				return seatId
	// 			}
	// 		}
	// 	}
	// }
	if seatId == 0 {
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 1 {
					return 1
				}
			}

		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 2 {
					return 2
				}
			}

		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 3 {
					return 3
				}
			}

		}

	} else if seatId == 1 {
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 2 {
					return 2
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 3 {
					return 3
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 0 {
					return 0
				}
			}
		}
	} else if seatId == 2 {
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 3 {
					return 3
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 0 {
					return 0
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 1 {
					return 1
				}
			}
		}
	} else if seatId == 3 {
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 0 {
					return 0
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 1 {
					return 1
				}
			}
		}
		for _, v := range room.Players {
			if v.Status == 3 || v.Status == 9 {
				if v.SeatId == 2 {
					return 2
				}
			}
		}
	}

	return seatId

}

// 返回玩家数据，等待玩家准备完毕
func GetUserInfo(ws *websocket.Conn, data []byte) {

	var uid = ClientUserIds[ws]
	req := &message.GetUserInfoReq{}
	proto.Unmarshal(data, req)
	rsp := &message.GetUserInfoRsp{}
	errcode := uint32(message.GameStatus_GAME_STATUS_OK)
	rsp.Result = &errcode
	log.Info("获取用户数据", uid)
	//测试期间：没有账号则创建账号和密码，有账号则验证密码
	//先验证账号不能为空
	lock4.Lock()
	//gameplayer := getPlayer(req.Uid)
	//	gameplayer := GamePlayers[req.Uid]
	if len(uid) == 0 {
		room := gameRooms[int(req.RoomId)]
		//加入观战玩家
		UserClientIds[uid] = ws
		ClientUserIds[ws] = uid
		var gameplayer = &GamePlayer{}

		gameplayer.Uid = uid

		//room := gameRooms[int(gameplayer.GameRoom.Id)]
		if room.GameEnd == 1 {
			//userRoom[req.Uid] = room

			//查看房间人数
			var names = []string{}
			var headImg = []string{}
			var uids = []string{}
			var seatId = []uint32{}
			var playerStatus = []uint32{}

			players := room.Players

			for i := 0; i < len(players); i++ {
				if players[i] != nil {
					if players[i].Status == 3 || players[i].Status == 9 {
						names = append(names, players[i].Name)
						headImg = append(headImg, players[i].HeadImg)
						uids = append(uids, players[i].Uid)
						seatId = append(seatId, players[i].SeatId)
						playerStatus = append(playerStatus, players[i].Status)
					}
				}

			}
			rsp.Nick = names
			rsp.HeadUrl = headImg
			rsp.PlayerID = uids
			rsp.SeatID = seatId
			rsp.PlayerStatus = playerStatus
			rsp.PlayerNum = uint32(len(players))
			room.GzPlayers = append(room.GzPlayers, gameplayer)
			var i = uint32(len(room.GzPlayers))
			rsp.WatchingPlayers = &i
			rsp.GameType = uint32(room.Mode)
			rData, _ := proto.Marshal(rsp) //回包
			log.Info("返回用户信息", rsp)
			sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
			
			gameplayer.Status = uint32(message.GameStatus_Player_Status_10)
			var playnum uint32 = uint32(len(players))

		rsp2 := &message.JoinRoomInfoRsp{Nick: gameplayer.Name, HeadUrl: gameplayer.HeadImg, PlayerID: gameplayer.Uid, SeatID: &gameplayer.SeatId, PlayerStatus: gameplayer.Status, PlayerNum: &playnum}
		log.Info("通知到玩家加入房间", rsp2)
		rData2, _ := proto.Marshal(rsp2) //回包
		for _, value := range players {
			if value.Uid != gameplayer.Uid {
				if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
					sendData(UserClientIds[value.Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
				}
			}
		}

		for j := 0; j < len(room.GzPlayers); j++ {
			if room.GzPlayers[j].Uid != gameplayer.Uid {
				//
				//if room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_3) || room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_10) {
					sendData(UserClientIds[room.GzPlayers[j].Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
			//	}
			}
		}
		} else {
			//返回倒计时
			room.GzPlayers = append(room.GzPlayers, gameplayer)
			//查看房间人数
			var names = []string{}
			var headImg = []string{}
			var uids = []string{}
			var seatId = []uint32{}
			var playerStatus = []uint32{}

			players := room.Players

			for i := 0; i < len(players); i++ {
				if players[i] != nil {
					if players[i].Status == 3 {
						names = append(names, players[i].Name)
						headImg = append(headImg, players[i].HeadImg)
						uids = append(uids, players[i].Uid)
						seatId = append(seatId, players[i].SeatId)
						playerStatus = append(playerStatus, players[i].Status)
					}
				}

			}
			rsp.Nick = names
			rsp.HeadUrl = headImg
			rsp.PlayerID = uids
			rsp.SeatID = seatId
			rsp.PlayerStatus = playerStatus
			rsp.PlayerNum = uint32(len(players))
			var time uint32 = 10
			rsp.Countdown = &time
			rsp.GameType = uint32(room.Mode)
			var i = uint32(len(room.GzPlayers))
			rsp.WatchingPlayers = &i
			rData, _ := proto.Marshal(rsp) //回包
			log.Info("返回用户信息", rsp)
			sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
		}
		
	} else {
		gameplayer := GamePlayers[uid]
		//查看房间人数
		//room := userRoom[gameplayer.Uid]

		room := gameplayer.GameRoom
		//room := gameRooms[int(req.RoomId)]
		var names = []string{}
		var headImg = []string{}
		var uids = []string{}
		var seatId = []uint32{}
		var playerStatus = []uint32{}

		players := room.Players

		for _, value := range room.Players {
			log.Info("uid", uid)
			log.Info("players[i].Uid", value.Uid)
			if value.Uid == uid {
				//如果是没有准备第一次进入房间，则会更新玩家座位号，如果是掉线重连
				//if value.Status == uint32(message.GameStatus_Player_Status_2) || value.Status == uint32(message.GameStatus_Player_Status_1) {
				if value.Status ==14 {
					gameplayer.Status = uint32(message.GameStatus_Player_Status_3)

					log.Print("获取room.PlayerNum", room.PlayerNum)
					//seatId 0 1 2
					gameplayer.SeatId = uint32(room.PlayerNum)
					room.PlayerNum = room.PlayerNum + 1

					//lock.Unlock()
					if len(players) == 2 {
						if gameplayer.SeatId == 0 {
							gameplayer.GamePlaneIndex = Maps[0]
						} else if gameplayer.SeatId == 1 {
							gameplayer.GamePlaneIndex = Maps[2]
						}
					} else if len(players) == 3 {
						if gameplayer.SeatId == 0 {
							gameplayer.GamePlaneIndex = Maps[0]
						} else if gameplayer.SeatId == 1 {
							gameplayer.GamePlaneIndex = Maps[1]
						} else if gameplayer.SeatId == 2 {
							gameplayer.GamePlaneIndex = Maps[2]
						}
					} else if len(players) == 4 {
						if gameplayer.SeatId == 0 {
							gameplayer.GamePlaneIndex = Maps[0]
						} else if gameplayer.SeatId == 1 {
							gameplayer.GamePlaneIndex = Maps[1]
						} else if gameplayer.SeatId == 2 {
							gameplayer.GamePlaneIndex = Maps[2]
						} else if gameplayer.SeatId == 3 {
							gameplayer.GamePlaneIndex = Maps[3]
						}
					}

				}
			}

			if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
				names = append(names, value.Name)
				headImg = append(headImg, value.HeadImg)
				uids = append(uids, value.Uid)
				seatId = append(seatId, value.SeatId)
				playerStatus = append(playerStatus, value.Status)
			}
		}
		rsp.Nick = names
		rsp.HeadUrl = headImg
		rsp.PlayerID = uids
		rsp.SeatID = seatId
		if gameplayer.Status == 3 {
			rsp.SelfSeatId = &gameplayer.SeatId
		}
//添加观战玩家
if gameplayer.Status == 10 {
	room.GzPlayers = append(room.GzPlayers, gameplayer)
}
		rsp.PlayerStatus = playerStatus
		rsp.PlayerNum = uint32(len(players))
		var i = uint32(len(room.GzPlayers))
		rsp.WatchingPlayers = &i
		rsp.GameType = uint32(room.Mode)
		rData, _ := proto.Marshal(rsp) //回包
		log.Info("返回用户信息", rsp)
		sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
		

	
		//广播除本人外的所有在线用户加入房间
		var playnum uint32 = uint32(len(players))

		rsp2 := &message.JoinRoomInfoRsp{Nick: gameplayer.Name, HeadUrl: gameplayer.HeadImg, PlayerID: gameplayer.Uid, SeatID: &gameplayer.SeatId, PlayerStatus: gameplayer.Status, PlayerNum: &playnum}
		log.Info("通知到玩家加入房间", rsp2)
		rData2, _ := proto.Marshal(rsp2) //回包

		for _, value := range players {
			if value.Uid != gameplayer.Uid {
				if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
					sendData(UserClientIds[value.Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
				}
			}
		}

		for j := 0; j < len(room.GzPlayers); j++ {
			if room.GzPlayers[j].Uid != gameplayer.Uid {
				//if room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_3) || room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_10) {
					sendData(UserClientIds[room.GzPlayers[j].Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
			//	}
			}
		}
		
		log.Print("加入房间的人数", len(room.Players))
		log.Info("加入房间的观战人数", len(room.GzPlayers))
		//log.Info("房间内的人数", len(room.Players))

		if room.PlayerNum == room.StartPlayerNum {
			//没有开始游戏才会开始游戏
			if room.GameEnd == GameNotStarted {
				for _, value := range room.Players {
					//初始化飞机
					var plane = []*GamePlane{}
					for j := 0; j < 4; j++ {
						gamePlane := createPlane(j, value.Uid)
						plane = append(plane, &gamePlane)
					}
					value.GamePlane = plane
				}

				log.Info("广播开始游戏")
				room.GameEnd = GamePlaying
				//玩家都准备完毕了就可以游戏
				if room.ticker != nil {
					room.ticker.Stop()
				}

				nextplayer := getPlayerBySeatId(0, room)
				broadInfoSz(nextplayer)
			}
		}

	}
	lock4.Unlock()
}

// var lock sync.Mutex
var lock4 sync.Mutex

// 返回玩家数据，等待玩家准备完毕

func createPlayer(i int, plane []*GamePlane, data []GamePlayer, room *GameRoom) GamePlayer {
	var gamePlayer = GamePlayer{}
	gamePlayer.GamePlane = plane
	gamePlayer.GameRoom = room
	//gamePlayer.Id = strconv.Itoa(i)
	gamePlayer.Uid = data[i].Uid
	gamePlayer.Name = data[i].Name
	gamePlayer.HeadImg = data[i].HeadImg
	gamePlayer.Status = uint32(0)
	//gamePlayer.SeatId = uint32(i)
	gamePlayer.Money = data[i].Money
	gamePlayer.FinishNum = 0
	gamePlayer.Num = 0
	var rounds = []*GameNumberOfRounds{}
	var num *GameNumberOfRounds = new(GameNumberOfRounds)
	var nums = []*uint32{}
	(*num).Num = 0
	(*num).NumberOfRounds = nums
	rounds = append(rounds, num)
	gamePlayer.NumberOfRounds = rounds
	return gamePlayer
}
func createPlayer2(uid string, ws *websocket.Conn,url string,name string, money uint32) *GamePlayer {
	var gamePlayer = GamePlayer{}

	//gamePlayer.GameRoom = room
	//gamePlayer.Id = strconv.Itoa(i)
	gamePlayer.Uid = uid
	uid2, _ := strconv.Atoi(uid)
	//userrsp := Utils.GetUserInfoData(uid2)
	userrsp := Utils.GetFbData(uid2,url,name,money)
	log.Printf("查看返回值", userrsp)
	
	if userrsp.Code != 200 {
		BroadErrorMsg("没有该玩家信息", ws)
		return nil
	} else {
		gamePlayer.Name = userrsp.Data[0].NickName
		gamePlayer.HeadImg = userrsp.Data[0].Avatar
		gamePlayer.Money = uint32(userrsp.Data[0].GoldCoins)
	}
	//log.Printf("查询到的玩家信息", userrsp.Data[0])

	gamePlayer.Status = uint32(0)
	//gamePlayer.SeatId = uint32(i)
	//gamePlayer.Status2 = uint32(PlayerIdle)
	gamePlayer.FinishNum = 0
	gamePlayer.Num = 0

	var rounds = []*GameNumberOfRounds{}
	var num *GameNumberOfRounds = new(GameNumberOfRounds)
	var nums = []*uint32{}
	(*num).Num = 0
	(*num).NumberOfRounds = nums
	rounds = append(rounds, num)
	gamePlayer.NumberOfRounds = rounds
	GamePlayers[gamePlayer.Uid] = &gamePlayer
	return &gamePlayer
}
func resetPlayer(gamePlayer *GamePlayer) int {

	//gamePlayer.GameRoom = room
	//gamePlayer.Id = strconv.Itoa(i)

	uid2, _ := strconv.Atoi(gamePlayer.Uid)
	userrsp := Utils.GetUserInfoData(uid2)
	if userrsp.Code != 200 {
		log.Printf("没有玩家信息")

		//return nil
		//gamePlayers[gamePlayer.Uid]=nil
		delete(GamePlayers, gamePlayer.Uid)
		return 666
	}
	log.Printf("查询到的玩家信息", userrsp.Data[0])
	gamePlayer.Name = userrsp.Data[0].NickName
	gamePlayer.HeadImg = userrsp.Data[0].Avatar
	gamePlayer.Money = uint32(userrsp.Data[0].GoldCoins)
	gamePlayer.Status = uint32(message.GameStatus_Player_Status_1)
	//gamePlayer.SeatId = uint32(i)
	//gamePlayer.Status2 = uint32(PlayerIdle)
	gamePlayer.FinishNum = 0
	gamePlayer.Num = 0

	var rounds = []*GameNumberOfRounds{}
	var num *GameNumberOfRounds = new(GameNumberOfRounds)
	var nums = []*uint32{}
	(*num).Num = 0
	(*num).NumberOfRounds = nums
	rounds = append(rounds, num)
	gamePlayer.NumberOfRounds = rounds
	return 200
	//gamePlayers[gamePlayer.Uid] = &gamePlayer
	//return &gamePlayer
}

// 用户登录 建立socket连接
func Login(ws *websocket.Conn, data []byte) {
	/*req := &message.UserInfoReq{}
	proto.Unmarshal(data, req) //解包
	userClientIds[req.Uid] = ws
	clientUserIds[ws] = req.Uid
	var gamePlayer = GamePlayer{Uid: req.Uid, Name: req.Name, HeadImg: req.HeadImg, Money: req.Money}
	gamePlayers[req.Uid] = &gamePlayer*/
	//需要携带房间号，如果有的话说明在一个房间，
	//玩家

}

// 确认一下对接方式
// 语聊房客户端直接传输roomId给游戏服务器，然后就
// 根据窗口id 找到对应的窗口
// 玩家根据游戏窗口加入窗口进行广播
// 携带窗口id和uid
func JoinRoomReq(ws *websocket.Conn, data []byte) {
	//语聊房携带id加入游戏房间
	//uid := clientUserIds[ws]
	req := &message.JoinRoomReq{}
	proto.Unmarshal(data, req) //解包
	log.Println("获取请求的参数", req)
	JoinRoom(req.Uid, int(*req.RoomId), ws)
}

func JoinRoom(uid string, roomId int, ws *websocket.Conn) {
	var player = GamePlayers[uid]
	//log.Info("uid", req.Uid)

	//gamePlayer :
	room := gameRooms[roomId]
	if room == nil {
		BroadErrorMsg("房间不存在，无法加入", ws)
		return
	} else {
		if room.Status == RoomIdle {
			BroadErrorMsg("房间还没开，不能使用", ws)
			return
		}
	}

	if player == nil {

		player = createPlayer2(uid, ws,"","",0)
		if nil == player {
			BroadErrorMsg("没有该玩家信息", ws)
			return
		}

	} else {
		if player.Status != 10 {
			BroadErrorMsg("玩家未拉取房间信息", ws)
			return
			// for _, player2 := range room.Players {
			// 	if player2.Uid == player.Uid {
			// 		BroadErrorMsg("已加入游戏不能创建游戏房间", ws)
			// 		return
			// 	}

			// }

		}

	}
	lock6.Lock()
	room.RoomPlayers[player.Uid] = player
	// ClientUserIds[ws] = req.Uid
	// UserClientIds[req.Uid] = ws
	//gamePlayer.Uid = req.Uid
	rsp4 := &message.JoinRoomInfoRsp{}
	if len(room.Players) < room.MaxNum {

		var canjoin = true
		for _, value := range room.Players {
			log.Printf("查看房间内剩余玩家", value.Uid)
			if value.Uid == uid {
				//已加入不能重复加入
				canjoin = false
			}
		}
		if canjoin {
			log.Print("加入玩家", player.Uid)

			 if player.Money<room.AdmissionFee{
			 	BroadErrorMsg("金币不足",ws)
			 	return
			 }
			//delete(room.GzPlayers,player)

			player.GameRoom = room
			player.AdmissionFee = room.AdmissionFee
			player.MaxNum = room.MaxNum
			player.Mode = room.Mode
			player.Status = uint32(message.GameStatus_Player_Status_2)
			player.FinishNum = 0
			player.Num = 0
			var rounds = []*GameNumberOfRounds{}
			var num *GameNumberOfRounds = new(GameNumberOfRounds)
			var nums = []*uint32{}
			(*num).Num = 0
			(*num).NumberOfRounds = nums
			rounds = append(rounds, num)
			player.NumberOfRounds = rounds
			//	player.GameRoom = room
			Rcfcz(player.Uid, room.AdmissionFee, 2)
			//broadRoomInfo(room, ws)
			room.RoomPlayers[player.Uid] = player
			if room.Players[0] == nil {
				room.Players[0] = player
				var seat uint32 = 0
				rsp4.SeatID = &seat
			} else if room.Players[1] == nil {
				room.Players[1] = player
				var seat uint32 = 1
				rsp4.SeatID = &seat
			} else if room.Players[2] == nil {
				room.Players[2] = player
				var seat uint32 = 2
				rsp4.SeatID = &seat
			} else if room.Players[3] == nil {
				room.Players[3] = player
				var seat uint32 = 3
				rsp4.SeatID = &seat
			}

		} else {

			BroadErrorMsg("该玩家已加入", ws)
			lock6.Unlock()
			return

		}

	}
	// else {
	// 	//broadRoomInfo(room, ws)
	// 	log.Info("加入观战玩家")
	// 	room.RoomPlayers[player.Uid] = player
	// 	player.GameRoom = room
	// 	player.Status = uint32(message.GameStatus_Player_Status_10)
	// 	room.GzPlayers = append(room.GzPlayers, player)
	// 	//BroadErrorMsg("人数已满，不能加入", ws)
	// 	lock6.Unlock()
	// 	return
	// }

	//broadInfo(player.GameRoom, int16(message.MSGID_Room_User_Info_Rsp), rData)
	//广播新玩家加入
	ClientUserIds[ws] = uid
	UserClientIds[uid] = ws

	rsp4.PlayerID = player.Uid
	rsp4.Nick = player.Name
	rsp4.HeadUrl = player.HeadImg

	rData4, _ := proto.Marshal(rsp4) //回包
	log.Info("广播玩家加入", rsp4)
	BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Join_User_Rsp), rData4)
	//如果房间是匹配模式满人则直接开始游戏
	if player.GameRoom.Mode == ModeMatch {

		if len(room.Players) == room.MaxNum {
			uid := strconv.Itoa(room.Homeowner)
			for i := 0; i < len(MatchGameplayers); i++ {
				if uid == MatchGameplayers[i].Uid {
					MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
					MatchGameplayers = append(MatchGameplayers[:i], MatchGameplayers[i+1:]...)

					rsp3 := &message.RoomStartGameRsp{}
					rData3, _ := proto.Marshal(rsp3) //回包
					log.Info("广播开始玩游戏")
					BroadInfoRoom(room, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
					//Utils.ChatRoomBroadcast(room.Id, 2, 1, room.Id)
					go countdonw2(player, 1)
					break
				}

			}

		}
	}
	lock6.Unlock()
}

// 游戏restart 按钮
func RoomRestartReq(ws *websocket.Conn, data []byte) {

	//req := &message.RoomInfoReq{}
	player := GamePlayers[ClientUserIds[ws]]
	// for key, player2 := range player.GameRoom.Players {
	// 	if player2.Uid == player.Uid {
	// 		delete(player.GameRoom.Players, key)
	// 	}
	// }
	//delete(player.GameRoom.RoomPlayers, player.Uid)
	//player.GameRoom = nil

	//log.Info("room====", room.Mode)

	if nil != player {
		if player.Status !=0 {

			BroadErrorMsg("该玩家已经在匹配或者已开房", ws)
			return
		}

	} else {
		BroadErrorMsg("没有该玩家信息", ws)
		return
	}

	if player.Money < player.AdmissionFee {
		BroadErrorMsg("该玩家入场费不足", ws)
		return
	}
	//Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
	lock3.Lock()
	player.LastHeartbeat=time.Now()
	//如果是房间内房主开启就拉人
	if player.Mode == ModeClass {
		//player.Status2 = uint32(PlayerRooming)
		//	player.Status = uint32(message.GameStatus_Player_Status_2)
		room := gameRooms[player.GameRoomId]
		// if room.RoomType == RoomIn {
		// 	uid, _ := strconv.Atoi(player.Uid)
		// 	if room.Homeowner == uid {
		// 		//如果是房主点的restart 会重新拉人 ,重新加入游戏房间
		// 		result := Utils.ChatRoomBroadcast(room.ChatRoomId, BroadcastInvisit, room.Id)
		// 		if result.Code != 200 {
		// 			log.Printf("发送邀请失败，通知客户端再发起邀请")
		// 		}
		// 	}

		// }
		log.Printf("进入了经典模式")
		//通知到返回房间信息
		GamePlayers[ClientUserIds[ws]].Status = 10

		broadRoomInfo(room, ws)
		var uid = strconv.Itoa(room.Homeowner)
		if uid != player.Uid {
			JoinRoom(player.Uid, player.GameRoomId, ws)
		} else {
			Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
			GamePlayers[ClientUserIds[ws]].Status = 2
			GamePlayers[ClientUserIds[ws]].GameRoom = room
			GamePlayers[ClientUserIds[ws]].AdmissionFee = room.AdmissionFee
			GamePlayers[ClientUserIds[ws]].MaxNum = room.MaxNum
			GamePlayers[ClientUserIds[ws]].Mode = room.Mode
			//GamePlayers[ClientUserIds[ws]].Status = uint32(message.GameStatus_Player_Status_2)
			GamePlayers[ClientUserIds[ws]].FinishNum = 0
			GamePlayers[ClientUserIds[ws]].Num = 0
			var rounds = []*GameNumberOfRounds{}
			var num *GameNumberOfRounds = new(GameNumberOfRounds)
			var nums = []*uint32{}
			(*num).Num = 0
			(*num).NumberOfRounds = nums
			rounds = append(rounds, num)
			GamePlayers[ClientUserIds[ws]].NumberOfRounds = rounds
		}
		//room := player.GameRoom

	} else if player.Mode == ModeMatch {
		log.Printf("进入了匹配模式")
		match(player, ws, int(player.AdmissionFee), player.MaxNum)
	}
	lock3.Unlock()
}

func match(player *GamePlayer, ws *websocket.Conn, adminfee int, playernum int) {
	// 重新匹配
	log.Info("进入匹配模式")

	// 判断是否没有玩家已经开房，判断开了房是否能开始游戏
	lock2.Lock()
	var roomCreated = false
	//Rcfcz(player.Uid, uint32(adminfee), 2)
	for i := 0; i < len(MatchGameplayers); i++ {

		if MatchGameplayers[i].AdmissionFee == uint32(adminfee) && playernum == int(MatchGameplayers[i].MaxNum) {
			//如果房间满了就开始游戏
			//player.Status = uint32(message.GameStatus_Player_Status_2)
			player.Status = uint32(message.GameStatus_Player_Status_1)
			MatchGameplayers = append(MatchGameplayers, player)
			//如果匹配金额相同 并且玩家人数相同就进入游戏对战
			roomCreated = true
			//移出次玩家
			room := MatchGameplayers[i].GameRoom
			player.GameRoom = room
			room.RoomPlayers[player.Uid] = player
			//	userRoom[req.Uid] = room

			//匹配成功会加入房间

			if room.Players[0] == nil {
				player.SeatId = 0
				room.Players[0] = player
			} else if room.Players[1] == nil {
				player.SeatId = 1
				room.Players[1] = player
			} else if room.Players[2] == nil {
				player.SeatId = 2
				room.Players[2] = player
			} else if room.Players[3] == nil {
				player.SeatId = 3
				room.Players[3] = player
			}
			broadRoomInfo(room, ws)
			//广播新玩家加入
			rsp4 := &message.RoomJoinUserRsp{}
			rsp4.PlayerID = player.Uid
			rsp4.Nick = player.Name
			rsp4.HeadUrl = player.HeadImg
			rsp4.SeatID = player.SeatId
			log.Print("回传数据====", rsp4)
			rData4, _ := proto.Marshal(rsp4) //回包

			broadInfoExceptUid(room, int16(message.MSGID_Room_Join_User_Rsp), rData4, player.Uid)
			//BroadInfoRoom(room, int16(message.MSGID_Room_Join_User_Rsp), rData4)

			log.Info("room.MaxNum", room.MaxNum)
			log.Info("len====", len(room.Players))
			if len(room.Players) == room.MaxNum {
				log.Info("开始清除匹配信息")
				player.GameRoom.ticker.Stop()
				for _, player := range room.Players {
					for j := 0; j < len(MatchGameplayers); j++ {
						if player.Uid == MatchGameplayers[j].Uid {
							//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
							MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
						}
					}

				}

				time.Sleep(2 * time.Second)
				for _, v := range player.GameRoom.Players {
					v.Status=14
			//	for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
				// 		if player.GameRoom.GzPlayers[i].Uid == v.Uid {
				// 			player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)
				// 			//MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
				// 		}
				// 	}
				 }
				rsp3 := &message.RoomStartGameRsp{}
				rData3, _ := proto.Marshal(rsp3) //回包
				log.Info("广播开始玩游戏")
				room.StartPlayerNum = len(room.Players)
				go countdonw2(player, 2)
				BroadInfo(room, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
				result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
				if result.Code != 200 {
					log.Printf("通知语聊房开始游戏失败")
				}

			}
			break

		}
	}
	log.Info("roomCreated====", roomCreated)
	if !roomCreated {
		//如果没有匹配到房间就自己开房
		// result := rcfcz(player.Uid, uint32(adminfee), Reduce)
		// if result != 200 {
		// 	BroadErrorMsg("入场费不足，不能进入房间", ws)
		// 	lock2.Unlock()
		// 	return
		// }
		//userRoom[req.Uid] = idleRoom
		player.Status = uint32(message.GameStatus_Player_Status_1)
		MatchGameplayers = append(MatchGameplayers, player)
		//player.GameRoom.Players = append(player.GameRoom.Players, player)
		room := GetIdleRoom(uint32(adminfee), playernum, ModeMatch)
		player.SeatId = 0
		room.RoomType = RoomOut
		player.GameRoom = room
		//	uuid, _ := strconv.Atoi(player.Uid)
		//room.RoomPlayers=append(room.RoomPlayers,player)
		room.RoomPlayers[player.Uid] = player
		//room.Homeowner = uuid
		//idleRoom.Players = append(idleRoom.Players, player)
		if room.Players[0] == nil {
			room.Players[0] = player
		} else if room.Players[1] == nil {
			room.Players[1] = player
		} else if room.Players[2] == nil {
			room.Players[2] = player
		} else if room.Players[3] == nil {
			room.Players[3] = player
		}
		// rsp3 := &message.MatchRsp{}
		// var success uint32 = 0
		// rsp3.Result = &success
		// rData3, _ := proto.Marshal(rsp3) //回包
		// log.Info("广播开始匹配")
		// //BroadInfo(room, int16(message.MSGID_Match_Rsp), rData3)
		// sendData(ws, int16(message.MSGID_Match_Rsp), rData3)
		// broadRoomInfo(room, ws)
		// rsp3 := &message.CreateGameRsp{}
		// var rid uint32 = uint32(room.Id)
		// rsp3.RoomId = &rid
		// rData3, _ := proto.Marshal(rsp3) //回包
		// sendData(ws, int16(message.MSGID_Create_Game_Rsp), rData3)
		broadRoomInfo(room, ws)

		go countdonw3(player.Uid, uint32(room.Id))
	}
	// 15046  149946
	lock2.Unlock()
}

// 查看房间信息
func RoomInfoReq(ws *websocket.Conn, data []byte) {
	req := &message.RoomInfoReq{}

	proto.Unmarshal(data, req) //解包
	log.Printf("roomId====", req)
	var room = gameRooms[int(*req.RoomId)]
	if room == nil {
		BroadErrorMsg("没有该房间信息", ws)
		return
	}
	if room.Status == 1 {
		BroadErrorMsg("该房间还不能使用", ws)
		return
	}
	// //回传玩家信息
	var player = GamePlayers[req.Uid]
	if player == nil {
		log.Printf("建立了新玩家")
		player = createPlayer2(req.Uid, ws,"","",0)
		if nil == player {
			//BroadErrorMsg("没有该玩家信息", ws)
			return
		}
	}
	log.Print("status====", player.Status)
	if player.Status != 0 && player.Status != 12 {
		log.Print("status====", player.Status)
		BroadErrorMsg("该玩家已经加入房间", ws)
		return
	}
	player.GameRoom = room
	player.Status = 10
	player.LastHeartbeat=time.Now()
	log.Print("status2====", player.Status)
	UserClientIds[player.Uid] = ws
	ClientUserIds[ws] = player.Uid
	room.RoomPlayers[player.Uid] = player

	broadRoomInfo(room, ws)

}

func broadRoomInfo(room *GameRoom, ws *websocket.Conn) {
	//回传玩家信息
	var uids = []string{}
	var names = []string{}
	var headImg = []string{}
	var moneys = []uint32{}
	var seatId = []uint32{}

	for i := 0; i < 4; i++ {
		if room.Players[i] != nil {
			if room.Players[i].Ticker != nil {
				//room.Players[i].Ticker.Stop()

			}
			uids = append(uids, room.Players[i].Uid)
			names = append(names, room.Players[i].Name)
			headImg = append(headImg, room.Players[i].HeadImg)
			moneys = append(moneys, room.Players[i].Money)
			seatId = append(seatId, uint32(i))
		}

	}
	// for _, value := range room.Players {

	// }
	rsp := &message.RoomInfoRsp{}
	rsp.Money = moneys
	rsp.PlayerID = uids
	rsp.Nick = names
	rsp.HeadUrl = headImg
	rsp.SeatId = seatId
	rsp.AdmissionFee = room.AdmissionFee
	rsp.PlayerNum = uint32(room.MaxNum)
	rsp.Mode = uint32(room.Mode)
	rData, _ := proto.Marshal(rsp) //回包
	log.Info("回传房间信息", rsp)
	//MSGID_Room_Info_Rsp
	sendData(ws, int16(message.MSGID_Room_Info_Rsp), rData)
}

// 开始游戏通知客户端
func RoomStartGameReq(ws *websocket.Conn, data []byte) {

	uid := ClientUserIds[ws]
	player := GamePlayers[uid]
	if player.GameRoom==nil{
		BroadErrorMsg("游戏房间没有", ws)
		return
	}
	if len(player.GameRoom.Players) < player.GameRoom.MinNum {
		BroadErrorMsg("一个人不能游戏", ws)
		return
	} else if len(player.GameRoom.Players) > player.GameRoom.MaxNum {
		BroadErrorMsg("不能超过房间人数", ws)
		return
	} else {
		player.LastHeartbeat=time.Now()
		req := &message.RoomStartGameRsp{}
		rData, _ := proto.Marshal(req) //回包
		log.Info("广播开始玩游戏", player.GameRoom.Players)
		player.GameRoom.StartPlayerNum = len(player.GameRoom.Players)
		for _, v := range player.GameRoom.Players {
			v.Status=14
	//	for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
		// 		if player.GameRoom.GzPlayers[i].Uid == v.Uid {
		// 			player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)
		// 			//MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
		// 		}
		// 	}
		 }
		go countdonw2(player, 3)
		

		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Start_Game_Rsp), rData)
		// result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
		// if result.Code != 200 {
		// 	log.Printf("通知语聊房开始游戏失败")
		// }

	}

	//通知到开始游戏  广播游戏客户端

}

func BroadErrorMsg(msg string, ws *websocket.Conn) {
	rsp := &message.PbErrorRsp{}
	rsp.MessageData = msg
	rData, _ := proto.Marshal(rsp) //回包
	sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData)
}
func DissolveTheGame(ws *websocket.Conn, data []byte) {
	//房主解散游戏房间
	//	req := &message.DissolveTheGameReq{}
	uid := ClientUserIds[ws]
	player := GamePlayers[uid]
	if player == nil {
		BroadErrorMsg("玩家不存在", ws)
		return
	}
	if player.GameRoom == nil {
		BroadErrorMsg("该房间不存在", ws)
		return
	}
	log.Printf("解散房间", player.GameRoom.RoomType)
	if player.GameRoom.RoomType == 1 {
		Dissolve_The_Game(player)
	}

}

// 游戏匹配
// 玩家登陆，上传头像金币信息
var MatchGameplayers = []*GamePlayer{}

var lock2 sync.Mutex

var lock3 sync.Mutex
var lock5 sync.Mutex
var lock6 sync.Mutex

// 玩家第一次选择模式
func CreateGameReq(ws *websocket.Conn, data []byte) {
	req := &message.CreateGameReq{}
	proto.Unmarshal(data, req) //解包
	log.Info("data", req)
	//player := gamePlayers[clientUserIds[ws]]
	UserClientIds[req.Uid] = ws
	ClientUserIds[ws] = req.Uid
	var player *GamePlayer = GamePlayers[req.Uid]
	if nil != player {
		if player.Status != 0 {

			BroadErrorMsg("该玩家已经在匹配或者已开房", ws)
			return
		}

	} else {
		player = createPlayer2(req.Uid, ws,req.HeadImg,req.Name,*req.Money)
		if nil == player {

				BroadErrorMsg("没有该玩家信息", ws)
			return
		}
	}
	player.LastHeartbeat=time.Now()
	player.AdmissionFee = uint32(req.AdmissionFee)

	//  if player.Money < player.AdmissionFee {
	//  	BroadErrorMsg("该玩家入场费不足", ws)
	//  	return
	//  }
	// Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
	player.MaxNum = int(req.PlayerNum)
	player.Mode = int(req.Mode)
	if req.Mode == uint32(ModeMatch) {
		//player.Status2 = uint32(PlayerMatching)
		match(player, ws, int(req.AdmissionFee), int(req.PlayerNum))
	} else if req.Mode == uint32(ModeClass) {
		//选择经典开房模式

		//lock5.Lock()

		room := GetIdleRoom(req.AdmissionFee, int(req.PlayerNum), int(req.Mode))

		//player.GameRoom = room
		player.Status = 12

		uid, _ := strconv.Atoi(player.Uid)
		room.Homeowner = uid
		room.RoomPlayers[player.Uid] = player
		//player.GameRoom = room
		rsp3 := &message.CreateGameRsp{}
		var rid uint32 = uint32(room.Id)
		rsp3.RoomId = &rid
		rData3, _ := proto.Marshal(rsp3) //回包
		//broadInfo(player.GameRoom, int16(message.MSGID_Create_Game_Rsp), rData3)
		sendData(ws, int16(message.MSGID_Create_Game_Rsp), rData3)
		room.RoomType = RoomOut
		//log.Printf("chatRoomId=====", *req.ChatRoomId)
		if req.ChatRoomId != nil {
			//
			//room.Type = 1
			room.RoomType = RoomIn
			room.ChatRoomId = int(*req.ChatRoomId)
			//房间内开房的话，则直接拉人
			result := Utils.ChatRoomBroadcast(int(*req.ChatRoomId), BroadcastInvisit, room.Id)
			if result.Code != 200 {
				log.Printf("发送邀请失败，通知客户端再发起邀请")
			}
		} else {
			room.RoomType = RoomOut
			//room.Players[0]=player
		}
		//lock5.Unlock()
	}

}

func Rcfcz(uid string, adminfee uint32, Type int) int {
	// 扣除玩家入场费
	var userInfos = []UserInfo{}
	uid2, _ := strconv.Atoi(uid)
	var userInfo = UserInfo{
		UserId:    uid2,
		GoldCoins: int(adminfee),
		Type:      Type,
	}
	userInfos = append(userInfos, userInfo)
	var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
	jsonData2, _ := json.Marshal(userInfoReq)
	result := Utils.PostData(jsonData2)
	return result
}

//player
//players map

// 房间踢人
func RoomKickUserReq(ws *websocket.Conn, data []byte) {
	req := &message.RoomKickUserReq{}
	proto.Unmarshal(data, req) //解包

	//uid := clientUserIds[ws]
	player := GamePlayers[req.Uid]
	uid1 := ClientUserIds[ws]
	uid, _ := strconv.Atoi(uid1)
	if uid != player.GameRoom.Homeowner {
		log.Printf("房主id", player.GameRoom.Homeowner)
		log.Printf("uid", uid)
		BroadErrorMsg("不是房主不能踢人", ws)
		return
	}

	for key, value := range player.GameRoom.Players {
		if value.GameRoom.GameEnd == GameNotStarted {
			if req.Uid == value.Uid {
				if player.Status != uint32(message.GameStatus_Player_Status_10) {
					Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
				}

				rsp := &message.RoomKickUserRsp{}
				rsp.Uid = req.Uid
				rData3, _ := proto.Marshal(rsp) //回包
				BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Kick_User_Rsp), rData3)
				//player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
				delete(player.GameRoom.Players, key)
				log.Println("开始踢人，查看剩余房间人数", req.Uid, player.GameRoom.Players)
				delete(GamePlayers, player.Uid)
				delete(ClientUserIds, UserClientIds[player.Uid])
				delete(UserClientIds, player.Uid)
				break
			}
		} else {
			BroadErrorMsg("游戏已经开始不能踢人", ws)
			break
		}

	}

}

// 退出房间或者房主解散房间 或者取消匹配
func RoomQuitReq(ws *websocket.Conn, data []byte) {
	req := &message.RoomQuitReq{}
	proto.Unmarshal(data, req) //解包
	uid := ClientUserIds[ws]
	player := GamePlayers[uid]
	if player == nil {
		BroadErrorMsg("改玩家已退出", ws)
		return
	}
	QuitRoom(player, ws, 11)

}

// 请求关闭客户端
func RoomCloseReq(ws *websocket.Conn, data []byte) {
	req := &message.RoomQuitReq{}
	proto.Unmarshal(data, req) //解包
	uid := ClientUserIds[ws]
	player := GamePlayers[uid]
	if player == nil {
		BroadErrorMsg("改玩家已退出", ws)
		return
	}
	QuitRoom(player, ws, 0)

}
func QuitRoom(player *GamePlayer, ws *websocket.Conn, status uint32) {
	//log.Info("玩家请求退出房间", player.GameRoom)
	uuid, _ := strconv.Atoi(player.Uid)
	if player.Status == 2 {
		player.Status = 10
		if player.GameRoom.Homeowner == uuid {
			//广播退出游戏
			var key2 int
			for key, value := range player.GameRoom.Players {
				if player.Uid == value.Uid {
					//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
					key2 = key
					delete(player.GameRoom.Players, key)
					break
				}
			}
			//player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
			Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
			rsp := &message.RoomQuitUserRsp{}
			rsp.Uid = player.Uid
			rData3, _ := proto.Marshal(rsp) //回包
			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)

			//player.Status = status

			//如果是房间开房玩家就移交下一个玩家，如果房间内没有玩家就解散房间
			if len(player.GameRoom.Players) == 0 {
				//解散房间
				Dissolve_The_Game(player)

			} else {
				//if player.GameRoom.Mode == 1 {
				if key2 == 0 {
					if player.GameRoom.Players[1] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[2] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[3] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
						player.GameRoom.Homeowner = uid
					}
				} else if key2 == 1 {
					if player.GameRoom.Players[2] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[3] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[0] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
						player.GameRoom.Homeowner = uid
					}
				} else if key2 == 2 {
					if player.GameRoom.Players[3] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[0] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[1] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
						player.GameRoom.Homeowner = uid
					}
				} else if key2 == 3 {
					if player.GameRoom.Players[0] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[1] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
						player.GameRoom.Homeowner = uid
					} else if player.GameRoom.Players[2] != nil {
						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
						player.GameRoom.Homeowner = uid
					}
				}
				//player.Status = status
				uuod := strconv.Itoa(player.GameRoom.Homeowner)
				log.Print("玩家是否移交房主", player.GameRoom.Mode)
				if player.GameRoom.Mode == 1 {
					rsp2 := &message.RoomChangeOfHomeownerRsp{}
					rsp2.Uid = uuod
					rData4, _ := proto.Marshal(rsp2) //回包
					log.Print("广播玩家移交房主", player.GameRoom.Mode)
					BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Change_Of_Homeowner_Rsp), rData4)
				} else if player.GameRoom.Mode == 2 {
					for key, value := range player.GameRoom.Players {
						if uuod == value.Uid {
							//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
							player.GameRoom.Players[key].Status = uint32(message.GameStatus_Player_Status_1)
							MatchGameplayers = append(MatchGameplayers, value)
							break
						}
					}
				}
				//player.GameRoom.RoomPlayers
				//delete(GamePlayers, player.Uid)
				//delete(ClientUserIds, ws)
				//delete(UserClientIds, player.Uid)
				//	}
			}

		} else {
			//不是房主的情况下
			for key, value := range player.GameRoom.Players {
				if player.Uid == value.Uid {
					//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
					delete(player.GameRoom.Players, key)
					break
				}
			}
			//player.Status = status
			//player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
			Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)

			// delete(GamePlayers, player.Uid)
			// delete(ClientUserIds, ws)
			// delete(UserClientIds, player.Uid)
			rsp := &message.RoomQuitUserRsp{}
			rsp.Uid = player.Uid
			rData3, _ := proto.Marshal(rsp) //回包
			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
		}
		//delete(GamePlayers, player.Uid)
		//delete(ClientUserIds, ws)
		//log.Printf("有玩家退出了清除了对应的ws", ClientUserIds[ws])
		//delete(UserClientIds, player.Uid)
	} else if player.Status == 10 {
		for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
			if player.GameRoom.GzPlayers[i].Uid == player.Uid {

				player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)

				i-- // 删除元素后，需要减少索引
				break
			}
		}
		delete(GamePlayers, player.Uid)
		delete(ClientUserIds, ws)
		delete(UserClientIds, player.Uid)

		rsp3 := &message.QuitRsp{}
		rsp3.SeatID = &player.SeatId
		rsp3.PlayerStatus = player.Status
		rsp3.Uid=player.Uid
		rData4, _ := proto.Marshal(rsp3) //回包
		BroadInfo(player.GameRoom, int16(message.MSGID_Quit_Rsq), rData4)

		rsp := &message.RoomQuitUserRsp{}
		rsp.Uid = player.Uid
		rData3, _ := proto.Marshal(rsp) //回包
		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)

	} else if player.Status == 1 {

		CancenMatch(player.Uid)
		
	
	} else if player.Status == 11 || player.Status == 12 {

		player.Status = 0
		delete(GamePlayers, player.Uid)
		delete(ClientUserIds, ws)
		delete(UserClientIds, player.Uid)
	} else if player.Status == 14 {

		Dissolve_The_Game(player)
	} else {
		//在游戏里退出直接退出游戏
		Quit(player.Uid)
		//delete(ClientUserIds, ws)
		//delete(UserClientIds, player.Uid)
	}

}

func Dissolve_The_Game(player *GamePlayer) {

	//广播解散游戏
	rsp := &message.DissolveTheGameRsp{}
	//rsp.Uid = req.Uid
	rData3, _ := proto.Marshal(rsp) //回包
	if player==nil{
		
		return
	}
	if player.GameRoom==nil{
		return
	}
	BroadInfoRoom(player.GameRoom, int16(message.MSGID_Dissolve_The_Game_Rsp), rData3)
	log.Printf("通知解散房间")
	UpdateRoom(player.GameRoom)

	var userInfos = []UserInfo{}
	for _, value := range player.GameRoom.Players {
		uid2, _ := strconv.Atoi(value.Uid)
		var userInfo = UserInfo{
			UserId:    uid2,
			GoldCoins: int(player.GameRoom.AdmissionFee),
			Type:      Plus,
		}
		//delete(userRoom, room.Players[j].Uid)
		userInfos = append(userInfos, userInfo)
		delete(GamePlayers, value.Uid)
		delete(ClientUserIds, UserClientIds[value.Uid])
		delete(UserClientIds, value.Uid)
	}
	for j := 0; j < len(player.GameRoom.GzPlayers); j++ {

		delete(GamePlayers, player.GameRoom.GzPlayers[j].Uid)
		delete(ClientUserIds, UserClientIds[player.GameRoom.GzPlayers[j].Uid])
		delete(UserClientIds, player.GameRoom.GzPlayers[j].Uid)
	}
	var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
	jsonData2, _ := json.Marshal(userInfoReq)
	if len(userInfos)>0{
		Utils.PostData(jsonData2)
	}


	// uid := player.Uid
	if player != nil {
		delete(GamePlayers, player.Uid)
		delete(ClientUserIds, UserClientIds[player.Uid])
		delete(UserClientIds, player.Uid)
	}

}

// 取消匹配
func CancelMatchReq(ws *websocket.Conn, data []byte) {
	req := &message.CancelMatchReq{}
	proto.Unmarshal(data, req) //解包
	uid := ClientUserIds[ws]
	CancenMatch(uid)

}

func CancenMatch(uid string) {
	var player = GamePlayers[uid]

	if player != nil {
		if player.GameRoom.GameEnd != GameNotStarted {
			//
			BroadErrorMsg("游戏已开始，不能取消匹配", UserClientIds[uid])
			return
		}
		// 先取消匹配，
		player.Status = 0

		//匹配状态下取消匹配并且更新房间状态
		//var key2 int = 0
		// player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
		Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
		for key, player2 := range player.GameRoom.Players {
			if player2.Uid == player.Uid {
				for j := 0; j < len(MatchGameplayers); j++ {
					if player2.Uid == MatchGameplayers[j].Uid {
						//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
						MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
					}
				}
				delete(player.GameRoom.Players, key)
				break
			}

		}

		

		rsp := &message.RoomQuitUserRsp{}
		rsp.Uid = player.Uid
		rData3, _ := proto.Marshal(rsp) //回包
		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)

		//让房主开启匹配

		delete(GamePlayers, player.Uid)
		delete(ClientUserIds, UserClientIds[uid])
		delete(UserClientIds, player.Uid)

		if len(player.GameRoom.Players) == 0 {
			//解散房间
			log.Info("开始解散房间")
			player.GameRoom.ticker.Stop()
			for _, player2 := range player.GameRoom.Players {
				for j := 0; j < len(MatchGameplayers); j++ {
					if player2.Uid == MatchGameplayers[j].Uid {
						//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
						MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)

					}

				}

			}

			rsp := &message.RoomQuitUserRsp{}
			rsp.Uid = player.Uid
			rData3, _ := proto.Marshal(rsp) //回包
			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
			Dissolve_The_Game(player)

		}
	}

}

// 客户端邀请房间内玩家
func RoomInviteReq(ws *websocket.Conn, data []byte) {
	req := &message.RoomInviteReq{}

	proto.Unmarshal(data, req) //解包
	result2 := Utils.ChatRoomBroadcast(int(*req.ChatRoomId), BroadcastInvisit, int(*req.RoomId))
	if result2.Code != 200 {
		log.Printf("发送邀请失败，通知客户端再发起邀请")
	}
	rsp := &message.RoomInviteRsp{}

	var result uint32 = 0
	rsp.Result = &result
	rData3, _ := proto.Marshal(rsp) //回包

	sendData(ws, int16(message.MSGID_Room_Invite_Rsp), rData3)

}

func DiscReq(ws *websocket.Conn, data []byte) {
	req := &message.DiscReq{}
	proto.Unmarshal(data, req) //解包
	room := gameRooms[int(req.RoomId)]
	if room.Status == RoomBusy {
		// if room.GameEnd == 0 {

		// } else if room.GameEnd == 1 {

		// }
		// rsp := &message.DiscR{}
		// var game = uint32(room.GameEnd)
		// rsp.RoomStatus = &game
		// rData3, _ := proto.Marshal(rsp) //回包

		// sendData(ws, int16(message.MSGID_Disc_Rsp), rData3)
	}
}

func SendDataReq(ws *websocket.Conn, data []byte) {
	req := &message.SendMsgReq{}
	proto.Unmarshal(data, req) //解包
	uid := ClientUserIds[ws]
	var player = GamePlayers[uid]
	rsp := &message.SendMsgRsp{}
	rsp.Uid=uid
	rsp.Data = req.Data
	
	rData3, _ := proto.Marshal(rsp) //解包
	//	room := gameRooms[int(req.RoomId)]
	//BroadInfo()
	BroadInfo(player.GameRoom, int16(message.MSGID_Send_Msg_Rsp), rData3)
	//sendData(ws, int16(message.MSGID_Send_Msg_Rsp), rData3)
}

func Gettoken(c *gin.Context) SqlResponse {
	appID := "53c2ddc63bbc41228d916e1bea9a566a"
	appCertificate := "ccefdf8d574d42a6a042a9415fceb18c"
	channelName := "1"
	uid := uint32(1)
	//uidStr := "2882341273"
	tokenExpirationInSeconds := uint32(3600)
	privilegeExpirationInSeconds := uint32(3600)
	// joinChannelPrivilegeExpireInSeconds := uint32(3600)
	// pubAudioPrivilegeExpireInSeconds := uint32(3600)
	// pubVideoPrivilegeExpireInSeconds := uint32(3600)
	// pubDataStreamPrivilegeExpireInSeconds := uint32(3600)

	result, err := rtctokenbuilder.BuildTokenWithUid(appID, appCertificate, channelName, uid, rtctokenbuilder.RoleSubscriber, tokenExpirationInSeconds, privilegeExpirationInSeconds)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("Token with int uid: %s\n", result)
	}
	log.Printf("result==", result)
	var sql = SqlResponse{
		Code:    200,
		Message: "成功",
		Data:    result,
	}
	return sql
	//c.JSON(http.StatusOK, sql)
	// result, err = rtctokenbuilder.BuildTokenWithUserAccount(appID, appCertificate, channelName, uidStr, rtctokenbuilder.RoleSubscriber, tokenExpirationInSeconds, privilegeExpirationInSeconds)
	// if err != nil {
	// 	fmt.Println(err)
	// } else {
	// 	fmt.Printf("Token with user account: %s\n", result)
	// }

	// result, err1 := rtctokenbuilder.BuildTokenWithUidAndPrivilege(appID, appCertificate, channelName, uid,
	// 	tokenExpirationInSeconds, joinChannelPrivilegeExpireInSeconds, pubAudioPrivilegeExpireInSeconds, pubVideoPrivilegeExpireInSeconds, pubDataStreamPrivilegeExpireInSeconds)
	// if err1 != nil {
	// 	fmt.Println(err1)
	// } else {
	// 	fmt.Printf("Token with int uid and privilege: %s\n", result)
	// }

	// result, err1 = rtctokenbuilder.BuildTokenWithUserAccountAndPrivilege(appID, appCertificate, channelName, uidStr,
	// 	tokenExpirationInSeconds, joinChannelPrivilegeExpireInSeconds, pubAudioPrivilegeExpireInSeconds, pubVideoPrivilegeExpireInSeconds, pubDataStreamPrivilegeExpireInSeconds)

	// if err1 != nil {
	// 	fmt.Println(err1)
	// } else {
	// 	fmt.Printf("Token with user account and privilege: %s\n", result)
	// }
}
