package Module

import (
	log "Server-Core/Server/Base/Log"
	"Server-Core/Server/GameServer/Server/PlaneGame/Utils"
	message "Server-Core/Server/Message"
	scheme "Server-Core/Server/Scheme"
	"fmt"
	"math/rand"
	"strconv"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/gorilla/websocket"
)

// 结构体  id ，值 根据值查询id，再根据id 查询对应的关联数据
// 用户 -》房间 -》 所有用户-》所有座位-》飞机
//

// 1一个房间对应多个玩家，一个玩家对应多个飞机 ，初始化生成房间号
// 游戏初始化根据http请求初始化

func broadInfoSz(player *GamePlayer) {
	//先启动倒计时防止
	log.Info("开启倒计时等待下一位玩家摇筛子,先开始倒计时，防止不能停止倒计时", player.SeatId)
	ticker := time.NewTicker(time.Second * 1)
	player.GameRoom.ticker = ticker
	go countdonw(player, 1, "")
	errcode2 := uint32(message.GameStatus_GAME_STATUS_OK)
	seatID := player.SeatId
	//返回房间id
	time2 := uint32(10)
	rsp3 := &message.GameStartRsp{SeatID: &seatID, CastSecond: &time2, Result: &errcode2}
	//log.Info("通知开始掷子,并开启倒计时", *rsp3.SeatID)
	rData3, _ := proto.Marshal(rsp3) //回包

	BroadInfo(player.GameRoom, int16(message.MSGID_Start_Game_Rsp), rData3)

}

func countdonw(player *GamePlayer, Type int, planeId string) {
	//type 1是摇筛子，而是起飞，3是行走

	defer player.GameRoom.ticker.Stop()
	for i := 0; i < 11; i++ {
		if player != nil {
			if player.GameRoom != nil {
				if player.GameRoom.ticker != nil {
					select {
					case <-player.GameRoom.ticker.C:
						//超过10秒没执行就会进入托管，
						if i == 10 {
							//超时了开始托管

							log.Info("operate time out update status 9", player.Uid)
							rsp2 := &message.TrusteeshipRsp{}
							rsp2.SeatID = &player.SeatId
							player.Status = uint32(message.GameStatus_Player_Status_9)
							rsp2.Trust = true
							rData, _ := proto.Marshal(rsp2) //回包
							BroadInfo(player.GameRoom, int16(message.MSGID_Trusteeship_Rsp), rData)
							player.GameRoom.ticker.Stop()
							if player.GameRoom.GameEnd == GamePlaying {
								fmt.Println("自动摇筛子", i)
								if 1 == Type {
									go ThrowTheDice2(player.Uid)
								} else if 2 == Type {
									//起飞
									go StartFly2(player.Uid, planeId)
								} else if 3 == Type {
									//行走
									go Move2(player.Uid, planeId)
								}

							}
							fmt.Println("托管结束", i)
							return
						}
						fmt.Println("托管倒计时", i, player.SeatId)
					}
				}
			}
		}

	}
}

// 拉房倒计时
func countdonw2(player *GamePlayer, num int) {
	ticker := time.NewTicker(time.Second * 1)
	player.GameRoom.ticker = ticker
	defer ticker.Stop()
	for i := 0; i < 61; i++ {
		select {
		case <-ticker.C:
			//room.TimeOut=room.TimeOut-1
			//超过10秒没执行就会进入托管，
			if i == 60 {
				//超时了需要告诉客户端解散游戏，发起http请求给语聊房回滚数据
				log.Warn("开始游戏一直没进入游戏数据回退")
				Dissolve_The_Game(player)
				ticker.Stop()
				return
			}
			fmt.Println("进房倒计时", i, num)

		}
	}
}

// 匹配倒计时
func countdonw3(uid string, roomId uint32) {
	ticker := time.NewTicker(time.Second * 1)

	var player = GamePlayers[uid]
	player.GameRoom.ticker = ticker
	defer player.GameRoom.ticker.Stop()
	for i := 0; i < 31; i++ {
		if player != nil {
			if player.GameRoom != nil {
				if player.GameRoom.ticker != nil {
					select {
					case <-ticker.C:
						//room.TimeOut=room.TimeOut-1
						//超过10秒没执行就会进入托管，

						if i == 30 {
							player.GameRoom.ticker.Stop()
							if len(player.GameRoom.Players) > 1 {
								player.GameRoom.ticker.Stop()
								for _, player := range player.GameRoom.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:]...)
										}
									}

								}
								player.GameRoom.StartPlayerNum = len(player.GameRoom.Players)
								time.Sleep(1 * time.Second)
								rsp3 := &message.RoomStartGameRsp{}
								rData3, _ := proto.Marshal(rsp3) //回包
								log.Info("广播开始玩游戏")
								go countdonw2(player, 2)
								BroadInfo(player.GameRoom, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
								// result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
								// if result.Code != 200 {
								// 	log.Info("通知语聊房开始游戏失败")
								// }

							} else {

								CancenMatch(player.Uid)
								//Dissolve_The_Game(player)
							}

							//player.GameRoom.ch2 = nil
							//	wg.Done()

							return
						} else {
							//通知到玩家倒计时
							rsp3 := &message.RoomDjsRsp{}
							var time = uint32(i)
							rsp3.Time = &time
							rData, _ := proto.Marshal(rsp3) //回包
							BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Djs_Rsp), rData)
							fmt.Println("匹配倒计时", i)
						}

					}
				}
			}
		}

	}
}

// 游戏结算倒计时退出
func countdonw4(player *GamePlayer, num int) {
	ticker := time.NewTicker(time.Second * 1)
	player.GameRoom.ticker = ticker
	///player.GameRoom
	defer ticker.Stop()
	for i := 0; i < 10; i++ {
		select {
		case <-ticker.C:
			//room.TimeOut=room.TimeOut-1
			//超过10秒没执行就会进入托管，
			if i == 60 {
				//超时了需要告诉客户端解散游戏，发起http请求给语聊房回滚数据
				//log.Warn("开始游戏一直没进入游戏数据回退")
				//Dissolve_The_Game(player)
				ticker.Stop()
				return
			}
			fmt.Println("结算倒计时", i, num)

		}
	}
}

// 前六轮过后（第七轮），没有可起飞飞机，必出6， 开始摇骰子
// 根据权重扔骰子  要记录该玩家每一轮出的值
// 房间数对应多个玩家，每个玩家对应一个游戏轮数,每个游戏轮数对应多个玩家的掷筛记录

func ThrowTheDice(ws *websocket.Conn, data []byte) {
	uid := ClientUserIds[ws]
	player := getPlayer(uid)
	if player.Status == 9 {
		BroadErrorMsg("托管状态下，不能执行操作", ws)
		return
	}
	ThrowTheDice2(uid)
}

