Files
hjha-server/GameModule/GlobalManager/TingManager.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

883 lines
25 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
* 时间: 9:27
*
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
*/
using System;
using Server.Pack;
using System.Collections;
using System.Collections.Generic;
using MrWu.Debug;
using Server.Data;
using System.Text;
using System.Threading;
using GameData;
using Game.Robot;
using GameMessage;
using Server.Core;
namespace Server
{
/// <summary>
/// 厅管理
/// </summary>
public abstract class TingManager : IGameUtil, ICollection<Desk>, IGameMessage<GamePack>
{
/*
* 所有的桌子
* 闲置的桌子
* 排队的桌子
* 开战中的桌子
*
* 有玩家来排队时创建桌子desk
* 把desk添加至排队中的桌子列表
*
* 当桌子开战时,告诉厅管理从闲置的桌子中移除桌子 把桌子添加至 开战中的桌子
*
* 当玩家退出桌子时,检查桌子是不是只有机器人
* 如果是,清空桌子,把桌子添加到闲置的桌子列表
*
* 当桌子战斗结束时,告诉厅管理从开战中的桌子放置排队中的桌子列表 如果真人没满,把里面的真人尽量往别的桌子凑
* (前提是去别的桌子后比现在的桌子人多)
* 查看玩家连续赢的次数在一桌连续赢了超过5局则换房间
*
* 桌子不清楚
*
* */
#region ICollection
/// <summary>
/// 桌子数量
/// </summary>
public int Count
{
get { return desks.Count; }
}
/// <summary>
/// 是否是只读
/// </summary>
public bool IsReadOnly
{
get { return true; }
}
void ICollection<Desk>.Add(Desk item)
{
}
void ICollection<Desk>.Clear()
{
}
/// <summary>
/// 是否存在某个桌子
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(Desk item)
{
if (item == null)
return false;
return item.id >= 0 && item.id < Count;
}
void ICollection<Desk>.CopyTo(Desk[] array, int arrayIndex)
{
desks.CopyTo(array, arrayIndex);
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool ICollection<Desk>.Remove(Desk item)
{
return false;
}
/// <summary>
/// 迭代器
/// </summary>
/// <returns></returns>
public IEnumerator<Desk> GetEnumerator()
{
return desks.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// 桌子
/// </summary>
/// <param name="idx"></param>
/// <returns></returns>
public Desk this[int idx]
{
get { return desks[idx]; }
}
/// <summary>
/// 是否要动态回收桌子
/// </summary>
protected virtual bool isRecycle
{
get { return true; }
}
#endregion
#region
/// <summary>
/// 战斗次数
/// </summary>
public int warCnt;
/// <summary>
/// 总战斗时间
/// </summary>
public long totalwarTime;
/// <summary>
/// 平均战斗时间
/// </summary>
public long avgWarTime
{
get
{
if (warCnt == 0)
return 0;
return totalwarTime / warCnt;
}
}
/// <summary>
/// 最大开战时间
/// </summary>
public long maxWarTime;
/// <summary>
/// 最短开战时间
/// </summary>
public long minWarTime = long.MaxValue;
/// <summary>
/// 玩家的数量
/// </summary>
public int PlayerCnt;
/// <summary>
/// 机器人数量
/// </summary>
public int RobotCnt;
/// <summary>
/// 真人数量
/// </summary>
public int RealCnt;
/// <summary>
/// 机器人胜利次数
/// </summary>
public int robotWinCnt;
#endregion
/// <summary>
/// 厅配置
/// </summary>
public readonly Server.Config.TingConfig config;
/// <summary>
/// 所有的房间
/// </summary>
public readonly IList<Desk> desks = new List<Desk>();
#region
/// <summary>
/// 闲置的桌子数量
/// </summary>
public int IdleCount
{
get { return idle.Count; }
}
/// <summary>
/// 闲置的桌子
/// </summary>
protected readonly IList<Desk> idle = new List<Desk>();
/// <summary>
/// 添加到闲置的桌子
/// </summary>
public void AddIdleing(Desk desk)
{
if ((desk.state & DeskState.Queue) > 0)
RemoveQueue(desk);
if ((desk.state & DeskState.War) > 0)
RemoveWaring(desk);
//闲置的桌子没有其他状态
desk.state = DeskState.Idle | desk.state;
idle.Add(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("AddIdleing Id of Same");
}
else
{
Debug.Error("AddIdleing Error Thread is not Same!");
}
}
/// <summary>
/// 移除闲置的桌子
/// </summary>
/// <param name="desk"></param>
/// <returns></returns>
public bool RemoveIdle(Desk desk)
{
bool r = idle.Remove(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("RemoveIdle Id of Same");
}
else
{
Debug.Error("RemoveIdle Error Thread is not Same!");
}
if (r)
desk.state = desk.state & ~DeskState.Idle;
return r;
}
#endregion
#region
/// <summary>
/// 排队桌子的数量
/// </summary>
public int QueueCount
{
get { return queueing.Count; }
}
/// <summary>
/// 排队中的桌子
/// </summary>
public readonly IList<Desk> queueing = new List<Desk>();
/// <summary>
/// 添加到排队中的桌子队列
/// </summary>
public void AddQueueing(Desk desk)
{
desk.state = DeskState.Queue | desk.state;
queueing.Add(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("AddQueueing Id of Same");
}
else
{
Debug.Error("AddQueueing Error Thread is not Same!");
}
}
/// <summary>
/// 移除排队中的桌子
/// </summary>
/// <param name="desk"></param>
/// <returns></returns>
public bool RemoveQueue(Desk desk)
{
bool r = queueing.Remove(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("RemoveQueue Id of Same");
}
else
{
Debug.Error("RemoveQueue Error Thread is not Same!");
}
if (r)
desk.state = desk.state & ~DeskState.Queue;
return r;
}
#endregion
#region
/// <summary>
/// 开战的桌子数量
/// </summary>
public virtual int WarCount
{
get { return waring.Count; }
}
/// <summary>
/// 战斗中的
/// </summary>
protected readonly IList<Desk> waring = new List<Desk>();
/// <summary>
/// 添加到战斗中的桌子
/// </summary>
/// <param name="desk"></param>
public void AddWaring(Desk desk)
{
waring.Add(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("AddWaring Id of Same");
}
else
{
Debug.Error("AddWaring Error Thread is not Same!");
}
desk.state = DeskState.War | desk.state;
}
/// <summary>
/// 移除战斗中的桌子
/// </summary>
/// <param name="desk"></param>
/// <returns></returns>
public bool RemoveWaring(Desk desk)
{
bool r = waring.Remove(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("RemoveWaring Id of Same");
}
else
{
Debug.Error("RemoveWaring Error Thread is not Same!");
}
if (r)
desk.state = desk.state & ~DeskState.War;
return r;
}
#endregion
/// <summary>
/// 游戏模式
/// </summary>
public int gameMode
{
get { return ServerConfigManager.Instance.GameMode; }
}
/// <summary>
///
/// </summary>
/// <param name="config"></param>
public TingManager(Server.Config.TingConfig config)
{
this.config = config;
int len = config.DeskCnt;
for (int i = 0; i < len; i++)
{
CreateNewDesk();
}
}
#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)
{
// Debug.Warning("赢取的金额:" + money);
winmoney += money;
}
/// <summary>
/// 添加税收的钱
/// </summary>
/// <param name="money"></param>
public void AddTaxMoney(long money)
{
// Debug.Warning("税收增加:" + money);
taxmoney += money;
}
#endregion
/// <summary>
/// 有玩家退出桌子
/// </summary>
public abstract bool QuitDesk(PlayerDataAsyc pl, bool isSendPack);
#region
/// <summary>
/// 获取桌子
/// </summary>
/// <param name="deskstate">要的桌子状态,一般来说,不会获取开战的桌子</param>
/// <param name="deskinfo">桌子信息</param>
/// <returns></returns>
public virtual Desk GetDesk(DeskState deskstate = DeskState.Queue | DeskState.Idle, DeskInfo deskinfo = null)
{
Desk desk = null;
//要排队的,优先获取排队的
if ((deskstate & DeskState.Queue) > 0)
{
//要排队的
if (QueueCount > 0)
desk = queueing[0];
}
if (desk == null && (deskstate & DeskState.Idle) > 0)
{
//如果没拿到桌子,要闲置的
if (IdleCount > 0)
{
//有闲置的,直接获取闲置的
desk = idle[0];
if (deskinfo != null)
{
desk.SetDeskInfo(deskinfo);
}
}
if (desk == null)
{
//还是没拿到 创建新桌子
desk = CreateNewDesk(deskinfo);
}
}
return desk;
}
/// <summary>
/// 创建一个新桌子
/// </summary>
/// <returns></returns>
protected Desk CreateNewDesk(DeskInfo deskinfo = null)
{
Desk desk = GameManager.instance.factory.CreateDesk(this, config, Count, deskinfo);
desk.WarOverHandler += DeskWarOver;
desk.PlayerChangeHandler += PlayerChange;
desks.Add(desk);
if (Thread.CurrentThread.ManagedThreadId == ServerConst.MainThreadId)
{
Debug.Info("CreateNewDesk Id of Same");
}
else
{
Debug.Error("CreateNewDesk Error Thread is not Same!");
}
AddIdleing(desk); //刚创建的桌子
return desk;
}
/// <summary>
/// 根据桌号获取指定桌子
/// </summary>
/// <param name="deskid"></param>
/// <returns></returns>
public virtual Desk GetDeskByDeskId(int deskid)
{
return null;
}
#endregion
/// <summary>
/// 战斗结束
/// </summary>
/// <param name="warTime"></param>
protected void DeskWarOver(DateTime warTime)
{
long tmp = (long)(DateTime.Now - warTime).TotalSeconds;
warCnt++;
//总战斗时间
totalwarTime = totalwarTime + tmp;
if (tmp < minWarTime)
minWarTime = tmp;
if (tmp > maxWarTime)
maxWarTime = tmp;
}
/// <summary>
/// 用户数量变化
/// </summary>
/// <param name="cnt"></param>
/// <param name="isRobot"></param>
protected void PlayerChange(int cnt, bool isRobot)
{
PlayerCnt += cnt;
if (isRobot)
RobotCnt += cnt;
else
RealCnt += cnt;
}
/// <summary>
/// 进入厅
/// </summary>
public abstract bool InTing(PlayerDataAsyc pl, int roomid, ref string errinfo, ref int errorcode, int deskid = -1, string pwd = "",
bool isClub = false);
#region ITimerProcessor
/// <summary>
/// 定时器
/// </summary>
public virtual void OnTime(int Interval)
{
//先检查朋友房的厅中,是否有朋友房桌子需要解散的, --- 自动解散掉
int len = desks.Count;
for (int i = len - 1; i >= 0; i--)
{
desks[i].OnTime(Interval);
}
}
/// <summary>
/// 定时器处理
/// </summary>
public abstract void SecondTime();
#endregion
/// <summary>
/// 是否存在某个桌子
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool isExists(int id)
{
return id >= 0 && id < Count;
}
#region IGameUtil
/// <summary>
/// 厅id
/// </summary>
public int id
{
get { return config.TingId; }
}
/// <summary>
/// 是否是朋友房
/// </summary>
public abstract bool isFriend { get; }
/// <summary>
/// 初始化
/// </summary>
public virtual void Init()
{
foreach (var it in desks)
{
it.Init();
}
}
/// <summary>
/// 获取厅信息
/// </summary>
/// <param name="lx">字段类型</param>
/// <returns>-1表示无效</returns>
public virtual int GetIntValue(string lx)
{
switch (lx)
{
case "0": //桌子数量 0表示动态生成桌子 >0表示预先生成桌子!
if (config.DeskCnt <= 0)
return 0;
return config.DeskCnt;
case "1": //最小开战人数
return config.MinPlayerCnt;
case "2": //最大开战人数
return config.MaxPlayerCnt;
case "3": //游戏模式
Debug.Error("转至游戏配置!");
break;
case "4": //获取厅的输赢
int money = (int)(winmoney / 100);
Debug.Log("获取厅赢的钱:" + money);
return money;
default:
Debug.Error("为解析的厅信息:" + lx);
break;
}
return -1;
}
/// <summary>
/// 获取厅字符串信息
/// </summary>
/// <param name="lx">字段类型 0:获取厅的所有规则</param>
/// <returns></returns>
public virtual string GetStringValue(string lx)
{
switch (lx)
{
case "0": //获取厅的所有规则
return config.TingGz;
}
Debug.Warning("没有啥厅字符串信息" + lx);
return string.Empty;
}
/// <summary>
/// 获取厅数据
/// </summary>
/// <returns></returns>
public virtual object GetData(string tag)
{
return null;
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="pl"></param>
public abstract void Ready(PlayerDataAsyc pl);
/// <summary>
/// 使用记牌器
/// </summary>
/// <param name="pl"></param>
public virtual void UsingHandTracker(PlayerDataAsyc pl, UsingHandTrackerData pack)
{
if (pl.deskid < 0 || pl.deskid >= Count)
{
Debug.Warning("没有这个桌子!");
return;
}
Debug.Info("使用记牌器!");
desks[pl.deskid].UsingHandTracker(pl, pack);
}
#region IGameMessage
/// <summary>
/// 处理子游戏包
/// </summary>
/// <param name="pack"></param>
public virtual void DoZyxPack(GamePack pack)
{
if (pack.pl.deskid < 0 || pack.pl.deskid >= desks.Count || pack.pl.seat < 0)
{
Debug.Warning("userid :" + pack.pl.userid + ",deskid:" + pack.pl.deskid + ",seat:" + pack.pl.seat);
return;
}
desks[pack.pl.deskid].DoZyxPack(pack);
}
/// <summary>
/// 处理聊天包
/// </summary>
/// <param name="pack"></param>
public virtual bool DoChatPack(GamePack pack)
{
if (pack.pl.deskid < 0 || pack.pl.deskid >= desks.Count || pack.pl.seat < 0)
{
Debug.Warning("DoChatPack userid:" + pack.pl.userid + ",deskid:" + pack.pl.deskid + ",seat:" +
pack.pl.seat);
return false;
}
return desks[pack.pl.deskid].DoChatPack(pack);
}
/// <summary>
/// 处理道具包
/// </summary>
/// <param name="pack"></param>
public virtual bool Drops(GamePack pack)
{
if (pack.pl.deskid < 0 || pack.pl.deskid >= desks.Count || pack.pl.seat < 0)
{
Debug.Warning("Drops userid:" + pack.pl.userid + ",deskid:" + pack.pl.deskid + ",seat:" + pack.pl.seat);
return false;
}
return desks[pack.pl.deskid].DoProps(pack);
}
#endregion
/// <summary>
/// 重连
/// </summary>
/// <param name="deskid"></param>
/// <param name="seat"></param>
public virtual void Reconnect(int deskid, int seat)
{
if (deskid < 0 || deskid >= desks.Count)
{
Debug.Warning("deskid :" + deskid + ",count:" + desks.Count);
return;
}
desks[deskid].Reconnect(seat);
}
/// <summary>
/// 检查两个玩家的之间的作弊等级
/// </summary>
/// <param name="pl"></param>
/// <param name="other"></param>
public virtual Tuple<int, int> CheckCheatingLevel(PlayerDataAsyc pl, PlayerDataAsyc other)
{
int myLevel = 0;
int otherLevel = other.device.zuobichengdu;
if (pl.device.GetPosition().isEmpty)
{
//无法定位
myLevel = 1;
}
//计算距离
//100米 内 高 500米内 中 1000米内 低
double distance = WorldPosition.GetDistance(pl.device.GetPosition(), other.device.GetPosition());
if (distance <= 50)
{
myLevel = 4;
if (otherLevel < myLevel)
otherLevel = myLevel;
}
else if (distance <= 500)
{
myLevel = 3;
if (otherLevel < myLevel)
otherLevel = myLevel;
}
else if (distance <= 1000)
{
myLevel = 2;
if (otherLevel < myLevel)
otherLevel = myLevel;
}
if (!string.IsNullOrEmpty(pl.device.wifimac) && !string.IsNullOrEmpty(other.device.wifimac))
{
if (pl.device.wifimac == other.device.wifimac)
{
//同一个wifi
myLevel = 4;
otherLevel = 4;
}
}
// if (pl.ip == other.ip) {
// myLevel = 4;
// otherLevel = 4;
// }
//Debug.Log("计算距离:" + distance + "," + myLevel);
return new Tuple<int, int>(myLevel, otherLevel);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("tingid:");
sb.Append(id);
sb.Append(Environment.NewLine);
sb.Append("deskCnt:");
sb.Append(this.Count);
sb.Append(Environment.NewLine);
sb.Append("是否朋友房:");
sb.Append(this.isFriend);
sb.Append(Environment.NewLine);
sb.Append("机器人数量:");
sb.Append(RobotController.instance.GetParCount(id));
sb.Append(Environment.NewLine);
sb.Append("税钱:");
sb.Append(this.taxmoney);
sb.Append(Environment.NewLine);
sb.Append("赢的游戏:");
sb.Append(this.winmoney);
sb.Append(Environment.NewLine);
sb.Append("总桌子:");
sb.Append(this.desks.Count + "," + this.Count);
sb.Append(Environment.NewLine);
sb.Append("闲置的桌子:");
sb.Append(this.IdleCount);
sb.Append(Environment.NewLine);
sb.Append("开战的桌子:");
sb.Append(this.WarCount);
sb.Append(Environment.NewLine);
sb.Append("排队中的桌子:");
sb.Append(this.QueueCount);
sb.Append(Environment.NewLine);
return sb.ToString();
}
public virtual void Close()
{
for (int i = 0; i < desks.Count; i++)
{
if (desks[i] != null)
{
desks[i].Close();
}
}
}
}
}