Files
hjha-server/GameModule/GlobalManager/Desk.cs
xiaoou e9616125ce feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) +
game logic (GameFix/GameDAL/ServerData) +
network layer (NetWorkMessage) +
data layer (ObjectModel) +
utilities (MrWu/Core/Config/CloudAPI/dll) +
adapters (zyxAdapter/base)

.NET 8.0 C# solution, 16 projects, 958 source files
2026-07-07 12:02:15 +08:00

2380 lines
75 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 由SharpDevelop创建。
* 用户: Administrator
* 日期: 2018-11-16
* 时间: 14:38
*
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
*/
using System;
using MrWu.Debug;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Server.Data;
using Server.Pack;
using GameData;
using System.Text;
using GameDAL.FriendRoom;
using MrWu.core;
using Server.MQ;
using Server.Data.Module;
using Game.Player;
using MrWu.Basic;
using MrWu.Time;
using GameDAL;
using Newtonsoft.Json;
using Server.DB.Redis;
using GameMessage;
using ObjectModel.Game;
using Server.AliyunSDK.Logic;
using MessageData = GameData.MessageData;
using Server.Config;
using Server.Core;
using Server.DB.Sql;
namespace Server
{
/// <summary>
/// 桌子战斗结束
/// </summary>
/// <param name="StartTime">开战时间</param>
public delegate void DeksWarOver(DateTime StartTime);
/// <summary>
/// 桌上玩家数量变化
/// </summary>
/// <param name="cnt"></param>
/// <param name="isRobot"></param>
public delegate void DeskPlayerChange(int cnt, bool isRobot);
/// <summary>
/// 桌子数据
/// </summary>
public abstract class Desk : IGameUtil, IGameBehavior<GamePack>, ICollection<PlayerDataAsyc>
{
/// <summary>
/// 是否是比赛的桌子
/// </summary>
public bool IsMatchDesk;
/// <summary>
/// 是否正在恢复
/// </summary>
public bool waitRecover = false;
/// <summary>
/// 重连是否取消托管
/// </summary>
public virtual bool ReConnectCancelDeposit
{
get { return true; }
}
/// <summary>
/// 战斗结束事件
/// </summary>
public virtual event DeksWarOver WarOverHandler;
/// <summary>
/// 玩家变化事件
/// </summary>
public virtual event DeskPlayerChange PlayerChangeHandler;
public readonly CommonDeskData DeskOtherData = new CommonDeskData();
/// <summary>
/// 桌子信息
/// </summary>
public DeskInfo deskinfo { get; private set; }
private readonly int mid;
/// <summary>
/// 桌子的索引
/// </summary>
public int id => mid;
private int mRealPerson;
/// <summary>
/// 真人数量
/// </summary>
public int RealPerson => mRealPerson;
/// <summary>
/// 是否全真人且满人了
/// </summary>
public bool AllRealPerson
{
get { return RealPerson == PlayerCnt; }
}
/// <summary>
/// 游戏模式
/// </summary>
public int gameMode
{
get { return ServerConfigManager.Instance.GameMode; }
}
protected DateTime mwarTime = DateTime.Now;
/// <summary>
/// 开战时间
/// </summary>
public DateTime warTime => mwarTime;
public bool IsNearingOver
{
get;
set;
}
#region
/// <summary>
/// 总开战时间
/// </summary>
public long totalWarTime;
/// <summary>
/// 战斗次数
/// </summary>
public int warTimeCnt;
#endregion
/// <summary>
/// 战斗超时时间
/// </summary>
public int warTimeOut
{
get { return ServerConfigManager.Instance.GoldDeskWarTimeOut; }
}
/// <summary>
/// 上次未开战时玩家的人数
/// </summary>
protected int lastWiatPlayerCnt = 0;
/// <summary>
/// 桌子的状态
/// 创建桌子时 桌子为闲置状态
/// 当金币场排队时,或者朋友房等待人时 为排队状态
/// </summary>
public DeskState state { get; set; }
/// <summary>
/// 最大上桌的机器人数量
/// </summary>
public int MaxRobot
{
get { return tingConfig.DeskMaxRobotCnt; }
}
private int _halfPlayer = -1;
/// <summary>
/// 一半的最大玩家数量
/// </summary>
protected int halfPlayer
{
get
{
if (_halfPlayer < 0)
_halfPlayer = Count / 2;
return _halfPlayer;
}
}
private int _towThirds = -1;
/// <summary>
/// 最大玩家数量的三分之二
/// </summary>
protected int towThirds
{
get
{
if (_towThirds < 0)
_towThirds = 2 * Count / 3;
return _towThirds;
}
}
/// <summary>
/// 玩家列表 必须是数组_需要位置固定
/// </summary>
protected PlayerDataAsyc[] pls;
/// <summary>
/// 获取桌上的一个玩家
/// </summary>
/// <param name="idx"></param>
/// <returns></returns>
public PlayerDataAsyc this[int idx]
{
get { return pls[idx]; }
}
/// <summary>
/// 托管玩家列表
/// </summary>
public List<int> DepositList = new List<int>();
protected readonly List<int> tempUserId = new List<int>();
/// <summary>
/// 当前的玩家数量
/// </summary>
public int PlayerCnt { get; protected set; }
/// <summary>
/// 厅管理
/// </summary>
public readonly TingManager ting;
/// <summary>
/// 厅配置
/// </summary>
public readonly Server.Config.TingConfig tingConfig;
/// <summary>
///
/// </summary>
public int tingid
{
get { return ting.id; }
}
/// <summary>
/// //临时变量
/// </summary>
protected long moenyInterval;
private GameDo mgamelogic;
/// <summary>
/// 游戏逻辑
/// </summary>
public GameDo gameLogic
{
get { return mgamelogic; }
}
/// <summary>
/// 战斗数据记录
/// </summary>
public FightData fightdata { get; set; }
/// <summary>
/// 上次真人数量
/// </summary>
private int lastPlayerCount = -1;
/// <summary>
/// 上次所有玩家数量
/// </summary>
private int lastAllPlayerCount = -1;
/// <summary>
/// 上次上桌的概率
/// </summary>
private decimal robotProability = 1;
protected readonly Random random;
/// <summary>
/// 房间ID
/// </summary>
public int RoomId;
/// <summary>
///
/// </summary>
/// <param name="ting"></param>
/// <param name="tingConfig"></param>
/// <param name="id"></param>
/// <param name="info"></param>
public Desk(TingManager ting, Server.Config.TingConfig tingConfig, int id, DeskInfo info = null)
{
this.ting = ting;
this.tingConfig = tingConfig;
this.mid = id;
this.deskinfo = info;
this.random = new Random(unchecked((int)DateTime.UtcNow.Ticks));
if (isFriend)
pls = new PlayerDataAsyc[info.rule.maxCnt];
else
pls = new PlayerDataAsyc[tingConfig.MaxPlayerCnt];
}
/// <summary>
/// 设置桌子的信息
/// </summary>
/// <param name="info"></param>
public void SetDeskInfo(DeskInfo info)
{
this.deskinfo = info;
this.pls = new PlayerDataAsyc[info.rule.maxCnt];
this.PlayerCnt = 0;
}
/// <summary>
/// 清空桌子上的人
/// </summary>
public void ClearPlayer()
{
if (state != DeskState.Idle) return;
for (int i = 0; i < pls.Length; i++)
{
if (pls[i] == null) continue;
if (pls[i].isRobot) pls[i].RobotInit();
pls[i] = null;
}
}
/// <summary>
/// 设置玩家的数量
/// </summary>
/// <param name="pl"></param>
/// <param name="isquit"></param>
public void PlayerChange(PlayerDataAsyc pl, bool isquit = false)
{
int cnt = 0;
if (isquit)
{
cnt = -1;
PlayerCnt--;
if (!pl.isRobot)
mRealPerson--;
}
else
{
cnt = 1;
PlayerCnt++;
if (!pl.isRobot)
mRealPerson++;
}
if (PlayerChangeHandler != null)
this.PlayerChangeHandler(cnt, pl.isRobot);
}
/// <summary>
/// 玩家托管列表,有先后顺序
/// </summary>
public readonly List<int> DepositUserIds = new List<int>();
public Action<int> DepositChangeHandler;
/// <summary>
/// 玩家托管状态发生变化
/// </summary>
public virtual void PlayerDepositChange(playerData pl)
{
if (pl == null)
{
return;
}
if (pl.seat >= 0 && pl.seat < pls.Length && pls[pl.seat] == pl)
{
if (pl.isDePosit)
{
if (!DepositUserIds.Contains(pl.userid))
{
DepositUserIds.Add(pl.userid);
}
}
else
{
DepositUserIds.Remove(pl.userid);
}
}
DepositChangeHandler?.Invoke(pl.seat);
}
/// <summary>
/// 桌子上有玩家的设备信息发生变化
/// </summary>
public virtual void ChangePosition()
{
}
#region IGameWinMoney
/// <summary>
/// 赢的游戏币
/// </summary>
public Int64 winmoney { get; private set; }
/// <summary>
/// 税收的钱
/// </summary>
public Int64 taxmoney { get; private set; }
/// <summary>
/// 增加赢的游戏币
/// </summary>
/// <param name="money"></param>
public void AddWinMoney(long money)
{
winmoney += money;
ting.AddWinMoney(money);
}
/// <summary>
/// 增加税收的钱
/// </summary>
/// <param name="money"></param>
public void AddTaxMoney(long money)
{
taxmoney += money;
ting.AddTaxMoney(money);
}
#endregion
#region IGameBehavior
/// <summary>
/// 下一个处理者
/// </summary>
public IGameBehavior<GamePack> NextBehavior
{
get { return gameLogic; }
}
/// <summary>
/// 是否开战
/// </summary>
public bool isWar
{
get { return NextBehavior.isWar; }
}
/// <summary>
/// 开战
/// </summary>
public virtual void StartWar()
{
mwarTime = DateTime.Now;
if ((state & DeskState.Queue) > 0)
{
//开战了一般来说就不能加入了
ting.RemoveQueue(this);
}
//添加到战斗列表
ting.AddWaring(this);
}
/// <summary>
/// 处理子游戏包
/// </summary>
/// <param name="pack">包裹</param>
public void DoZyxPack(GamePack pack)
{
NextBehavior.DoZyxPack(pack);
}
/// <summary>
/// 服务器维护,发送禁止开战包
/// </summary>
public void SendNoWarPack()
{
PackHead head = PackHead.Create(GamePackAgreement.pack_error);
SendAllPack(head, new TipInfo(0, 1));
head.Dispose();
}
/// <summary>
/// 重连
/// </summary>
/// <param name="seat"></param>
public virtual void Reconnect(int seat)
{
if (ReConnectCancelDeposit)
{
GameManager.instance.DoTuoGuanCalc(pls[seat], false);
}
foreach (var item in pls)
{
if (item == null) continue;
if (item.isRobot) continue;
SendAllPlayerInfo(item);
}
SendOtherData(-1);
if ((state & DeskState.War) > 0)
{
if (seat < -1 || PlayerCnt <= seat)
{
Debug.Error("玩家重连时位置错误:" + PlayerCnt + "," + seat + "," + (pls[seat] == null));
}
NextBehavior.Reconnect(seat);
}
}
/// <summary>
/// 战斗结束
/// </summary>
public virtual void WarOver()
{
if (WarOverHandler != null)
WarOverHandler(warTime);
WarUpdateData();
}
/// <summary>
/// 计算战斗时间
/// </summary>
public void AddWarTime()
{
long tmp = (long)(DateTime.Now - warTime).TotalSeconds;
totalWarTime = totalWarTime + tmp; //战斗总时长
warTimeCnt++; //战斗次数
}
/// <summary>
/// 游戏结束更新玩家数据_去通知数据中心改变游戏币
/// </summary>
public void WarUpdateData()
{
int len = pls.Length;
for (int i = 0; i < len; i++)
{
if (pls[i] == null || pls[i].isRobot)
continue;
if (pls[i].moneyChange != 0 || pls[i].expChange != 0)
{
long key = Debug.StartTiming();
PlayerDataChange pdc = PlayerDataChange.Create(pls[i].userid);
pdc.moneyChange = pls[i].moneyChange;
pdc.expChange = pls[i].expChange;
pdc.MoneyBak = pls[i].money;
PlayerFun.WritePlayerDataAsync(pdc);
Debug.Info("写数据时间:" + Debug.GetRunTime(key));
// Debug.ImportantLog($"玩家-deskid:{pls[i].deskid},userid:{pls[i].userid},moneyChange:{pls[i].moneyChange},expChange:{pls[i].expChange}");
pls[i].moneyChange = 0;
pls[i].expChange = 0;
}
else
{
Debug.Info("玩家数据未变化:" + pls[i].userid);
}
}
}
/// <summary>
/// 加载桌子
/// </summary>
public abstract bool LoadDesk();
/// <summary>
/// 玩家离线
/// </summary>
/// <param name="seat">某座位的玩家离线</param>
public virtual void OutLine(int seat)
{
NextBehavior.OutLine(seat);
if (isFriend) //朋友房,发送玩家离线包
SendDeskInfoAll(GameSeverAgreement.friendLeave, new int[] { pls[seat].userid });
SendPlayerOutLineChange(seat);
}
/// <summary>
/// 某个座位的玩家退出了游戏
/// </summary>
/// <param name="seat">座位</param>
public virtual void Quit(int seat)
{
NextBehavior.Quit(seat);
}
/// <summary>
/// 玩家是否可以退出此桌子
/// </summary>
/// <param name="seat">座位</param>
/// <returns></returns>
public virtual bool CanQuit(int seat)
{
//判断玩家在不在桌子上, 不在桌子上肯定是不能退出的
if (deskinfo != null && !deskinfo.noWar)
return false;
if ((state & DeskState.Idle) > 0)
{
Debug.Error("玩家怎么会在闲置的桌子中,服务器错误!");
return false;
}
if (seat < 0)
{
Debug.Error("玩家不在这个桌子怎么退出桌子!" + seat);
return false;
}
return NextBehavior.CanQuit(seat);
}
#endregion
/// <summary>
/// 设置游戏逻辑
/// </summary>
/// <param name="gd"></param>
public void SetGameLogic(GameDo gd)
{
mgamelogic = gd;
}
#region ICollection
/// <summary>
/// 座位数量
/// </summary>
public int Count
{
get
{
if (!isFriend)
return tingConfig.MaxPlayerCnt;
return deskinfo.rule.maxCnt;
}
}
/// <summary>
/// 只读的
/// </summary>
public bool IsReadOnly
{
get { return true; }
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
void ICollection<PlayerDataAsyc>.Add(PlayerDataAsyc item)
{
}
/// <summary>
///
/// </summary>
void ICollection<PlayerDataAsyc>.Clear()
{
}
/// <summary>
/// 是否存在某玩家
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(PlayerDataAsyc item)
{
if (item == null)
return false;
if (item.seat < 0 || item.seat >= Count)
{
return false;
}
if (pls[item.seat] == null)
{
Debug.Warning("查询玩家数据时对应座位上的玩家不存在:" + item.ToString());
return false;
}
return true;
}
/// <summary>
/// 拷贝至array 数组中
/// </summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
public void CopyTo(PlayerDataAsyc[] array, int arrayIndex)
{
Array.Copy(pls, 0, array, arrayIndex, Count);
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool ICollection<PlayerDataAsyc>.Remove(PlayerDataAsyc item)
{
return false;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
/// <summary>
/// 迭代器
/// </summary>
/// <returns></returns>
public IEnumerator<PlayerDataAsyc> GetEnumerator()
{
return new ArrayEnumerator<PlayerDataAsyc>(pls);
}
#endregion
/// <summary>
/// 检查玩家是否有与此ip相同的
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public bool CheckPlayersIP(string ip)
{
PlayerDataAsyc tmppl;
int len = Count;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null) continue;
if (tmppl.ip == ip)
return true;
}
return false;
}
/// <summary>
/// 添加到玩家列表
/// </summary>
/// <returns>返回座位号,-1表示添加失败</returns>
protected abstract int AddPlayerArray(PlayerDataAsyc pl, int roomid);
/// <summary>
/// 加入桌子
/// </summary>
/// <param name="pl">玩家</param>
/// <param name="roomid">房间id</param>
/// <returns>true 表示加入成功 false 表示加入失败</returns>
public abstract bool AddPlayer(PlayerDataAsyc pl, int roomid);
/// <summary>
/// 从桌上移除玩家
/// </summary>
/// <param name="pl"></param>
/// <returns></returns>
public abstract bool RemovePlayer(PlayerDataAsyc pl);
/// <summary>
/// 检查房间是否是空房间
/// </summary>
/// <returns></returns>
public virtual bool CheckRoomIsEmpty()
{
return RealPerson == 0; //真人数为0表示空房间
}
#region ITimerProcessor
/// <summary>
/// 游戏定时器
/// </summary>
public virtual void OnTime(int interval)
{
if ((state & DeskState.War) > 0)
{
if (waitRecover)
{
return;
}
gameLogic.OnTime(interval);
}
}
/// <summary>
/// 秒级定时器
/// </summary>
public abstract void SecondTime();
#endregion
/// <summary>
/// 准备
/// </summary>
public virtual void Ready(PlayerDataAsyc pl, bool isSendPack = false)
{
//玩家桌子deskid 是 -1 但却在桌子列表里头
if (pl.deskid != id)
{
Debug.Error("准备出错不是本桌子:" + pl.deskid + "," + id + "," + pl.userid + "," + pl.id + "," + isSendPack);
return;
}
if (pl.state != (int)PlayerState.Desk)
{
Debug.Warning("状态不对,不是在桌上状态!" + pl.userid + "," + pl.id + "," + pl.state);
return;
}
else
{
pl.state = (int)PlayerState.Ready;
if (isSendPack)
SendPlayerStateChange(pl.seat);
Debug.Log("玩家准备好了:" + pl.userid);
}
}
public virtual async void UsingHandTracker(PlayerDataAsyc pl,UsingHandTrackerData pack)
{
if (state != DeskState.War)
{
Debug.Info("桌子的状态不是开战。使用失败!");
return;
}
//桌子信息
if (deskinfo != null)
{
Debug.Info("朋友房桌子,不让使用记牌器!");
return;
}
// //有比赛 比赛也让用
// if (pl.MatchObj != null)
// {
// Debug.Info("有比赛,不让使用记牌器");
// return;
// }
if(DeskOtherData.IsUsingHandTacker == null || pl.seat >= DeskOtherData.IsUsingHandTacker.Length)
{
Debug.Error("数据错误,记牌器数据未初始化!");
return;
}
if (DeskOtherData.IsUsingHandTacker[pl.seat])
{
Debug.Info("正在使用记牌器,无需再次使用!");
return;
}
//判断记牌器是否充足
PropManager.UserPropData propData = await PropManager.Instance.GetUserPropDataAsync(pl.userid);
if (DeskOtherData.IsUsingHandTacker[pl.seat])
{
Debug.Info("正在使用记牌器,无需再次使用!");
return;
}
if (pack.ConsumeType != 2 && pack.ConsumeType != 1)
{
Debug.Info($"没有这种消耗类型:{pack.ConsumeType} {pl.userid}");
return;
}
//钻石
if (pack.ConsumeType == 2)
{
if (pl.MatchRoll < ConstConfigCategory.Instance.HandTrackerDiamondCnt)
{
Debug.Info("使用记牌器失败,钻石不足!");
return;
}
}
if (pack.ConsumeType == 1)
{
int handTracker = propData.GetPropCount(PropType.HandTracker);
if (handTracker <= 0)
{
Debug.Info("记牌器不足!");
return;
}
}
DeskOtherData.IsUsingHandTacker[pl.seat] = true;
SendOtherData(pl.seat);
if (pack.ConsumeType == 1)
{
pack.ConsumeValue = 1;
propData.AddProp(PropType.HandTracker, -pack.ConsumeValue,"使用记牌器");
PropManager.Instance.SaveUserPropDataRedis(pl.userid, false);
}else if (pack.ConsumeType == 2)
{
pack.ConsumeValue = ConstConfigCategory.Instance.HandTrackerDiamondCnt;
PlayerDataChange pdc = PlayerDataChange.Create(pl.userid);
pdc.MatchRollChange -= pack.ConsumeValue;
_ = PlayerFun.WritePlayerDataAsync(pdc);
pl.MatchRoll -= pack.ConsumeValue;
propData.AddLog(ResName.Diamond,-pack.ConsumeValue,pl.MatchRoll,"使用记牌器");
}
SendUsingHandTrackerData(pl.seat,pack);
}
/// <summary>
/// 发送桌子其他数据
/// </summary>
/// <param name="seat"></param>
public void SendOtherData(int seat)
{
DeskOtherDataResponse response = DeskOtherDataResponse.Create(DeskOtherData);
byte[] data = MessagePackHelper.Serialize(response);
PackHead head = PackHead.Create(GameSeverAgreement.DeskOtherData);
int len = pls.Length;
string jsonData = null;
for (int i = 0; i < len; i++)
{
if (pls[i] == null) continue;
if (seat != -1 && i != seat) continue;
pls[i].SendPack2Client(head,data,false,ref jsonData);
}
response.Dispose();
head.Dispose();
}
public void SendUsingHandTrackerData(int seat,UsingHandTrackerData response)
{
if (seat < 0 || seat >= pls.Length || pls[seat] == null)
{
return;
}
Debug.Info("发送使用记牌器数据!");
byte[] data = MessagePackHelper.Serialize(response);
PackHead head = PackHead.Create(GameSeverAgreement.UsingHandTracker);
string jsonData = null;
pls[seat].SendPack2Client(head,data,false,ref jsonData);
head.Dispose();
}
/// <summary>
/// 处理道具包
/// </summary>
/// <param name="pack"></param>
/// <returns></returns>
public virtual bool DoProps(GamePack pack)
{
PropsPack cp = JsonPack.GetData<PropsPack>(pack.JsonData);
if (cp == null || cp.sendId <= 0 || cp.PropsId <= 0 || cp.Count <= 0)
{
Debug.Error("客户端发包错误:道具包无效:" + pack.JsonData);
return true;
}
//应该还要扣除玩家身上的道具
int ret = gameLogic.DoProps(cp);
if(ret < -1)
return false;
if (ret == -1)
{
//发送给所有玩家
SendAllPack(pack.Head, pack.JsonData);
}
else
{
SendPack(ret, pack.Head, pack.JsonData);
}
return false;
}
/// <summary>
/// 处理聊天包
/// </summary>
/// <param name="pack">包裹</param>
public bool DoChatPack(GamePack pack)
{
int ret = gameLogic.DoChatNewPack(pack);
if (ret < -1)
return true;
int seat = pack.pl.seat;
string jsondata = pack.JsonData;
ChatPack cp = JsonPack.GetData<ChatPack>(jsondata);
if (cp == null)
{
Debug.Error("客户端发包错误:聊天包没包体:" + jsondata);
return true;
}
PackHead head = PackHead.Create();
int roomid = pls[seat].roomid;
int len = pls.Length;
for (int i = 0; i < len; i++)
{
if (pls[i] == null) continue;
if (ret != -1 && i != ret) continue;
if (!isFriend && gameMode != 1 && seat != i)
{
//不是朋友房 且不是 百家乐
cp.sendName = pls[seat].shadows[pls[i].roomid].nickname;
Debug.Info("取影子的名字:" + seat + "," + i + "," + cp.sendName);
}
else
{
cp.sendName = pls[seat].nickname;
Debug.Info("取真实名字:" + seat + "," + i + "," + cp.sendName);
}
head.packlx = GameSeverAgreement.chatDesk;
GameNet.SendPack(pls[i], head, cp);
}
head.Dispose();
return true;
}
#region IGameUtil
/// <summary>
/// 是否是朋友房
/// </summary>
public abstract bool isFriend { get; }
/// <summary>
/// 初始化
/// </summary>
public virtual void Init()
{
DepositUserIds.Clear();
}
/// <summary>
/// 获取整数值数据
/// </summary>
/// <param name="lx">类型</param>
/// <returns></returns>
public virtual int GetIntValue(string lx)
{
switch (lx)
{
case "0": //桌上最大人数
Debug.Error("这个信息应该转至厅!");
return -1;
case "1": //桌上当前人数
return PlayerCnt;
case "2": //开战最小人数
Debug.Error("这个信息应该转至厅!");
break;
case "3": //桌所在房间id
Debug.Error("废弃字段,桌子只属于厅!");
break;
case "4": //规则idx 用的第几个规则,也就是第几个厅
return tingid;
//Debug.Error("啥规则xxx");
case "5": //是否开战中
if (isWar)
return 1;
return 0;
case "6": //开战最大人数
Debug.Error("这个信息应该去问厅要!");
break;
case "7": //是否朋友房桌子
return isFriend ? 1 : 0;
case "8": //已完成局数 原来的gameint 6 - - 0
//Debug.Error("来包获取已完成的局数!");
if (isFriend)
{
Debug.Log("已完成的局数:" + deskinfo.overCnt);
return deskinfo.overCnt;
}
break;
case "9": //当前局数-1 第几局
//Debug.Error("来包获取当前是第几局!");
if (isFriend)
{
Debug.Log("当前的局数:" + deskinfo.nowCnt);
return deskinfo.nowCnt - 1;
}
break;
case "10": //是否是vip
Debug.Log("没有vip字段!");
break;
case "11": //创建者id
if (isFriend)
return deskinfo.creatUserid;
break;
case "12": //朋友房总盘数
if (isFriend)
return deskinfo.rule.warCnt;
break;
case "13": //座位数量
//Debug.Error("这里注意--以前是固定数量,现在是动态!");
//Debug.Error("获取座位数量:" + isFriend + "," + deskinfo.rule.maxCnt);
if (isFriend)
return deskinfo.rule.maxCnt;
return Count;
case "14": //创建类型 原0玩家 1竞技比赛 2代开 现在 0普通开 1代开房间 5竞技比赛创建房间
Debug.Info("字段值已改变,注意修改!");
if (isFriend)
return deskinfo.creatStyle;
break;
// case "15"://是否托管代打房间
// AutoReady();
// break;
case "16":
return id;
case "20": //获取是否需要发牌,返回需要发牌的位置.位置从0开始-1就不需要发牌
return -1;
default:
Debug.Warning("未解析的absdjh:" + lx);
break;
}
return -1;
}
/// <summary>
/// 获取字符串类型信息
/// </summary>
/// <param name="lx">lx</param>
/// <returns></returns>
public virtual string GetStringValue(string lx)
{
switch (lx)
{
case "0":
break;
case "1":
break;
case "2":
break;
case "3":
break;
case "4":
break;
case "5": //获取朋友房桌子的规则 100个
if (isFriend)
{
Debug.Info("获取到朋友房规则:" + deskinfo.rule.roomrule);
return deskinfo.rule.roomrule;
}
break;
}
Debug.Error("暂时没有什么可以解析的!" + lx);
return string.Empty;
}
/// <summary>
/// 获取桌子数据
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public virtual object GetData(string tag)
{
return null;
}
#endregion
/// <summary>
/// 强行闪桌
/// </summary>
public void ForceWarOver()
{
if ((state & DeskState.War) == 0)
{
Debug.Warning("桌子当前未开战!");
return;
}
Debug.Warning("强制结束房间!");
gameLogic.WarOver();
}
#region
/// <summary>
/// 查某个玩家是否存在
/// </summary>
/// <param name="userid"></param>
/// <returns>true 表示玩家在桌上 false 表示玩家不在桌 </returns>
public bool Exists(int userid)
{
return FindPlayer(userid) >= 0;
}
/// <summary>
/// 是否存在某个玩家
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool isExists(int id)
{
int len = pls.Length;
for (int i = 0; i < len; i++)
{
if (pls[i] != null && pls[i].id == id)
return true;
}
return false;
}
/// <summary>
/// 查某个玩家是否存在
/// </summary>
/// <param name="pl">玩家数据</param>
/// <returns>true 表示玩家在桌上 false 表示玩家不在桌上</returns>
public bool Exists(PlayerDataAsyc pl)
{
return FindPlayer(pl) >= 0;
}
/// <summary>
/// 查找一个玩家,返回座位号,如果桌子上没有这个玩家,则返回-1
/// </summary>
/// <param name="pl"></param>
/// <returns>-1表示桌上没这个人,大于等于0表示玩家所在位置</returns>
public int FindPlayer(PlayerDataAsyc pl)
{
return FindPlayer(pl.userid);
}
/// <summary>
/// 查找一个玩家,返回座位号,如果桌子上没有这个玩家,则返回-1
/// </summary>
/// <param name="userid"></param>
/// <returns></returns>
public int FindPlayer(int userid)
{
int len = pls.Length;
for (int i = 0; i < len; i++)
{
if (pls[i] == null) continue;
if (pls[i].userid == userid)
return i;
}
return -1;
}
#endregion
#region
/// <summary>
/// 发包给所有玩家
/// </summary>
/// <param name="head">包头</param>
/// <param name="data">包数据</param>
/// <param name="userid">排除谁</param>
public void SendAllPack(PackHead head, object data = null, int userid = -1)
{
int len = Count;
PlayerDataAsyc tmppl;
int packlx = head.packlx;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null || tmppl.userid == userid) continue;
head.packlx = packlx;
GameNet.SendPack(tmppl, head, data);
}
}
/// <summary>
/// 发包给所有玩家
/// </summary>
/// <param name="head"></param>
/// <param name="jsonmessage"></param>
/// <param name="userid">排除谁</param>
public void SendAllPack(PackHead head, string jsonmessage, int userid = -1)
{
int len = Count;
PlayerDataAsyc tmppl;
int packlx = head.packlx;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null || tmppl.userid == userid) continue;
head.packlx = packlx;
GameNet.SendPack(tmppl, head, jsonmessage);
}
}
public void SendPack(int seat, PackHead head, string jsonMessage)
{
if (seat < 0 || seat >= Count)
{
return;
}
PlayerDataAsyc tmppl = pls[seat];
if (tmppl != null)
{
GameNet.SendPack(tmppl, head, jsonMessage);
}
}
/// <summary>
/// 发送子游戏包
/// </summary>
/// <param name="seat">小于0发全桌</param>
/// <param name="data">数据</param>
/// <param name="native">原生代码</param>
public virtual void SendZyxPack(int seat, byte[] data,bool native)
{
PackHead head = PackHead.Create(); //发送开战信号
head.packlx = GameSeverAgreement.zyxPack;
if ((state & DeskState.War) == 0)
{
Debug.Warning("未开战不能发送子游戏包!");
return;
}
string jsonMessage = null;
PlayerDataAsyc tempPlayer;
int len = Count;
for (int i = 0; i < len; i++)
{
if (seat < 0 || seat == i)
{
tempPlayer = pls[i];
if (tempPlayer == null) continue;
tempPlayer.SendPack2Client(head,data,native,ref jsonMessage);
}
}
if (seat >= Count)
{
Debug.Warning("发包位置大于桌子人数!" + seat + "," + PlayerCnt);
}
head.Dispose();
}
/// <summary>
/// 发送添加玩家
/// </summary>
/// <param name="pl"></param>
public virtual void SendAddPlayer(PlayerDataAsyc pl)
{
PackHead head = PackHead.Create();
int len = Count;
PlayerDataAsyc tmppl;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null || tmppl == pl || tmppl.isRobot) continue;
head.packlx = GameSeverAgreement.deskPlayerInfo;
//把替身信息发出去 是比赛桌,但是玩家没有参加比赛
pl.UpdateShadow(tmppl.roomid,IsMatchDesk && !tmppl.IsJoinMatch);
GameNet.SendPack(tmppl, head, GetAddPlayerPack(pl.seat, pl.currShadow,tmppl.ClientVer < VersionConfigCategory.Instance.CVersion48));
}
head.Dispose();
}
/// <summary>
/// 获取增加玩家包裹
/// </summary>
/// <param name="index_">第几个位置</param>
/// <param name="dt">玩家数据</param>
/// <returns></returns>
public static DeskPlayerData<PlayerDataAsyc> GetAddPlayerPack(int index_, PlayerDataAsyc dt,bool IsClone)
{
if (IsClone)
{
dt = dt.Clone();
}
return new DeskPlayerData<PlayerDataAsyc>()
{
style = 0,
index = index_,
datas = new playerData[] { dt }
};
}
/// <summary>
/// 移除一个玩家包裹
/// </summary>
/// <param name="index_">第几个玩家</param>
/// <returns></returns>
public static DeskPlayerData<PlayerDataAsyc> GetRemovePlayerPack(int index_)
{
return new DeskPlayerData<PlayerDataAsyc>()
{
style = 1,
index = index_,
datas = new playerData[0]
};
}
/// <summary>
/// 所有玩家数据
/// </summary>
/// <param name="dts">所有的玩家</param>
/// <param name="roomid">房间编号</param>
/// <returns></returns>
protected DeskPlayerData<PlayerDataAsyc> GetAllPayerPack(PlayerDataAsyc[] dts, PlayerDataAsyc pl)
{
int roomid = pl.roomid;
bool isClone = pl.ClientVer < VersionConfigCategory.Instance.CVersion48;
bool isForceShdow = IsMatchDesk && !pl.IsJoinMatch;
DeskPlayerData<PlayerDataAsyc> dp = new DeskPlayerData<PlayerDataAsyc>
{
style = 2
};
int len = dts.Length;
dp.datas = new playerData[len];
for (int i = 0; i < len; i++)
{
if (dts[i] != null)
{
dts[i].UpdateShadow(roomid,(pl.userid != dts[i].userid) && isForceShdow);
if (isClone)
{
dp.datas[i] = dts[i].currShadow.Clone();
dp.datas[i].roomid = CastleHelper.GetVirtualCastle(roomid);
}
else
{
dp.datas[i] = dts[i].currShadow;
}
Debug.Info($"GetAllPayerPack {i} {isClone} {dp.datas[i].roomid}");
//Debug.Log("用户的ip地址:" + dts[i].ip + "," + dp.datas[i].ip);
}
}
return dp;
}
/// <summary>
/// 发送移除玩家包
/// </summary>
/// <param name="seat">座位</param>
public virtual void SendRemovePlayer(int seat)
{
PackHead head = PackHead.Create();
PlayerDataAsyc tmppl;
for (int i = 0; i < Count; i++)
{
tmppl = pls[i];
if (tmppl == null) continue;
head.packlx = GameSeverAgreement.deskPlayerInfo;
GameNet.SendPack(tmppl, head, GetRemovePlayerPack(seat));
}
head.Dispose();
}
/// <summary>
/// 发送桌上所有玩家信息给玩家
/// </summary>
/// <param name="pl">发给哪个玩家</param>
/// <param name="isSelf">是否只发自己的信息</param>
public virtual void SendAllPlayerInfo(PlayerDataAsyc pl, bool isSelf = false)
{
PackHead head = PackHead.Create(GameSeverAgreement.deskPlayerInfo); // new ServerHead();
Debug.Log("发送所有玩家信息:" + pl.tingid);
if (isSelf)
{
PlayerDataAsyc[] tmppls = new PlayerDataAsyc[pls.Length];
int len = pls.Length;
int tmpcnt = 0;
for (int i = 0; i < len; i++)
{
if (pls[i] != null && pls[i].userid == pl.userid)
{
tmpcnt++;
tmppls[i] = pl;
break;
}
}
Debug.Log("发送所有玩家信息给自己:" + tmppls.Length + "," + tmpcnt);
GameNet.SendPack(pl, head, GetAllPayerPack(tmppls, pl));
}
else
GameNet.SendPack(pl, head, GetAllPayerPack(pls, pl));
head.Dispose();
}
/// <summary>
/// 发送开战信息
/// </summary>
protected virtual void SendStartWar()
{
PackHead head = PackHead.Create(GameSeverAgreement.startWar);
Debug.Log("发送房间开战信号!");
SendAllPack(head);
head.Dispose();
}
/// <summary>
/// 发送战斗结束
/// </summary>
protected virtual void SendWarOver()
{
PackHead head = PackHead.Create(GameSeverAgreement.warOver);
SendAllPack(head,"");
head.Dispose();
}
/// <summary>
/// 发送战斗数据
/// </summary>
/// <param name="pl"></param>
public virtual void SendWarOver(PlayerDataAsyc pl)
{
PackHead head = PackHead.Create(GameSeverAgreement.warOver);
GameNet.SendPack(pl, head,"");
head.Dispose();
}
/// <summary>
/// 发送桌子信息给谁_朋友房使用
/// </summary>
/// <param name="pl"></param>
/// <param name="packlx">包类型</param>
/// <param name="otherint">其他参数</param>
public virtual void SendDeskInfo(PlayerDataAsyc pl, int packlx = GameSeverAgreement.friendroominfo,
int[] otherint = null)
{
PackHead head = PackHead.Create(packlx);
if (otherint != null)
head.otherInt = otherint;
//Debug.Log("朋友房发包:" + pl.userid);
GameNet.SendPack(pl, head, deskinfo);
head.Dispose();
}
/// <summary>
/// 发送桌子信息给所有玩家
/// </summary>
public virtual void SendDeskInfoAll(int packlx = GameSeverAgreement.friendroominfo, int[] otherint = null)
{
int len = PlayerCnt;
for (int i = 0; i < len; i++)
{
if (pls[i] != null)
SendDeskInfo(pls[i], packlx, otherint);
}
}
/// <summary>
/// 朋友房结束
/// </summary>
/// <param name="style">0某局结束 1所有局数打完 2开战过 提前解散 3朋友房超时解散(24小时内未打完) 4朋友房超时解散(1小时内还没满员) 5房主解散 6玩法被删除 7管理或者会长主动解散</param>
public virtual void SendFriendRoomOver(int style)
{
int packlx = 0;
switch (style)
{
case 0:
packlx = GameSeverAgreement.over_paiju;
break;
case 1:
packlx = GameSeverAgreement.over_All;
break;
case 2:
packlx = GameSeverAgreement.over_jiesan;
break;
case 3:
packlx = GameSeverAgreement.over_timeout;
break;
case 4:
packlx = GameSeverAgreement.over_timeout_nowar;
break;
case 5:
packlx = GameSeverAgreement.over_fangzhu;
break;
case 6:
packlx = GameSeverAgreement.wayDel;
break;
case 7:
packlx = GameSeverAgreement.ClubDisBankCmd;
break;
case 8:
packlx = GameSeverAgreement.ClubMatchDisBankDeskByBurs;
break;
case 9:
packlx = GameSeverAgreement.DepositAutoDissolve;
break;
default:
packlx = GameSeverAgreement.over_jiesan;
break;
}
int len = PlayerCnt;
for (int i = 0; i < len; i++)
{
if (pls[i] != null)
SendDeskInfo(pls[i], packlx);
}
}
/// <summary>
/// 发送朋友房中的玩家信息给所有玩家
/// </summary>
/// <param name="cmd">指令类型</param>
/// <param name="userid">谁加入或者谁离开</param>
/// <param name="nickname">昵称-提示用</param>
public virtual void SendPlayersinfo(int cmd, int userid, string nickname)
{
FriendPlayersInfo fpi = new FriendPlayersInfo
{
style = cmd,
userid = userid,
nickname = nickname,
players = deskinfo.pls,
seat = deskinfo.seat,
plsDis = deskinfo.plsDis,
onceFight = deskinfo.OnceFight
};
PackHead head = PackHead.Create(GameSeverAgreement.friendroomplayers);
SendAllPack(head, fpi, userid);
head.Dispose();
}
/// <summary>
/// 发送解散信息给所有玩家
/// </summary>
/// <param name="cmd">指令</param>
/// <param name="userid">谁发起的指令</param>
/// <param name="nickname">玩家昵称</param>
public virtual void SendDisInfo(int cmd, int userid, string nickname)
{
DisInfo di = new DisInfo()
{
style = cmd,
userid = userid,
count = deskinfo.DisCount,
nickname = nickname,
requestCnt = deskinfo.RequestDissolveCnt,
isDising = deskinfo.isDising
};
PackHead head = PackHead.Create(GameSeverAgreement.disbankinfo);
SendAllPack(head, di);
head.Dispose();
}
/// <summary>
/// 发送立即战斗数据包
/// </summary>
public virtual void SendOnceFight()
{
if (deskinfo == null)
return;
PackHead head = PackHead.Create(GameSeverAgreement.questOnceFight);
head.otherInt = deskinfo.OnceFight;
SendAllPack(head, null);
head.Dispose();
}
/// <summary>
/// 发送玩家状态变化包
/// </summary>
/// <param name="seat">座位</param>
public virtual void SendPlayerStateChange(int seat)
{
if (seat < 0 || seat >= pls.Length)
{
Debug.Error("桌子数据错误{0},{1}", seat, PlayerCnt);
return;
}
pls[seat].UpdatePlayerState();
PlayerStateChangePack pscp = new PlayerStateChangePack(seat, (int)pls[seat].state);
PackHead head = PackHead.Create(GameSeverAgreement.playerStateChange);
SendAllPack(head, pscp);
head.Dispose();
}
public virtual void SendPlayerDePositChange(int seat)
{
if (seat < 0 || seat >= pls.Length)
{
Debug.Error("桌子数据错误{0},{1}", seat, PlayerCnt);
return;
}
PlayerDePositChange pack = new PlayerDePositChange(seat, pls[seat].isDePosit);
PackHead head = PackHead.Create(GameSeverAgreement.PlayerDepositChange);
SendAllPack(head, pack);
head.Dispose();
}
/// <summary>
/// 发送离线变化状态
/// </summary>
/// <param name="seat"></param>
public virtual void SendPlayerOutLineChange(int seat)
{
if (seat < 0 || seat >= pls.Length)
{
return;
}
OutLineChangePack plcp = new OutLineChangePack(seat, pls[seat].outline);
PackHead head = PackHead.Create(GameSeverAgreement.OutLineChange);
SendAllPack(head, plcp);
head.Dispose();
}
#endregion
/// <summary>
/// 消息数据
/// </summary>
/// <param name="data"></param>
public void DoMessageData(MessageData data)
{
PackHead head = PackHead.Create(GamePackAgreement.DoMessgae);
SendAllPack(head, data); //发给全桌的人
head.Dispose();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public string StateToString()
{
string result = string.Empty;
if ((DeskState.Idle & this.state) > 0)
{
result += "闲置/";
}
if ((DeskState.Queue & this.state) > 0)
{
result += "排队中/";
}
if ((DeskState.War & this.state) > 0)
{
result += "开战中/";
}
return result;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("是否朋友房:");
sb.Append(this.deskinfo != null);
sb.Append(Environment.NewLine);
sb.Append("桌子id:");
sb.Append(this.id);
sb.Append(Environment.NewLine);
sb.Append("上次等待开战的玩家数量:");
sb.Append(this.lastWiatPlayerCnt);
sb.Append(Environment.NewLine);
sb.Append("玩家数量:");
sb.Append(this.PlayerCnt);
sb.Append(Environment.NewLine);
sb.Append("是否是全部真人:");
sb.Append(this.AllRealPerson);
sb.Append(Environment.NewLine);
sb.Append("真人数量:");
sb.Append(this.RealPerson);
sb.Append(Environment.NewLine);
sb.Append("房间状态:");
sb.Append(StateToString());
sb.Append(Environment.NewLine);
sb.Append("税收:");
sb.Append(taxmoney);
sb.Append(Environment.NewLine);
sb.Append("所属厅:");
sb.Append(tingid);
sb.Append(Environment.NewLine);
sb.Append("赢的游戏币:");
sb.Append(winmoney);
sb.Append(Environment.NewLine);
sb.Append("开战时间:");
sb.Append(warTime.TimeToString());
sb.Append(Environment.NewLine);
PlayerDataAsyc tmppl;
for (int i = 0; i < Count; i++)
{
tmppl = pls[i];
if (tmppl == null) continue;
sb.Append("玩家:");
sb.Append(i);
sb.Append(Environment.NewLine);
sb.Append("userid:");
sb.Append(tmppl.userid);
sb.Append(Environment.NewLine);
sb.Append("nickName:");
sb.Append(tmppl.nickname);
sb.Append(Environment.NewLine);
sb.Append("isRobot:");
sb.Append(tmppl.isRobot);
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
/// <summary>
/// 加减钱
/// </summary>
/// <param name="seat">座位</param>
/// <param name="lx">类型</param>
/// <param name="num">类型</param>
public abstract void IncMoney(int seat, int lx, int num);
/// <summary>
/// 玩家变化
/// </summary>
/// <param name="seat"></param>
/// <param name="pl"></param>
public void ChangePlayer(int seat, PlayerDataAsyc pl)
{
pls[seat] = pl;
pl.seat = seat;
}
/// <summary>
/// 发送设备信息
/// </summary>
public void SendDeviceInfo()
{
int len = pls.Length;
//设备信息
DeviceInfo[] deviceInfos = new DeviceInfo[len];
for (int i = 0; i < len; i++)
{
if (pls[i] != null)
{
deviceInfos[i] = pls[i].device;
}
}
PackHead head = PackHead.Create();
for (int i = 0; i < len; i++)
{
if (pls[i] == null)
continue;
head.packlx = GameSeverAgreement.DeviceInfoChange;
GameNet.SendPack(pls[i], head, deviceInfos, false);
}
Debug.Info("有玩家的定位信息发生变化,更新玩家的设备信息!");
head.Dispose();
}
/// <summary>
/// 解散房间
/// </summary>
/// <param name="dskInfo">桌子信息</param>
/// <param name="style">解散类型</param>
public static void DisBank(DeskInfo dskInfo, int style = -1)
{
dskInfo.closeTime = DateTime.Now;
if (!dskInfo.noWar)
{
Debug.Info("竞技比赛房间解散:" + dskInfo.creatUserid);
SendFightRecordToClub(dskInfo, style);
}
if (dskInfo.creatStyle == 5)
{
WayManager.instance.DelDeskInfo(dskInfo.creatUserid, dskInfo.wayid, dskInfo.weiyima);
}
Room.DeleteRoom(dskInfo); //操作redis
}
/// <summary>
/// 加载内存数据
/// </summary>
/// <param name="data"></param>
public abstract void LoadMem(byte[] data, bool isOld);
/// <summary>
/// 加载内存成功,朋友房使用
/// </summary>
public virtual void LoadMemSuccess()
{
}
/// <summary>
/// 恢复桌子数据
/// </summary>
/// <param name="weiyima"></param>
/// <param name="wayId"></param>
/// <param name="isSave"></param>
public static void SendFightScore(string weiyima, string wayId, bool isSave = false)
{
var dt = GameDB.Instance.selectDb(dbbase.game2018,"RoomData",null,$"weiyima={weiyima}");
var pls = GameDB.Instance.selectDb(dbbase.game2018, "Room_Player", null, $"roomweiyima={weiyima}");
FightScore fs = new FightScore();
fs.weiyima = dt.Rows[0]["weiyima"].ToString();
fs.wayid = wayId;
fs.clubid = int.Parse(dt.Rows[0]["createid"].ToString());
fs.roomnum = int.Parse(dt.Rows[0]["roomnum"].ToString());
fs.CardNum = int.Parse(dt.Rows[0]["fangka"].ToString());// dskinfo.overCnt <= 0 ? 0 : dskinfo.fangka; //打完才计算房卡
fs.warCnt = int.Parse(dt.Rows[0]["warcnt"].ToString());// dskinfo.rule.warCnt;
fs.overCnt = int.Parse(dt.Rows[0]["overCnt"].ToString());// dskinfo.overCnt; //完整的打了多少盘
fs.game_serid = int.Parse(dt.Rows[0]["gameid"].ToString());
fs.Style = int.Parse(dt.Rows[0]["createStyle"].ToString());// style;
int capping = int.Parse(dt.Rows[0]["Capping"].ToString());
Debug.Info("game_serid:" + fs.game_serid);
fs.startTime = DateTime.Parse(dt.Rows[0]["createTime"].ToString());// dskinfo.CreateTime;
fs.endTime = DateTime.Parse(dt.Rows[0]["closeTime"].ToString()); // dskinfo.closeTime;
int len = int.Parse(dt.Rows[0]["mincnt"].ToString());
int _len = int.Parse(dt.Rows[0]["maxcnt"].ToString());
if (len != _len)
{
Debug.Error("人数不对!");
return;
}
decimal beishu = decimal.Parse(dt.Rows[0]["peilv"].ToString());
Debug.Info($"beishu:{beishu}");
fs.scores = new FightScore.Player[len];
//decimal beishu = (decimal)dskinfo.rule.peilv;
int cnt = 0;
for (int i = 0; i < len; i++)
{
var row = pls.Rows[i];
int id = int.Parse(row["playerid"].ToString());
if (id != i)
{
Debug.Error("位置不对!");
return;
}
// if (dskinfo.pls[i] != null)
{
fs.scores[i] = new FightScore.Player();
fs.scores[i].userid = int.Parse(row["userid"].ToString());// dskinfo.pls[i].userid;
fs.scores[i].name = row["nickname"].ToString();// dskinfo.pls[i].nickName;
fs.scores[i].clubId = int.Parse(row["clubid"].ToString());// dskinfo.pls[i].ClubId;
fs.scores[i].photo = "0";
//把头像换成性别给客户端使用。
//if (dskinfo.SumBurs != null && dskinfo.SumBurs.Count > 0)
{
fs.scores[i].score = decimal.Parse(row["allScore"].ToString());
}
cnt++;
}
}
decimal[] score = new decimal[len];
for (int i = 0; i < len; i++)
{
score[i] = fs.scores[i].score * beishu;
Debug.Info($"玩家的分:{score[i]}");
}
score = Room.CalcCapping(score, capping);
for (int i = 0; i < len; i++)
{
fs.scores[i].score = score[i];
}
if (cnt != len)
{
FightScore.Player[] lst = new FightScore.Player[cnt];
cnt = 0;
for (int i = 0; i < len; i++)
{
if (fs.scores[i] != null)
{
lst[cnt++] = fs.scores[i];
}
}
fs.scores = lst;
}
string jsondata = JsonConvert.SerializeObject(fs);
Debug.Info($"json:{jsondata}");
if (isSave)
{
PackHead head = PackHead.Create(ServerPackAgreement.ClubFightRecord);
GlobalMQ.instance.DeliveryEveryOne((int)ModuleType.ClubModule, GlobalMQ.CreateMessage(head, fs), true,
true);
}
}
/// <summary>
/// 发送战绩给竞技比赛
/// </summary>
public static void SendFightRecordToClub(DeskInfo dskinfo, int style = -1)
{
int len = dskinfo.pls.Length;
FightScore fs = new FightScore();
fs.weiyima = dskinfo.weiyima;
fs.wayid = dskinfo.wayid;
fs.clubid = dskinfo.creatUserid;
fs.roomnum = int.Parse(dskinfo.roomNum);
fs.CardNum = dskinfo.overCnt <= 0 ? 0 : dskinfo.fangka; //打完才计算房卡
fs.warCnt = dskinfo.rule.warCnt;
fs.overCnt = dskinfo.overCnt; //完整的打了多少盘
fs.game_serid = ServerConfigManager.Instance.GameId;
fs.Style = style;
fs.DisUserId = dskinfo.DisUserId;
Debug.Info("game_serid:" + fs.game_serid);
fs.startTime = dskinfo.CreateTime;
fs.endTime = dskinfo.closeTime;
fs.scores = new FightScore.Player[len];
decimal beishu = (decimal)dskinfo.rule.peilv;
int cnt = 0;
for (int i = 0; i < len; i++)
{
if (dskinfo.pls[i] != null)
{
fs.scores[i] = new FightScore.Player();
fs.scores[i].userid = dskinfo.pls[i].userid;
fs.scores[i].name = dskinfo.pls[i].nickName;
fs.scores[i].clubId = dskinfo.pls[i].ClubId;
fs.scores[i].photo = !string.IsNullOrWhiteSpace(dskinfo.pls[i].photo)
? dskinfo.pls[i].photo
: dskinfo.pls[i].sex.ToString();
//把头像换成性别给客户端使用。
if (dskinfo.SumBurs != null && dskinfo.SumBurs.Count > 0)
{
fs.scores[i].score = dskinfo.SumBurs[i].Score;
}
cnt++;
}
}
if (dskinfo.SumBurs == null || dskinfo.SumBurs.Count <= 0)
{
foreach (var bur in dskinfo.burs)
{
for (int i = 0; i < len; i++)
{
if (fs.scores[i] == null)
continue;
fs.scores[i].score += bur.playScore[i] * beishu;
}
}
}
if (cnt != len)
{
FightScore.Player[] lst = new FightScore.Player[cnt];
cnt = 0;
for (int i = 0; i < len; i++)
{
if (fs.scores[i] != null)
{
lst[cnt++] = fs.scores[i];
}
}
fs.scores = lst;
}
if (dskinfo.creatStyle == 5)
{
PackHead head = PackHead.Create(ServerPackAgreement.ClubFightRecord);
GlobalMQ.instance.DeliveryEveryOne((int)ModuleType.ClubModule, GlobalMQ.CreateMessage(head, fs), true,
true);
TestManager.Instance.AddGameFightData(fs);
head.Dispose();
}
try
{
//上传日志
int cnt1 = dskinfo.nowCnt != 0 ? dskinfo.nowCnt : dskinfo.overCnt;
FriendRoomFightFileInfo info = new FriendRoomFightFileInfo { weiyima = dskinfo.weiyima, overCnt = cnt1, endTime = dskinfo.closeTime };
//保存回放数据
FightRecordManager.Instance.SaveRoomInfo(dskinfo.weiyima, info);
if (dskinfo.creatStyle != 5)
{
string content = JsonPack.GetJson(fs);
List<WarFriendItemData> datas = new List<WarFriendItemData>();
for (int i = 0; i < dskinfo.pls.Length; i++)
{
if (dskinfo.pls[i] != null)
{
datas.Add(new WarFriendItemData()
{
UserId = dskinfo.pls[i].userid,
GameId = ServerConfigManager.Instance.ClientId,
WeiYiMa = dskinfo.weiyima,
Content = content
});
}
}
WarRecordSLSManager.Instance.ReportFriendAsync(datas);
}
}
catch (Exception e)
{
Debug.Error($"保存朋友房日志:{e.Message}");
}
}
/// <summary>
/// 检查玩家是否有资格解散
/// </summary>
/// <param name="pl"></param>
public bool CheckDisbank(PlayerDataAsyc pl)
{
if (!isFriend)
{
Debug.Error("不是朋友房,怎么解散桌子!");
return false;
}
if (deskinfo.creatStyle == 0 || deskinfo.creatStyle == 1)
{
//普通房间或者代开房间
if (deskinfo.creatUserid == pl.userid)
{
//是本人创建的
if (deskinfo.noWar)
{
//没开战过
return true;
}
}
}
return false;
}
public virtual void DisBank(int style = -1)
{
//朋友房完成解散
//bool isOverBank = deskinfo.overCnt == deskinfo.rule.warCnt;
gameLogic.DisBank(style);
}
/// <summary>
/// 解散房间
/// </summary>
/// <param name="style">解散类型</param>
public void DisBankAfter(int style = -1)
{
Debug.Info("解散房间,修改redis数据!");
DisBank(deskinfo, style);
if (deskinfo.nowCnt > 0)
{
//战斗中,保存战斗记录
Room.SaveFightRecord(deskinfo, fightdata, style);
}
Debug.Info("修改玩家数据!");
PlayerDataAsyc pl;
for (int i = 0; i < Count; i++)
{
pl = pls[i];
if (pl == null)
continue;
PlayerChange(pl, true);
if (!GameManager.instance.isExistsRoom(pl.roomid))
{
Debug.Warning("玩家的房间数据错误:" + pl.roomid + "," + pl.userid + "," + pl.nickname);
}
else
{
var room = GameManager.instance.FindRoom(pl.roomid);
room.SetRoomPlayerCnt(pl, true);
}
pl.seat = -1; //退出游戏
pl.deskid = -1;
pl.roomid = -1;
pl.tingid = -1;
pl.friendRoomNum = -1;
pl.friendWeiYiMa = null;
pl.state = (int)PlayerState.INGame;
//发送玩家信息
GameManager.instance.QuitGame(pl, "DisBank", deskinfo.noWar);
}
}
/// <summary>
/// 回收房间
/// </summary>
public virtual List<PlayerDataAsyc> RecoverRoom()
{
if ((state & DeskState.War) > 0)
{
Debug.Warning("开战中的房间无法回收snajknkj");
return null;
}
List<PlayerDataAsyc> result = new List<PlayerDataAsyc>();
int len = Count;
for (int i = 0; i < len; i++)
{
if (pls[i] != null)
{
result.Add(pls[i]);
PlayerChange(pls[i], true);
pls[i] = null;
}
}
return result;
}
/// <summary>
/// 百家乐机器人上桌
/// </summary>
public virtual bool RobotJoin()
{
if (MaxRobot <= 0) //不要机器人
return false;
decimal dec = 0;
//人数没变化,和上次上桌概率一样
if (lastAllPlayerCount == PlayerCnt && lastPlayerCount == RealPerson)
{
dec = robotProability;
}
else
{
//重新计算
lastAllPlayerCount = PlayerCnt;
lastPlayerCount = RealPerson;
if (lastAllPlayerCount > towThirds)
{
dec = 0;
}
else
{
dec = MaxRobot - (lastAllPlayerCount - lastPlayerCount);
dec = dec / MaxRobot;
dec = dec * dec;
if (lastAllPlayerCount > halfPlayer)
dec = dec * (1 - ((decimal)lastAllPlayerCount / Count));
}
}
if (dec < 0)
dec = 0;
//计算概率上桌
return dec != 0 && BaseFun.Probability((double)dec);
}
public virtual void Close()
{
if (state == DeskState.War && deskinfo != null && fightdata != null && fightdata.fightPack.Count > 0)
{
try
{
Debug.Info("保存战绩!!!");
if (!Directory.Exists("fightRecord"))
{
Directory.CreateDirectory("fightRecord");
}
string jsonData = JsonConvert.SerializeObject(fightdata);
//desk.deskinfo.weiyima, desk.deskinfo.burs.Count, onedata
string fileName =
$"{RedisDictionary.friendRoomfightRecord}{deskinfo.burs.Count}:{deskinfo.weiyima}";
fileName = fileName.Replace(":", "");
File.WriteAllText($"fightRecord/{fileName}", jsonData);
}
catch (Exception e)
{
Debug.Error($"保存回放数据报错:{e.Message}");
}
}
}
}
}