func ThrowTheDice2(uid string) {

	/*defer func() {
		//捕获test抛出的panic
		if err := recover(); err != nil {
			fmt.Println("协程发生错误", err)
			log.Warn("开始游戏一直没进入游戏数据回退")
		}
	}()*/
	player := getPlayer(uid)
	if player==nil{
		log.Warn("该玩家已退出")
		return
	}
	//room := userRoom[player.Uid]
	room := player.GameRoom
	if room.GameEnd == GameEnd {
		log.Warn("游戏已经结束")
		return
	}
	if room.ticker != nil {
		log.Info("停止倒计时")
		room.ticker.Stop()
	} else {
		log.Info("计时器为空")
	}

	rand.Seed(time.Now().UnixNano())
	num := rand.Int31n(10000)
	var ds uint32 = 0
	//判断是否是最后一个棋子
	planes := player.GamePlane
	var distance3 = 56
	var range1 = []*scheme.SzItem{}
	if player.FinishNum == 3 {
		//获取最后跑的飞机是否在终点区
		//获取飞机距离重点区的距离
		//var isFinish = 0
		for i := 0; i < len(planes); i++ {
			if planes[i].IsFly == 1 {
				distance3 = 56 - int(planes[i].CurPosIndex)
				//log.Info("更新距离", distance3)
				break
			}
		}
		if distance3 <= 6 {
			//log.Info("查询range4<6")
			range1 = GetRange4(1, 1, 6, room.DataList)
		} else {
			//最后一架飞机 玩家人数小于4,不在终点区 ，
			if len(room.Players) < 4 {
				//log.Info("查询range2<4")
				range1 = GetRange2(1, 2, 1, room.DataList)
			} else {
				//最后一架飞机 ，玩家人数等于4,,不在终点区 ，
				//log.Info("查询range2=4")
				range1 = GetRange2(1, 1, 1, room.DataList)
			}
		}
	} else {
		//	var range1 = []*scheme.SzItem{}
		if len(room.Players) < 4 {
			//不是最后一架飞机，玩家人数小于4
			//log.Info("查询range<4", room.DataList)
			range1 = GetRange(2, 2, room.DataList)
		} else {
			//不是最后一架飞机，玩家人数等于4
			//log.Info("查询range=", room.DataList)
			range1 = GetRange(2, 1, room.DataList)
		}
	}
	//log.Info("range========", range1)
	if num < range1[0].Weight {
		ds = uint32(range1[0].Ds)
	} else if num < range1[1].Weight {
		ds = uint32(range1[1].Ds)
	} else if num < range1[2].Weight {
		ds = uint32(range1[2].Ds)
	} else if num < range1[3].Weight {
		ds = uint32(range1[3].Ds)
	} else if num < range1[4].Weight {
		ds = uint32(range1[4].Ds)
	} else if num < range1[5].Weight {
		ds = uint32(range1[5].Ds)
	}
	// 玩家没有棋子可操作时 若前六轮没有一个六，则第7轮必出6
	var ismove = 1
	for i := 0; i < len(planes); i++ {
		if planes[i].IsFly == 1 {
			ismove = 2
			break
		}
	}
	gamenum := player.Num
	if ismove == 1 {
		//0,1,2,3,4,5,6
		if gamenum > 4 {
			//最后一次是6 ，
			log.Warn("没有飞机起飞的情况下，进入了第七轮")
			var issix = 0
			for i := gamenum - 5; i < gamenum; i++ {
				if len(player.NumberOfRounds[i].NumberOfRounds) > 1 {
					log.Warn("上一次", *player.NumberOfRounds[i].NumberOfRounds[0])
					issix = 1
					break
				}
			}
			if issix == 0 {
				ds = 6
			}
		}
	}

	//如果当前轮里没有数据则直接添加，如果已有数据，则看是不是6 是的话加在当前轮，不是的话，新加一轮
	if len(player.NumberOfRounds[gamenum].NumberOfRounds) == 0 {
		player.NumberOfRounds[gamenum].NumberOfRounds = append(player.NumberOfRounds[gamenum].NumberOfRounds, &ds)
	} else {
		//如果是第一轮，多次投色子
		i := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-1]
		if *i == 6 {
			//上一次是6的情况下直接追加当前轮，
			player.NumberOfRounds[gamenum].NumberOfRounds = append(player.NumberOfRounds[gamenum].NumberOfRounds, &ds)
		} else {
			////上一轮不是是6的情况下添加新的轮数
			var rounds = []*uint32{}
			rounds = append(rounds, &ds)
			player.Num = player.Num + 1
			var gameRound2 *GameNumberOfRounds = new(GameNumberOfRounds)
			(*gameRound2).Num = player.Num
			(*gameRound2).NumberOfRounds = rounds
			player.NumberOfRounds = append(player.NumberOfRounds, gameRound2)

		}
	}
	//玩家都准备完毕了就可以游戏
	rsp := &message.ThrowTheDiceRsp{}
	errcode2 := uint32(message.GameStatus_GAME_STATUS_OK)
	rsp.Result = &errcode2
	rsp.Point = ds
	//如果没有飞机起飞，并且点数不为6则跳过当局
	//players := userRoom[player.Uid].Players
	//planes := player.GamePlane
	var canMove = 0
	var flyplane []*GamePlane
	var unflyplane []*GamePlane
	//var moveplane *GamePlane
	for i := 0; i < len(planes); i++ {
		//正在移动加点数距离不到终点或者没有起飞点数为6 可以操作
		if planes[i].IsFly == 1 {

			//isFly = 1
			if planes[i].CurPosIndex+ds <= 56 {
				flyplane = append(flyplane, planes[i])
				canMove = canMove + 1
				//	moveplane=planes[i]
			}
			//break
		} else if planes[i].IsFly == 0 {

			if ds == 6 {
				unflyplane = append(unflyplane, player.GamePlane[i])
				canMove = canMove + 1
				//	moveplane=planes[i]
			}
		}
	}

	if canMove > 0 {
		if ds != 6 {
			setNextTurn(true, player, rsp)
		} else {
			//判断是不是3次连续6
			log.Info("这是第几轮", gamenum)
			if len(player.NumberOfRounds[gamenum].NumberOfRounds) > 2 {
				u := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-1]
				u2 := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-2]
				u3 := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-3]
				log.Warn("第一回合%d", *u)
				log.Warn("第二回合%d", *u2)
				log.Warn("第三回合%d", *u3)
				if *u == 6 && *u2 == 6 && *u3 == 6 {
					//log.Info("飞机已起飞，点数为6的情况下,连续三次6", nextSeatId)  三次六的情况下直接结束这一轮
					setNextTurn(false, player, rsp)
					var rounds = []*uint32{}
					//rounds = append(rounds, &ds)
					player.Num = player.Num + 1
					var gameRound2 *GameNumberOfRounds = new(GameNumberOfRounds)
					(*gameRound2).Num = player.Num
					(*gameRound2).NumberOfRounds = rounds
					player.NumberOfRounds = append(player.NumberOfRounds, gameRound2)

				} else {

					setNextTurn(true, player, rsp)
				}

			} else {
				//有飞机起飞，有6，判断有没有未起飞的
				setNextTurn(true, player, rsp)
			}
		}
	} else {

		setNextTurn(false, player, rsp)
	}
	rsp.SeatID = &player.SeatId
	var i1 uint32 = 1
	var i2 uint32 = 2
	var i3 uint32 = 3
	var i4 uint32 = 4
	rsp.AutoMove = &i1
	//判断是否是托管
	var operatePlane *GamePlane
	//var tg bool =false
	if player.Status == uint32(message.GameStatus_Player_Status_9) {
		//tg=false
		//托管的情况下，就会完全自动走
		if *rsp.SkipReason == 0 {
			//只有一架飞机已经起飞，且能行走
			if len(flyplane) > 0 {
				rsp.AutoMove = &i4
				operatePlane = flyplane[0]
			} else if len(unflyplane) > 0 {
				if ds == 6 {
					rsp.AutoMove = &i3
					operatePlane = unflyplane[0]
				}
			}
		} else if *rsp.SkipReason == 1 {
			if rsp.SeatID == rsp.NextTurn {
				rsp.AutoMove = &i2
				//ThrowTheDice(ws)
			}

		}
	} else {
		//	tg=true
		//不是托管的情况下只会在单棋子的情况下自动走
		if *rsp.SkipReason == 0 {
			//log.Info("len(flyplane)", len(flyplane))
			//只有一架飞机已经起飞，且能行走
			if len(flyplane) == 1 {
				if len(unflyplane) == 0 {
					//其他飞机都到达了终点的情况自动行走
					rsp.AutoMove = &i4
					operatePlane = flyplane[0]
					//	Move(ws, plane[0].Id)
				} else {
					//其他飞机没有起飞,点数不为六，且小于等于终点区自动行走
					if ds != 6 {
						rsp.AutoMove = &i4
						operatePlane = flyplane[0]
					}
				}
			} else if len(flyplane) == 0 {
				if len(unflyplane) == 1 {
					if ds == 6 {
						//其他飞机都到达了终点的情况自动起飞
						rsp.AutoMove = &i3
						operatePlane = unflyplane[0]
						//StartFly(ws, unflyplane.Id)
					}

				}
			}
		} else if *rsp.SkipReason == 1 {
			if rsp.SeatID == rsp.NextTurn {
				rsp.AutoMove = &i2
				//ThrowTheDice(ws)
			}

		}
	}
	var data2 = []*message.PlayerRsp{}
	for _, value := range room.Players {
		rsp3 := &message.PlayerRsp{}
		rsp3.SeatId = &value.SeatId
		var data1 = []*message.PlaneRsp{}
		for j := 0; j < len(value.GamePlane); j++ {
			rsp4 := &message.PlaneRsp{}
			rsp4.PlaneId = value.GamePlane[j].Id
			u := uint32(value.GamePlane[j].IsFly)
			rsp4.PlaneStatus = &u
			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
			data1 = append(data1, rsp4)
		}
		rsp3.Planes = data1
		data2 = append(data2, rsp3)
	}
	rsp.Players = data2
	rData, _ := proto.Marshal(rsp) //回包
	log.Warn("发送骰子数据=======", rsp)

	//下一个人
	nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
	if room.GameEnd == GamePlaying {
		//下一个人是自己的时候，才会自动摇骰子
		if rsp.NextTurn == rsp.SeatID {
			if *rsp.AutoMove == 2 {
				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
				broadInfoSz(nextPlayer)

				//摇到6，下一个行动人还是自己的情况
				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
					time.Sleep(1 * time.Second)
					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
						go ThrowTheDice2(uid)
					}
				} else {
					go ThrowTheDice2(uid)
				}

			} else if *rsp.AutoMove == 3 {
				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
				ticker := time.NewTicker(time.Second * 1)
				player.GameRoom.ticker = ticker
				go countdonw(nextPlayer, 2, operatePlane.Id)
				//	go countdonw(nextPlayer)
				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
					time.Sleep(1 * time.Second)
					//要判断是不是单棋子自动走，如果只是则不用判断托管
					if len(flyplane) == 0 && len(unflyplane) == 1 {
						go StartFly2(uid, operatePlane.Id)
					} else {
						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
							go StartFly2(uid, operatePlane.Id)
						}
					}
				} else {
					go StartFly2(uid, operatePlane.Id)
				}
			} else if *rsp.AutoMove == 4 {
				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
				ticker := time.NewTicker(time.Second * 1)
				player.GameRoom.ticker = ticker
				go countdonw(nextPlayer, 3, operatePlane.Id)
				//go countdonw(nextPlayer)
				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
					time.Sleep(1 * time.Second)
					//	if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
					if len(flyplane) == 1 && len(unflyplane) == 0 {
						go Move2(uid, operatePlane.Id)
					} else {
						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
							go Move2(uid, operatePlane.Id)
						}
					}

					//}
				} else {
					go Move2(uid, operatePlane.Id)
				}

			} else if *rsp.AutoMove == 1 {
				log.Info("下一个人是自己行动的时候，要自己选择棋子起飞，或者选择棋子行走")
				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
				ticker := time.NewTicker(time.Second * 1)
				player.GameRoom.ticker = ticker
				if len(flyplane) > 0 {
					go countdonw(nextPlayer, 3, flyplane[0].Id)
				} else {
					go countdonw(nextPlayer, 2, unflyplane[0].Id)
				}

				//broadInfoSz(nextPlayer)
			}
		} else {
			BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
			log.Info("player======,", player.SeatId)
			log.Info("nextPlayer========,", *rsp.NextTurn)
			broadInfoSz(nextPlayer)
			if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {

				time.Sleep(1 * time.Second)
				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
					go ThrowTheDice2(nextPlayer.Uid)
				}

				// } else {
				// 	if room.GameEnd == GamePlaying {
				// 		log.Info("下一个人不是自己通知倒计时等待下一位玩家摇筛子")
				// 		broadInfoSz(nextPlayer)
				// 	}

			}

		}
	}

}

