using GameData; using MrWu.Debug; using Server.AliyunSDK.Logic; using Server.Data; using System; using System.Collections.Generic; using System.Text; using GameMessage; using MrWu.Basic; namespace Server { /// /// 金币场桌子 /// public partial class Desk_gold : Desk { /// /// 是否是朋友房 /// public override bool isFriend => false; /// /// 构造器 /// /// /// /// /// public Desk_gold(TingManager ting, Server.Config.TingConfig tingConfig, int id, DeskInfo info = null) : base(ting, tingConfig, id, info) { } /// /// 桌子上添加玩家 /// /// 玩家 /// 房间id /// protected override int AddPlayerArray(PlayerDataAsyc pl, int roomid) { int seat = -1; int len = Count; for (int i = 0; i < len; i++) { if (pls[i] != null && pls[i].userid == pl.userid) { Debug.Error("桌上有相同玩家:" + pl.userid); return seat; } if (pls[i] == null) { PlayerChange(pl, false); if (!GameManager.instance.SetPlayerShadow(pl, roomid)) //2020/02/22 增加 判断,没获取到影子就跳走 return seat; if (gameMode == 1 && pl.isRobot) { pl.nickname = pl.shadows[0].nickname; } pls[i] = pl; seat = i; pl.DepositChange = PlayerDepositChange; break; } } return seat; } /// /// 添加玩家 /// /// /// /// public override bool AddPlayer(PlayerDataAsyc pl, int roomid) { StringBuilder logStringBuilder = new StringBuilder(); try { if (PlayerCnt >= tingConfig.MaxPlayerCnt) { Debug.Error("玩家数量超过最大值!" + PlayerCnt + "," + id + "," + state); return false; } long key1 = Debug.StartTiming(); pl.seat = AddPlayerArray(pl, roomid); //Debug.Info("玩家上桌:" + pl.seat + ",userid:" + pl.userid); logStringBuilder.AppendLine("AddPlayerArray time:" + Debug.GetRunTime(key1)); if (pl.seat < 0) { Debug.Error("程序错误,上桌失败!"); return false; } //在桌上 pl.state = (int)PlayerState.Desk; pl.SetDeposit(false); pl.tingid = tingConfig.TingId; pl.deskid = id; if (roomid < 0) { //如果是机器人,则自动获取房间id //如果是机器人,则自动获取房间id if (!pl.isRobot) Debug.Error("程序错误,只有机器人排队才能传递小于0的值"); long key2 = Debug.StartTiming(); int len = pls.Length; for (int i = 0; i < len; i++) { PlayerDataAsyc pda = pls[i]; if (pda == null) continue; if (!pda.isRobot) { pl.roomid = pda.roomid; } } logStringBuilder.AppendLine("GetRoomid:" + Debug.GetRunTime(key2)); } else pl.roomid = roomid; RedressRobotMoney(pl); long key3 = Debug.StartTiming(); if (!pl.isRobot && GameManager.instance.isExistsRoom(roomid)) { var room = GameManager.instance.FindRoom(roomid); room.SetRoomPlayerCnt(pl); } logStringBuilder.AppendLine("SetRoomPlayerCnt time:" + Debug.GetRunTime(key3)); if (gameMode == 1) { //百家乐,发送桌上玩家信息给客户端 //发送添加玩家包 SendAddPlayer(pl); //发送所有玩家信息给玩家 SendAllPlayerInfo(pl); //开战 pl.state = (int)PlayerState.War; } else { //其他模式,发送自己信息给客户端 long key4 = Debug.StartTiming(); SendAllPlayerInfo(pl, true); logStringBuilder.AppendLine("SendAllPlayerInfo time:" + Debug.GetRunTime(key4)); } long key5 = Debug.StartTiming(); //发送场景切换 GeneralSendPack.SendSceneChange(pl, SceneType.Desk); if ((state & DeskState.War) > 0) { Debug.Error("进入桌子桌子正在开战!"); Reconnect(pl.seat); } logStringBuilder.AppendLine("SendPack time:" + Debug.GetRunTime(key5)); return true; } finally { } } protected virtual void RedressRobotMoney(PlayerDataAsyc pl) { if (pl.isRobot) { RoomManager roomManager = GameManager.instance.FindRoom(pl.roomid); if (roomManager != null) { if (pl.money < roomManager.config.MinMoney || pl.money > roomManager.config.MaxMoney) { if (roomManager.config.MinMoney < 10000) { pl.money = BaseFun.random.Next(roomManager.config.MinMoney, roomManager.config.MaxMoney); } else { int minValue = roomManager.config.MinMoney / 10000; int maxValue = roomManager.config.MaxMoney / 10000; pl.money = BaseFun.random.Next(minValue, maxValue) * 10000; } Debug.ImportantLog("纠正机器人身上的钱!"); } } else { Debug.Error($"纠正机器人Money时,不存在房间:{pl.roomid}"); } } } /// /// 从玩家列表中移除玩家 /// /// /// public override bool RemovePlayer(PlayerDataAsyc pl) { if ((state & DeskState.Idle) > 0) { return false; } PlayerDataAsyc tmppl; int len = Count; for (int i = 0; i < len; i++) { tmppl = pls[i]; if (tmppl == null) continue; if (pl.userid == tmppl.userid) { pl.seat = -1; pl.DepositChange = null; pls[i] = null; PlayerChange(pl, true); Quit(i); //玩家退出事件 //设置玩家数量 SendRemovePlayer(i); return true; } } return false; } bool strartWarError = false; /// /// 开战检查定时器 /// protected void StartWarTimer() { if (gameMode == 1) { //百家乐,有人就开战 if ((state & DeskState.Idle) > 0) return; if ((state & DeskState.War) == 0) { //未开战 //未开战 if (PlayerCnt > 0) { //闲置 但是有人,开战 Debug.Info("游戏开战:" + this.id); StartWar(); } } return; } else { //匹配模式,满人就开战 if ((state & DeskState.Queue) == 0) { //状态不是排队,跳走 return; } PlayerDataAsyc tmppl; if (PlayerCnt >= ting.config.MinPlayerCnt) { //大于最小可开战的人,全部自动准备 //Debug.Log("人到齐了,自动准备!"); int len = Count; for (int i = 0; i < len; i++) { //全部自动准备 tmppl = pls[i]; if (tmppl == null) continue; Ready(tmppl, false); //--准备 自动准备,迎合原先的设计 } //检查是否开战 bool war = true; for (int i = len - 1; i >= 0; i--) { tmppl = pls[i]; if (tmppl == null) continue; if (tmppl.state != (int)PlayerState.Ready) { war = false; if (!strartWarError) { Debug.Fatal("不该出现有人没准备的情况" + tmppl.ToString()); strartWarError = true; } break; } } if (war) { //开战 StartWar(); } else { Debug.Error("不应该存在的情况!"); ting.AddIdleing(this); } } } } /// /// 检查战斗超时的定时器 /// private int CheckWarTimeOutTimeCnt = 0; /// /// 检查战斗超时的时间间隔 /// private const int DoCheckTimeOutInterval = 60; /// /// 战斗检查超时 /// private void CheckWarTimeOutTimer() { if (gameMode == 1) //百家乐模式不检查 return; if ((state & DeskState.War) == 0) return; CheckWarTimeOutTimeCnt++; if (CheckWarTimeOutTimeCnt < DoCheckTimeOutInterval) { return; } CheckWarTimeOutTimeCnt = 0; DateTime wartimeout = DateTime.Now.AddMinutes(-warTimeOut); //Debug.Error("检查桌子是否超时:" + warTime + "," + wartimeout); //检查是否超时 if (warTime < wartimeout) //开战时间在超时之前 { //先拿到所有的玩家 List tmps = new List(pls); this.WarOver(); if (gameLogic.TimeOutWarOver()) { int cnt = tmps.Count; for (int i = cnt - 1; i >= 0; i--) { //循环所有的玩家在-在线的强制离线 if (tmps[i] != null && !tmps[i].isRobot) { Debug.Error("超时未打完!!!" + tmps[i].userid + "," + tmps[i].state + "," + tmps[i].id); GameManager.instance.QuitGame(tmps[i], "CheckWarTimeOutTimer"); } } } } } /// /// 金币场秒级定时器 /// public override void SecondTime() { //金币场模式 StartWarTimer(); CheckWarTimeOutTimer(); if ((state & DeskState.War) > 0) { PlayerDataAsyc tmppl; for (int i = Count - 1; i >= 0; i--) { tmppl = pls[i]; if (tmppl == null) { continue; } if (!tmppl.isDePosit && tmppl.outline > 0) { tmppl.OutLineTime++; if (tmppl.OutLineTime > 10) { GameManager.instance.DoTuoGuanCalc(tmppl, true); } } } } } /// /// 开战处理 /// public override void StartWar() { if (!GlobalManager.instance.IsCanWar) { SendNoWarPack(); return; } base.StartWar(); CheckWarTimeOutTimeCnt = 0; if (gameMode != 1) { PlayerDataAsyc tmppl; int len = Count; for (int i = 0; i < len; i++) { tmppl = pls[i]; if (tmppl == null) continue; if (!tmppl.isRobot) { // Debug.Error("开战发送全桌玩家信息:" + tmppl.userid); SendAllPlayerInfo(tmppl); } tmppl.state = (int)PlayerState.War; tmppl.WarMoney = 0; } } SendStartWar(); gameLogic.StartWar(); } /// /// /// public override void WarOver() { //战斗结束 处理完, // 桌子放入限制的桌子列表, 玩家状态全部在房间中, 客户端记录上次房间进入的厅,发送过来... // 人进入房间 // //要把人全部踢出桌子! /* * 1.修改房间状态 * 2.修改厅中的列表 * 3.处理玩家信息 * 4.检查房间重新排队 * * */ try { SaveGoldRecordData(); } catch (Exception e) { Debug.Error($"保存战绩出错:{e.Message}"); } if (CalculateIsRobotWin()) { ting.robotWinCnt++; } base.WarOver(); GetOverHandle().WarOver(); //发送结束信号 } /// /// 计算是否机器人胜利 /// private bool CalculateIsRobotWin() { long winMoney = 0; for (int i = 0; i < Count; i++) { if (pls[i] == null || !pls[i].isRobot) continue; winMoney += pls[i].WarMoney; } return winMoney > 0; } protected WarOverHandle generalHandle; protected WarOverHandle baijialeHandle; protected virtual WarOverHandle GetOverHandle() { if (generalHandle == null) generalHandle = new GeneralWarOver(this); if (baijialeHandle == null) baijialeHandle = new BaiJiaLeWarOver(this); if (gameMode != 1) return generalHandle; return baijialeHandle; } /// /// 保存金币场战绩记录 /// public void SaveGoldRecordData() { // 这里还要看影子数据 - 这样存下去就是真实数据 // 分类 金币模式,比赛模式,朋友房模式 与回放数据绑定 List datas = new List(); List players = new List(); for (int i = 0; i < Count; i++) { if (pls[i] == null || pls[i].isRobot || pls[i].MatchObj != null) continue; players.Clear(); for (int j = 0; j < Count; j++) { pls[j].UpdateShadow(pls[i].roomid,IsMatchDesk && !pls[i].IsJoinMatch); players.Add(new WarRecordPlayerData() { UserId = pls[j].userid, //这里有鬼的问题,后面把鬼的ID 头像固定化。不然显示要穿帮 Score = 0, //金币场暂时不存这个,这个现在统计不到 }); } RoomManager roomManager = GameManager.instance.FindRoom(pls[i].roomid); Server.Config.CastlesConfig config = roomManager?.config; WarGoldRecordItemData data = new WarGoldRecordItemData(); int shui = GameManager.instance.FindRoom(pls[i].roomid).config.Tax; data.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); data.GameId = ServerConfigManager.Instance.ClientId; data.UserId = pls[i].userid; data.Score = pls[i].WarMoney; data.Tax = shui; if (config != null) { data.BeiLv = config.BeiLv; data.Tax = config.Tax; } data.Content = players; datas.Add(data); Debug.Info($"上传玩家{pls[i].userid}金币场战绩数据"); } if (datas.Count > 0) { WarRecordSLSManager.Instance.ReportGoldAsync(datas); } } /// /// 加载桌子 /// /// public override bool LoadDesk() { return true; } /// /// /// /// /// /// public override void IncMoney(int seat, int lx, int num) { return; } /// /// /// /// public override void LoadMem(byte[] data, bool isOld) { Debug.Error("金币场不存在加载桌子内存!"); } /// /// 战斗结束的处理 /// protected interface WarOverHandle { /// /// 桌子 /// Desk_gold desk { get; } /// /// 战斗结束 /// void WarOver(); } /// /// 普通游戏的战斗结束 /// protected class GeneralWarOver : WarOverHandle { /// /// 桌子 /// public Desk_gold desk { get; private set; } /// /// 构造器 /// /// public GeneralWarOver(Desk_gold desk) { this.desk = desk; } /// /// 战斗结束处理 /// public void WarOver() { Debug.Log("普通游戏战斗结束!!!!"); //金币场超过上限检测在 进入桌子的时候 if (!desk.ting.RemoveWaring(desk)) { Debug.Error("竟然没能移出桌子!"); } bool isAllRobot = desk.RealPerson == 0; PlayerDataAsyc tmppl; int len = desk.Count; for (int i = len - 1; i >= 0; i--) { tmppl = desk[i]; if (tmppl == null) continue; if (tmppl.state == (int)PlayerState.War) { tmppl.state = (int)PlayerState.Desk; } else { Debug.Error("不可能存在的情况asdasjbdkjasb!" + tmppl.state); tmppl.state = (int)PlayerState.Desk; } if (tmppl.outline != 1) desk.SendWarOver(tmppl); if (!tmppl.isRobot) //玩家不是机器人-打完就退出桌子,此处会检查回收 desk.ting.QuitDesk(tmppl, false); if (tmppl.outline == 1) { //Debug.Error("玩家已经离线,退出桌子处理:" + tmppl); GameManager.instance.QuitGame(tmppl, "WarOver"); } } if (isAllRobot) { for (int i = len - 1; i >= 0; i--) { tmppl = desk[i]; if (tmppl == null) continue; desk.ting.QuitDesk(tmppl, false); } desk.ClearPlayer(); } } } /// /// 百家乐战斗结束 /// public class BaiJiaLeWarOver : WarOverHandle { /// /// 桌子 /// public Desk_gold desk { get; private set; } /// /// 构造器 /// /// public BaiJiaLeWarOver(Desk_gold desk) { this.desk = desk; } /// /// 战斗结束处理 /// public void WarOver() { Debug.Info("百家乐战斗结束!!!!!!" + desk.id); //检查游戏币是否超过上限,超过则把玩家踢出去-让他手动去存金币 int len = desk.Count; for (int i = len - 1; i >= 0; i--) { if (desk[i] == null) continue; if (desk[i].money >= playerData.MaxMoney) { if (desk[i].isRobot) desk[i].money -= 500000000; } } if (desk.PlayerCnt == 0) { if (desk.ting.RemoveWaring(desk)) { Debug.Error("没有人的桌子移出开战列表却失败!"); } } } } } }