// 心跳包
// 客户端请求起飞
func StartFly(ws *websocket.Conn, data []byte) {
	req := &message.PlaneStartReq{}
	err := proto.Unmarshal(data, req)
	if err != nil {
		//	errcode2 := GAME_STATUS_PB_ERR
		rsp := &message.PbErrorRsp{}
		rData2, _ := proto.Marshal(rsp) //回包
		sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData2)
		return
	}
	uid := ClientUserIds[ws]
	player := getPlayer(uid)
	if player.Status == 9 {
		BroadErrorMsg("托管状态下，不能执行操作", ws)
		return
	}
	StartFly2(uid, req.PlaneID)
}

func StartFly2(uid string, PlaneId string) {
	/*defer func() {
		//捕获test抛出的panic
		if err := recover(); err != nil {
			fmt.Println("协程发生错误", err)
			log.Warn("开始游戏一直没进入游戏数据回退")
		}
	}()*/
	rsp := &message.PlaneStartRsp{}

	//uid := clientUserIds[ws]
	player := getPlayer(uid)
	if player==nil{
		log.Warn("已没有该用户")
		return
	}
	room := player.GameRoom
	if room.GameEnd == GameEnd {
		log.Warn("游戏已经结束")
		return
	}

	if room.ticker != nil {
		log.Info("停止倒计时")
		room.ticker.Stop()
	}
	planes := player.GamePlane
	seatId := player.SeatId
	//userRoom[player.Uid].ticker.Stop()
	players := room.Players
	room.ticker.Stop()
	for i := 0; i < len(planes); i++ {
		if planes[i].Id == PlaneId {
			planes[i].IsFly = 1
			//如果是seat是0，起飞就是1  seat2 -》14  ，seat3-》27 seat4-》40
			planes[i].CurPosIndex = 0
			break
		}
	}

	rsp.SeatID = &seatId
	rsp.PlaneID = PlaneId

	rsp.PlayerNum = uint32(len(players))
	//如果是6的情况下下一个摇色子的是自己
	rsp.NextTurn = &seatId

	log.Warn("发送起飞数据", rsp)
	var data2 = []*message.PlayerRsp{}
	for _, value := range room.Players {
		rsp3 := &message.PlayerRsp{}
		rsp3.SeatId = &value.SeatId
		var data1 = []*message.PlaneRsp{}
		for j := 0; j < len(value.GamePlane); j++ {
			rsp4 := &message.PlaneRsp{}
			rsp4.PlaneId = value.GamePlane[j].Id
			u := uint32(value.GamePlane[j].IsFly)
			rsp4.PlaneStatus = &u
			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
			data1 = append(data1, rsp4)
		}
		rsp3.Planes = data1
		data2 = append(data2, rsp3)
	}

	rsp.Players = data2
	rData, _ := proto.Marshal(rsp) //回包
	BroadInfo(room, int16(message.MSGID_Start_Plane_Rsp), rData)
	broadInfoSz(player)
	if player.Status == uint32(message.GameStatus_Player_Status_9) {
		//log.Info("aotumove8")

		time.Sleep(1 * time.Second)
		if player.Status == uint32(message.GameStatus_Player_Status_9) {
			go ThrowTheDice2(player.Uid)
		}

	}
	// else {

	// 	if room.GameEnd == GamePlaying {
	// 		broadInfoSz(player)
	// 	}

	// }

	//倒计时发一个10
	//countdonw(userRoom[player.Uid].Players, MSGID_START_GAME, 10, player.SeatId)
}

// 要讨论下棋盘布局
// 客户端请求行走 逻辑待完善
func Move(ws *websocket.Conn, data []byte) {

	req := &message.MoveReq{}
	err := proto.Unmarshal(data, req) //解包
	if err != nil {
		//	errcode2 := GAME_STATUS_PB_ERR
		rsp := &message.PbErrorRsp{}
		rData2, _ := proto.Marshal(rsp) //回包
		sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData2)
		return
	}
	uid := ClientUserIds[ws]
	player := getPlayer(uid)
	if player.Status == 9 {
		BroadErrorMsg("托管状态下，不能执行操作", ws)
		return
	}
	Move2(uid, req.PlaneID)
}

func Move2(uid string, PlaneId string) {
	/*defer func() {
		//捕获test抛出的panic
		if err := recover(); err != nil {
			fmt.Println("协程发生错误", err)
			log.Warn("结束数据回退")
		}
	}()*/
	rsp := &message.MoveRsp{}
	//玩家都准备完毕了就可以游戏
	//uid := clientUserIds[ws]
	player := getPlayer(uid)
	if nil == player {
		log.Info("已没有该玩家")
		return
	}
	planes := player.GamePlane
	

	if player.GameRoom==nil{
		log.Warn("游戏已经结束")
		return
	}
	room := player.GameRoom
	if room.GameEnd == GameEnd {
		log.Warn("游戏已经结束")
		return
	}
	if room.ticker != nil {
		log.Info("停止倒计时")
		room.ticker.Stop()
	}
	//获取玩家上一次的筛子点数
	rounds := player.NumberOfRounds[player.Num].NumberOfRounds
	var rand uint32 = 0
	if len(rounds) > 0 {
		u := rounds[len(rounds)-1]
		//对指针取值
		rand = *u
	}
	players := room.Players
	room.ticker.Stop()
	//修改飞机位置
	planeId, _ := strconv.Atoi(PlaneId)
	plane := planes[planeId]
	log.Warn("查询上一次的点数", rand)

	if plane.CurPosIndex+rand > 56 {
		// log.Warn("超出范围，不能行走")
		// var data = &message.KickPlayerRsp{}
		// rData, _ := proto.Marshal(data) //回包
		// broadInfo(room, int16(message.MSGID_Move_Error_Rsp), rData)
		BroadErrorMsg("超出范围，不能行走", UserClientIds[uid])
		return
	}
	plane.CurPosIndex = plane.CurPosIndex + rand
	log.Warn("update plane rand", plane)
	//到达终点的情况
	if plane.CurPosIndex == 56 {
		player.FinishNum = player.FinishNum + 1

		//log.Info("FinishNum", player.FinishNum)
		//0代表撞子或者到达终点
		var nilds uint32 = 0
		player.NumberOfRounds[player.Num].NumberOfRounds = append(player.NumberOfRounds[player.Num].NumberOfRounds, &nilds)
		rsp2 := &message.FinishEventRsp{SeatId: &player.SeatId, PlaneId: plane.Id}
		rsp.FinishEvent = rsp2
		plane.IsFly = 2
		//获得全部到达终点
		//代表自己走完了   3 0 1
		if player.FinishNum == 4 {
			log.Info("endgameplayer", player.Uid)
			player.Status = uint32(message.GameStatus_Player_Status_5)
			room.ArrivalNum = room.ArrivalNum + 1
			log.Info("ArrivalNum", room.ArrivalNum)
			//判断是否结束游戏
			if room.StartPlayerNum < 4 {
				//rsp.NextTurn = &player.SeatId
				rsp.NextTurn = nil
			} else {
				if room.ArrivalNum == 2 {
					//userRoom[player.Uid].GameEnd = 2
					rsp.NextTurn = nil
				} else {
					nextSeatId := getNextSeatId(player.SeatId, room)
					rsp.NextTurn = &nextSeatId
				}

			}
		} else {
			rsp.NextTurn = &player.SeatId
		}
	} else {
		if plane.IsFly == 1 {
			// 获取飞机所在的下标
			//获取地图的值标获取对应的格子
			//未到达终点区的情况,就会发生撞棋
			if plane.CurPosIndex < 51 {
				var planess []*GamePlane = []*GamePlane{}

				for _, value := range players {
					if value.Uid != player.Uid {
						for i := 0; i < len(value.GamePlane); i++ {
							if value.GamePlane[i].IsFly == 1 {
								//不在8个位置上就会发生撞棋
								i2 := player.GamePlaneIndex[plane.CurPosIndex]
								if i2 == 1 || i2 == 9 || i2 == 14 || i2 == 22 || i2 == 27 || i2 == 35 || i2 == 40 || i2 == 48 {
									continue
								}
								if value.GamePlaneIndex[value.GamePlane[i].CurPosIndex] == player.GamePlaneIndex[plane.CurPosIndex] {
									log.Warn("有可以撞的飞机", value.GamePlane[i])
									planess = append(planess, value.GamePlane[i])
								}
							}
						}
					}

				}

				if len(planess) == 1 {
					//if planess[0].Uid != player.Uid {
					log.Warn("have clash plane", player.Uid)
					log.Warn("发生了撞棋的被撞飞机uid", planess[0].Uid)
					//如果只有一个飞机也不是自己的飞机就会发生撞棋
					planess[0].IsFly = 0
					planess[0].CurPosIndex = 0
					player.Kick = player.Kick + 1
					getPlayer(planess[0].Uid).BeKick = getPlayer(planess[0].Uid).BeKick + 1
					var i uint32 = 1
					m := &message.KickPlayerRsp{SeatId: &getPlayer(planess[0].Uid).SeatId, PlaneNum: &i, PlaneID: planess[0].Id}
					var data = []*message.KickPlayerRsp{}
					data = append(data, m)
					rsp2 := &message.TKickEventRsp{PlayerNum: &i, KickPlayer: data}
					rsp.TKickEvent = rsp2
					//撞棋下一个行动人还是自己
					rsp.NextTurn = &player.SeatId
					//100代表撞子或者达到终点
					var nilds uint32 = 0
					player.NumberOfRounds[player.Num].NumberOfRounds = append(player.NumberOfRounds[player.Num].NumberOfRounds, &nilds)
				} else {
					seatId := player.SeatId
					if rand == 6 {
						rsp.NextTurn = &seatId
					} else {
						nextSeatId := getNextSeatId(player.SeatId, room)
						rsp.NextTurn = &nextSeatId
					}
				}
			} else {
				seatId := player.SeatId
				if rand == 6 {
					rsp.NextTurn = &seatId
				} else {
					nextSeatId := getNextSeatId(player.SeatId, room)
					rsp.NextTurn = &nextSeatId
				}
			}

		} else {
			//游戏出错了，要清除房间数据重来
			//UpdateRoom(room)
			log.Warn("飞机没有起飞不能行走", plane)
			Dissolve_The_Game(player)
		}
	}
	//判断是否撞棋   根据地图上查看对应的位置上有哪些飞机，
	//获取棋盘内所有玩家是否有飞机在对应的位置
	rsp.CurPosIndex = &plane.CurPosIndex
	rsp.PlaneID = PlaneId
	rsp.Step = &rand
	//结束游戏就没有下一个人，并且不能行动
	rsp.PlayerNum = uint32(len(room.Players))
	rsp.SeatID = &player.SeatId
	//如果上一次是6的点数，这一次还是自己摇色子  待改
	var data2 = []*message.PlayerRsp{}

	for _, value := range room.Players {
		rsp3 := &message.PlayerRsp{}
		rsp3.SeatId = &value.SeatId
		var data1 = []*message.PlaneRsp{}
		for j := 0; j < len(value.GamePlane); j++ {
			rsp4 := &message.PlaneRsp{}
			rsp4.PlaneId = value.GamePlane[j].Id
			u := uint32(value.GamePlane[j].IsFly)
			rsp4.PlaneStatus = &u
			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
			data1 = append(data1, rsp4)
		}
		rsp3.Planes = data1
		data2 = append(data2, rsp3)
	}

	rsp.Players = data2

	rData, _ := proto.Marshal(rsp) //回包
	log.Warn("发送移动结果数据", rsp)
	BroadInfo(room, int16(message.MSGID_Move_Rsp), rData)
	//log.Info("又发来了请求2")

	//如果下一个玩家是托管状态就直接帮忙投色子 //因为之前的函数没结束，在后面的函数中结束了，导致又会执行一次
	//判断是否结束游戏
	if room.GameEnd == GamePlaying {
		log.Warn("游戏没结束的情况")
		if room.StartPlayerNum == 4 {
			//如果已经有人到达终点了
			if room.ArrivalNum == 2 {
				log.Warn("4个人的情况下有2人到达了终点,结算游戏进行排名", room.ArrivalNum)
				if room.RunnerNum == 0 {
					//将会直接对4个人进行排名 432 缺少1
					rank34(room, player)

					for _, value := range players {
						log.Info("结束后玩家状态===", value.Status, value.Uid)
						if value.Status == uint32(message.GameStatus_Player_Status_5) {
							//GamePlayers = append(GamePlayers, userRoom[player.Uid].Players[i])
							if value.Uid != player.Uid {
								//添加第一名
								log.Info("添加第一名")
								room.RankPlayers[len(room.RankPlayers)] = value
								break
							}
						}
					}

				} else if room.RunnerNum == 1 {
					//对三个人排名 32
					addRank(room, player)
					//rank34(room, player)
					for _, value := range players {
						if value.Status == uint32(message.GameStatus_Player_Status_5) {
							//GamePlayers = append(GamePlayers, userRoom[player.Uid].Players[i])
							if value.Uid != player.Uid {
								//	room.RankPlayers = append(room.RankPlayers, value)
								//添加第一名
								log.Info("添加第一名", player.Uid)
								room.RankPlayers[len(room.RankPlayers)] = value
								break
							}
						}
					}
					//room.RankPlayers[len(room.Players)] = player

				}
				endGame(uid)
			} else {
				log.Info("下一个玩家", rsp.NextTurn)
				if rsp.NextTurn != nil {
					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
					broadInfoSz(nextPlayer)
					//log.Info("下一个人的状态", nextPlayer.Status)
					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
						time.Sleep(1 * time.Second)
						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
							go ThrowTheDice2(nextPlayer.Uid)
						}

					}

				}
			}

		} else if room.StartPlayerNum == 3 {

			if room.ArrivalNum == 1 {
				log.Warn("三个人结束了游戏")
				//三个人的情况需要排名

				//4个人的情况下要根据撞棋数排名
				//先添加失败者最后添加胜者  三个人没有逃跑的情况
				if room.RunnerNum == 0 {
					rank34(room, player)
				} else if room.RunnerNum == 1 {
					//先添加失败者最后添加胜者  三个人逃跑了一个的情况
					addRank(room, player)

				}
				endGame(uid)
			} else {
				if rsp.NextTurn != nil {
					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
					broadInfoSz(nextPlayer)
					//log.Info("下一个人的状态", nextPlayer.Status)
					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
						time.Sleep(1 * time.Second)
						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
							go ThrowTheDice2(nextPlayer.Uid)
						}

					}

				}
			}
		} else if room.StartPlayerNum == 2 {
			if room.ArrivalNum == 1 {
				log.Warn("两个人结束了游戏", len(players))
				//三个人以下的情况
				addRank(room, player)
				endGame(uid)

			} else {
				if rsp.NextTurn != nil {
					log.Info("当前玩家", *rsp.SeatID)
					log.Info("下一个玩家是谁,", *rsp.NextTurn)
					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
					broadInfoSz(nextPlayer)
					//log.Info("下一个人的状态", nextPlayer.Status)
					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
						time.Sleep(1 * time.Second)
						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
							go ThrowTheDice2(nextPlayer.Uid)
						}

					}

				}
			}
		}

	}

}

func addRank(room *GameRoom, player *GamePlayer) {
	players := room.Players

	for _, value := range players {
		//log.Warn("人员状态", value.Uid)
		if value.Status == uint32(message.GameStatus_Player_Status_3) || value.Status == uint32(message.GameStatus_Player_Status_9) {
			//还在玩的是3名
			log.Info("添加第三名", value.Uid)
			room.RankPlayers[len(room.RankPlayers)] = value
			break
		}
	}
	//先添加失败者最后添加胜者
	log.Info("添加第er名", player.Uid)
	room.RankPlayers[len(room.RankPlayers)] = player
}

func rank34(room *GameRoom, player *GamePlayer) {
	var GamePlayers = []*GamePlayer{}
	// for i := 0; i < len(players); i++ {
	// 	if players[i].Status != uint32(message.GameStatus_Player_Status_5) && players[i].Status != uint32(message.GameStatus_Player_Status_6) && players[i].Status != uint32(message.GameStatus_Player_Status_8) {
	// 		GamePlayers = append(GamePlayers, players[i])
	// 	}
	// }

	for _, value := range room.Players {
		// 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) {
		// 	GamePlayers = append(GamePlayers, value)
		// }
		if value.Status == 3 || value.Status == 9 {
			log.Info("添加第一名，第二名玩家", value.SeatId)
			GamePlayers = append(GamePlayers, value)
		}
	}
	if GamePlayers[0].FinishNum > GamePlayers[1].FinishNum {
		log.Warn("四个人结束了游戏")

		//room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
	} else if GamePlayers[0].FinishNum < GamePlayers[1].FinishNum {
		//room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
		//	room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
	} else if GamePlayers[0].FinishNum == GamePlayers[1].FinishNum {
		var total0 uint32 = 0
		for i := 0; i < len(GamePlayers[0].GamePlane); i++ {
			if GamePlayers[0].GamePlane[i].IsFly == 1 {
				if GamePlayers[0].GamePlane[i].CurPosIndex > total0 {
					total0 = GamePlayers[0].GamePlane[i].CurPosIndex
				}
			}

		}
		var total1 uint32 = 0
		for i := 0; i < len(GamePlayers[1].GamePlane); i++ {
			if GamePlayers[1].GamePlane[i].IsFly == 1 {
				if GamePlayers[1].GamePlane[i].CurPosIndex > total0 {
					total1 = GamePlayers[1].GamePlane[i].CurPosIndex
				}
			}
		}
		if total0 > total1 {
			// room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
			// room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
		} else if total0 < total1 {
			// room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
			// room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
		} else {
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
		}
	}
	//room.RankPlayers = append(room.RankPlayers, player)
	log.Info("添加第二名")
	if player != nil {
		room.RankPlayers[len(room.RankPlayers)] = player
	}

}

// 客户端通知托管
func Trusteeship(ws *websocket.Conn, data []byte) {
	req := &message.TrusteeshipReq{}
	proto.Unmarshal(data, req) //解包
	rsp := &message.TrusteeshipRsp{}

	//玩家都准备完毕了就可以游戏
	//uid := clientUserIds[ws]
	rsp.Trust = req.Trust
	uid := ClientUserIds[ws]
	player := getPlayer(uid)
	if rsp.Trust {
		player.Status = uint32(message.GameStatus_Player_Status_9)
	} else {
		player.Status = uint32(message.GameStatus_Player_Status_3)
	}
	rsp.SeatID = &player.SeatId
	rData, _ := proto.Marshal(rsp) //回包
	BroadInfo(player.GameRoom, int16(message.MSGID_Trusteeship_Rsp), rData)
}

func Quit(uid string) {
	rsp := &message.QuitRsp{}
	player := getPlayer(uid)
	if nil == player {
		BroadErrorMsg("该玩家已退出", UserClientIds[uid])
		return
	}

	room := player.GameRoom
	if room == nil {
		BroadErrorMsg("该玩家已退出房间", UserClientIds[uid])
		return
	}


	rsp.SeatID = &player.SeatId
	rsp.PlayerStatus = player.Status
	rsp.Uid=player.Uid
	rData, _ := proto.Marshal(rsp) //回包
	BroadInfo(room, int16(message.MSGID_Quit_Rsq), rData)
	if room.GameEnd==0{
		rsp3 := &message.RoomQuitUserRsp{}
		rsp3.Uid = player.Uid
		rData3, _ := proto.Marshal(rsp3) //回包
		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
	}
	
	// for key, v := range room.Players {
	// 	if v.Uid==v.Uid{

	// 	}
	// }
	//没走完逃跑的情况下

	uuid, _ := strconv.Atoi(player.Uid)
	//广播退出游戏
	log.Info("玩家退出")
	var key2 int
	//清除玩家状态

	if len(player.GameRoom.Players) == 0 {
		Dissolve_The_Game(player)
	} else {
		for key, value := range player.GameRoom.Players {
			log.Info("player----", player.Uid)
			if player.Uid == value.Uid {
				//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)

				if player.GameRoom.Homeowner == uuid {
					log.Info("查看房主信息")
					key2 = key
					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.GameRoom.Players[key].Status = 0
					//player.Status = status
					uuod := strconv.Itoa(player.GameRoom.Homeowner)
					log.Info("玩家是否移交房主", player.GameRoom.Mode)
					if player.GameRoom.Mode == 1 {
						rsp2 := &message.RoomChangeOfHomeownerRsp{}
						rsp2.Uid = uuod
						rData4, _ := proto.Marshal(rsp2) //回包
						log.Info("广播玩家移交房主", player.GameRoom.Mode)
						BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Change_Of_Homeowner_Rsp), rData4)
					}

					break
				}
			}
		}
	}

	//先判断游戏有没有结束
	if room.GameEnd == GamePlaying {
		room.PlayerNum = room.PlayerNum - 1
		//player.GameRoom = nil
		if player.Status == uint32(message.GameStatus_Player_Status_10) {
			for i := 0; i < len(room.GzPlayers); i++ {
				if room.GzPlayers[i].Uid == uid {
					room.GzPlayers = append(room.GzPlayers[:i], room.GzPlayers[i+1:]...)
					i-- // 删除元素后，需要减少索引
					break
				}
			}

		} else {
			//delete(room.Players, int(player.SeatId))
			//是否完全达到终点
			if player.Status == 5 {
				//player.Status = uint32(message.GameStatus_Player_Status_6)
				//player.Status = 0
				//要讲排名插入头插
				//胜利后逃跑如何给奖励 bug
				//不会影响游戏结算
				//只有4个人的情况下，第一名离开，才会有这情况
				room.RankPlayers[3] = player
			} else {

				room.RunnerNum = room.RunnerNum + 1

				players := room.Players
				//index越小，排名越后
				//room.RankPlayers = append(room.RankPlayers, player)
				log.Info("add rankplayer====", player.SeatId)
				room.RankPlayers[len(room.RankPlayers)] = player
				if room.StartPlayerNum == 2 {
					//log.Warn("两个人的房间直接结束游戏", room)
					//头插
					for i := 0; i < len(players); i++ {
						if players[i] != nil {
							if players[i].Uid != player.Uid {
								//room.RankPlayers = append(room.RankPlayers, players[i])
								room.RankPlayers[len(room.RankPlayers)] = players[i]
							}
						}

					}
					endGame(uid)
				} else if room.StartPlayerNum == 3 {

					if room.RunnerNum == 2 {
						log.Warn("3个人情况下逃跑了两个", room.RunnerNum)
						for i := 0; i < len(players); i++ {
							if players[i] != nil {
								if players[i].Uid != player.Uid {
									//room.RankPlayers = append(room.RankPlayers, players[i])
									room.RankPlayers[len(room.RankPlayers)] = players[i]
								}
							}

						}

						endGame(uid)
					} else {
						if room.ticker != nil {
							room.ticker.Stop()
						}

						seatId3 := getNextSeatId(player.SeatId, room)
						log.Info("返回的seatId", seatId3)
						player2 := getPlayerBySeatId(seatId3, player.GameRoom)
						log.Info("玩家退出导致的托管倒计时", player2.SeatId)
						broadInfoSz(player2)
					}
				} else if room.StartPlayerNum == 4 {

					if room.RunnerNum == 2 {
						//
						player.Status = 0
						rank34(room, nil)
						//addRank(room, player)
						endGame(uid)
					} else {
						if room.ticker != nil {
							room.ticker.Stop()
						}
						seatId2 := getNextSeatId(player.SeatId, room)
						log.Info("返回的seatId", seatId2)
						player2 := getPlayerBySeatId(seatId2, player.GameRoom)
						//player2 := getPlayerBySeatId(player.SeatId, room)
						log.Info("玩家退出导致的托管2倒计时", player2.SeatId)
						broadInfoSz(player2)
					}
				}
			}

		}

	}
	//房主退出来的话，其他玩家没有进房就会直接解散房间
	log.Info("删除用户", player.Uid,len(room.Players))
	if player.GameRoom != nil {
		 for key, v := range player.GameRoom.Players {
		 	if v.Uid == player.Uid {
		 		delete(player.GameRoom.Players, key)
		 	}
		 }
		delete(player.GameRoom.RoomPlayers, player.Uid)
	}

	//log.Info("查看删除用户", player.GameRoom.Players[int(player.SeatId)])

	delete(GamePlayers, player.Uid)
	delete(UserClientIds, uid)
	delete(ClientUserIds, UserClientIds[uid])
	if len(room.Players) == 0 {
		Dissolve_The_Game(player)
	}
}

// 退出游戏
func QuitGame(ws *websocket.Conn, data []byte) {
	req := &message.QuitReq{}
	_ = proto.Unmarshal(data, req) //解包

	//要加入逻辑，将不统计此人数据

	//玩家都准备完毕了就可以游戏
	uid := ClientUserIds[ws]
	Quit(uid)

}

func MyHeartBeatReq(ws *websocket.Conn, data []byte) {
	/*player := G.playerMng.GetPlayerByClientId(clientId)
	if player != nil {
		player.LastHeartbeat = time.Now().Unix()
	}*/
	//
	uid := ClientUserIds[ws]
	player := getPlayer(uid)
	if player != nil {
		player.LastHeartbeat = time.Now()
		log.Info("收到了心跳包",player.Uid)
		
	}
	rsp2 := &message.HeartbeatPush{}
			rData2, _ := proto.Marshal(rsp2) //回包
		sendData(ws,int16(message.MSGID_MSGID_Heartbeat_Push_Rsp),rData2)
	//5分钟清理一次socket无用连接
	//长时间没有收到用户消息就清理掉对应的socket
}

func BroadInfo(room *GameRoom, cmd int16, rData []byte) {

	if room != nil {
		//判断房主在不在游戏房间，不在也要通知
		for _, value := range room.Players {
			//log.Info("房间内玩家", value.Uid)
			//返回筛子点数广播
			ws := UserClientIds[value.Uid]
			if nil != ws {
				sendData(ws, cmd, rData)
			}
		}

		for i := 0; i < len(room.GzPlayers); i++ {
			//返回筛子点数广播
			ws := UserClientIds[room.GzPlayers[i].Uid]
			if nil != ws {
				sendData(ws, cmd, rData)
			}
		}

		// for _, player := range room.RoomPlayers {
		// 	ws := UserClientIds[player.Uid]
		// 	if nil != ws {
		// 		sendData(ws, cmd, rData)
		// 	}
		// }
	}

}
func BroadInfoRoom(room *GameRoom, cmd int16, rData []byte) {

	if room != nil {

		for _, player := range room.RoomPlayers {
			log.Info("房间内玩家", player.Uid)
			ws := UserClientIds[player.Uid]
			//log.Info("ws=====", ws)
			if nil != ws {
				sendData(ws, cmd, rData)
			}
		}
	}

}

// 广播除某些uid外的
func broadInfoExceptUid(room *GameRoom, cmd int16, rData []byte, uid string) {
	if room != nil {

		for _, player := range room.RoomPlayers {
			if player.Uid != uid {
				ws := UserClientIds[player.Uid]
				//log.Info("ws=====", ws)
				if nil != ws {
					sendData(ws, cmd, rData)
				}
			}

		}
	}
}

//退出游戏

func packageData2(cmd int16, protoData []byte, dataSize int64) []byte {
	//int32类型大小为 4 字节
	pkgsize := dataSize + 6
	pkglength := dataSize + 2
	datapkg := make([]byte, pkgsize)
	//数据长度  18
	datapkg[0] = byte((pkglength >> 24) & 0xFF)
	datapkg[1] = byte((pkglength >> 16) & 0xFF)
	datapkg[2] = byte((pkglength >> 8) & 0xFF)
	datapkg[3] = byte(pkglength & 0xFF)
	datapkg[4] = byte((cmd >> 8) & 0xFF)
	datapkg[5] = byte(cmd & 0xFF)
	//int16类型大小为 2 字节
	//数据实体
	for i, _ := range protoData {
		datapkg[i+6] = protoData[i]
	}
	protoBytes := make([]byte, len(datapkg)-6)
	for i, _ := range protoBytes {
		protoBytes[i] = datapkg[i+6]
	}
	return datapkg
}

// 发送单个玩家
func sendData(ws *websocket.Conn, cmd int16, rData []byte) {
	defer func() {
		err := recover()
		if err != nil {
			//	fmt.Println("recover panic, err:", err)
			//log.Info("游戏出错，房间重置")
			//	Dissolve_The_Game(gamePlayers[ClientUserIds[ws]])
			log.Info("发送失败说明玩家断开连接不用管，进行局部异常捕获")
		}
	}()
	pkg_data := packageData2( //匹配服务
		cmd, //返回房间列表
		rData, int64(len(rData)))
	if ws != nil {

		error := ws.WriteMessage(websocket.BinaryMessage, pkg_data)
		if error != nil {
			//Dissolve_The_Game(gamePlayers[ClientUserIds[ws]])
			//log.Info("发送失败,直接按退出处理")
			if GamePlayers[ClientUserIds[ws]] != nil {
				if GamePlayers[ClientUserIds[ws]].Status != 0 {
					GamePlayers[ClientUserIds[ws]].Status = 0
					log.Info("请求退出")
					//QuitRoom(GamePlayers[ClientUserIds[ws]], ws, 0)
				}

			}

			//delete(gamePlayers,ClientUserIds[ws])
			//delete(UserClientIds, ClientUserIds[ws])
			//delete(ClientUserIds, ws)

		}
	}

}

func GetRange(j int32, k int32, data []*scheme.SzItem) []*scheme.SzItem {
	//	data := scp.dataList
	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
	var szs = []*scheme.SzItem{}
	for i := 0; i < len(data); i++ {
		if data[i].FinialPlane == j {
			if data[i].PlayerNum == k {
				szs = append(szs, data[i])
				//szs[data[i].Ds]=data[i]
			}
		}
	}
	return szs
}

// 最后一架飞机，玩家人数小于4 ，不在终点区
func GetRange2(j int32, k int32, l int32, data []*scheme.SzItem) []*scheme.SzItem {
	//data := scp.dataList
	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
	var szs = []*scheme.SzItem{}
	for i := 0; i < len(data); i++ {
		//121 是最后一个飞机，不是最后一个玩家，是终点区
		if data[i].FinialPlane == j {
			if data[i].PlayerNum == k {
				if data[i].FinialArea == l {
					szs = append(szs, data[i])
				}

				//szs[data[i].Ds]=data[i]
			}
		}
	}
	return szs
}

// 最后一架飞机，在终点区,点数为1点的情况
func GetRange4(j int32, l int32, m int32, data []*scheme.SzItem) []*scheme.SzItem {
	//	data := scp.dataList
	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
	var szs = []*scheme.SzItem{}
	for i := 0; i < len(data); i++ {
		if data[i].FinialPlane == j {
			if data[i].FinialArea == l {
				if data[i].FinialPoint == m {
					szs = append(szs, data[i])
				}
				//szs[data[i].Ds]=data[i]
			}
		}
	}
	return szs
}
func GetUserMoneyReq(ws *websocket.Conn, data []byte) {
	//var gamePlane = GamePlane{Id: strconv.Itoa(j), Uid: uid, IsFly: 0}
	req := &message.GetUserMoneyReq{}
	_ = proto.Unmarshal(data, req) //解包
	uid2, _ := strconv.Atoi(req.Uid)
	//userrsp := Utils.GetUserInfoData(uid2)
	userrsp := Utils.GetFbData(uid2,"","",0)
	if userrsp.Code == 666 {
		BroadErrorMsg("获取金币出错", ws)
		return
	}
	rsp2 := &message.GetUserMoneyRsp{}
	var coin = uint32(userrsp.Data[0].GoldCoins)
	rsp2.Money = &coin
	rData4, _ := proto.Marshal(rsp2) //回包
	//return userrsp.Data[0].GoldCoins
	sendData(ws, int16(message.MSGID_Get_User_Money_Rsp), rData4)
}
func createPlane(j int, uid string) GamePlane {
	var gamePlane = GamePlane{Id: strconv.Itoa(j), Uid: uid, IsFly: 0}
	return gamePlane
}

func setNextTurn(canmove bool, player *GamePlayer, rsp *message.ThrowTheDiceRsp) {
	if canmove {
		skip := uint32(0)
		rsp.SkipReason = &skip
		rsp.NextTurn = &player.SeatId
	} else {
		skip := uint32(1)
		rsp.SkipReason = &skip
		nextSeatId := getNextSeatId(player.SeatId, player.GameRoom)
		log.Info("获取下一个人的uid", nextSeatId)
		rsp.NextTurn = &nextSeatId
	}

}
