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

2008 lines
67 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 GameData;
using Game.Player;
using Game.Robot;
using Game.Shadow;
using GameDAL;
using GameDAL.Backend;
using GameDAL.Game;
using MrWu.Debug;
using ObjectModel.Config;
using ObjectModel.Game;
using Server.Data;
using Server.DB.Redis;
using Server.MQ;
using Server.Pack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Server.Core;
using zyxAdapter;
using GameMessage.Const;
using GameMessage;
using NetWorkMessage;
using Server.Config;
using Server.Data.Module;
using MessageData = GameData.MessageData;
/*
* 包明细
* 玩家信息包
* 游戏信息包
* 桌子其他玩家信息包
* 指令包{
* 1.上桌
* 2.重连
* 3.开战
* 4.战斗结束
* }
*
* 行为包
*
* */
namespace Server
{
/// <summary>
/// 游戏管理 单线程操作
/// </summary>
public partial class GameManager : IGameUtil, IGameMessage<GamePack>
{
/// <summary>
/// 游戏管理
/// </summary>
public static GameManager instance { get; private set; }
static IHostUtil m_dllUtil;
/// <summary>
/// c# 调用子游戏dll的方法
/// </summary>
public static IHostUtil dllUtil
{
get
{
if (m_dllUtil == null)
{
m_dllUtil = instance.factory.CreateHostUtil();
}
return m_dllUtil;
}
}
/// <summary>
/// 游戏配置
/// </summary>
public Config.GameConfig config;
/// <summary>
/// 游戏单元工厂
/// </summary>
public readonly GameUtilFactory factory;
/// <summary>
/// 影子管理
/// </summary>
public readonly ShadowPool shadowPool;
#region ,,
/// <summary>
/// 房间数量
/// </summary>
public readonly int roomCnt;
/// <summary>
/// 房间
/// </summary>
public readonly RoomManager[] rooms;
/// <summary>
/// 厅数量
/// </summary>
public readonly int tingCnt;
/// <summary>
/// 厅-管理桌子控制玩法
/// </summary>
private readonly TingManager[] tings;
/// <summary>
/// 朋友房厅
/// </summary>
public TingManager friendTing
{
get
{
if (isFriend)
{
return tings[tingCnt - 1];
}
return null;
}
}
/// <summary>
/// 朋友房城堡
/// </summary>
public RoomManager friendRoom
{
get
{
if (isFriend)
{
return rooms[roomCnt - 1];
}
return null;
}
}
/// <summary>
/// 获取所有的桌子
/// </summary>
public int deskCnt
{
get
{
int sum = 0;
foreach (var item in tings)
{
sum += item.Count;
}
return sum;
}
}
/// <summary>
/// 闲置的桌子数量
/// </summary>
public int idleDeskCnt
{
get
{
int sum = 0;
foreach (var item in tings)
{
sum += item.IdleCount;
}
return sum;
}
}
/// <summary>
/// 排队中的桌子数量
/// </summary>
public int queueDeskCnt
{
get
{
int sum = 0;
foreach (var item in tings)
{
sum += item.QueueCount;
}
return sum;
}
}
/// <summary>
/// 开战中的桌子数量
/// </summary>
public int warDeskCnt
{
get
{
int sum = 0;
foreach (var item in tings)
{
sum += item.WarCount;
}
return sum;
}
}
/// <summary>
/// 开战次数
/// </summary>
public int warCnt
{
get
{
int sum = 0;
foreach (var item in tings)
{
sum += item.warCnt;
}
return sum;
}
}
#endregion
#region
/// <summary>
/// 消耗的房卡
/// </summary>
public int DelFangKa;
/// <summary>
/// 登录次数
/// </summary>
public long loginCnt { get; set; }
/// <summary>
/// 重连次数
/// </summary>
public long reConnection { get; protected set; }
#endregion
/// <summary>
/// 不用检查进入房间--测试同桌
/// </summary>
public bool noCheckAddDesk;
/// <summary>
/// 禁止同桌的玩家
/// </summary>
public NoDeskMatesAllowedInfo NoDeskPlayers = new NoDeskMatesAllowedInfo();
/// <summary>
/// 充值的商品列表
/// </summary>
public List<ChongZhiShangPing> ShangPings = null;
/// <summary>
/// 构造器
/// </summary>
/// <param name="config">游戏配置</param>
/// <param name="factory">游戏单元工厂</param>
public GameManager(Server.Config.GameConfig config, GameUtilFactory factory)
{
if (instance == null)
instance = this; //子类继承了 这个this 就是子类
this.factory = factory;
this.config = config;
shadowPool = factory.GetShadowPool();
RobotController.instance = new RobotController(this, ServerConfigManager.Instance.RobotMinMoney, ServerConfigManager.Instance.RobotMaxMoney);
//PlayerCollection.instance = new PlayerCollection(config.maxPlayer);
int len = ServerConfigManager.Instance.Tings.Length;
tingCnt = len;
tings = new TingManager[len];
len = ServerConfigManager.Instance.Castles.Length;
roomCnt = len;
rooms = new RoomManager[len];
GetNoDeskPlayerInfo();
if (ServerConfigManager.Instance.OpenFriend > 0)
{
FightRecordManager.Instance.Init(config.GameId);
}
GameDispatcher.Instance.AddListener(GameMsgId.UserCurrencyChange,OnCurrencyChange);
}
/// <summary>
/// 获取不能同桌的玩家信息
/// </summary>
void GetNoDeskPlayerInfo()
{
//如果获取不到值就3分钟后再获取
NoDeskPlayers.GetTime = DateTime.Now.AddMinutes(3);
//Task.Factory.StartNew(() =>
//{ //逻辑简单不异步做
try
{
string str = DeskPlayerDal.GetNoDeskPlayer();
Debug.Info("获取禁止同桌信息:" + str);
if (!string.IsNullOrWhiteSpace(str))
{
NoDeskPlayers.PlayerIds = JsonPack.GetData<List<NoDeskPlayerInfo>>(str);
NoDeskPlayers.GetTime = DateTime.Now.AddMinutes(30);
}
}
catch (Exception e)
{
Debug.Error($"获取禁止同桌信息出错 msg:{e.Message} code:{e.StackTrace}");
}
//});
}
// /// <summary>
// /// 获取玩家禁止同桌的信息
// /// </summary>
// /// <param name="userid"></param>
// /// <returns>有就返回有的值没有就是Null</returns>
// public string GetNoDeskPlayerInfoById(int userid)
// {
// if (userid <= 0) return null;
// if (NoDeskPlayers.PlayerIds == null || NoDeskPlayers.PlayerIds.Count <= 0) return null;
// string s = userid.ToString();
// foreach (var item in NoDeskPlayers.PlayerIds)
// {
// if (item == null || item.UserIds == null || item.UserIds.Length < 1) continue;
// if (item.UserIds.IndexOf(s) >= 0)
// {
// return item.UserIds;
// }
// }
// return null;
// }
#region IGameWinMoney
/// <summary>
/// 赢的游戏币
/// </summary>
public Int64 winmoney { get; private set; }
/// <summary>
/// 税收的游戏币
/// </summary>
public Int64 taxmoney { get; private set; }
/// <summary>
///
/// </summary>
public void AddWinMoney(long money)
{
winmoney += money;
}
/// <summary>
/// 添加税收的钱
/// </summary>
/// <param name="money"></param>
public void AddTaxMoney(long money)
{
taxmoney += money;
}
#endregion
#region ITimerProcessor
/// <summary>
/// 定时器
/// </summary>
public virtual void OnTime(int Interval)
{
// if (NoDeskPlayers.GetTime <= DateTime.Now)
// {
// GetNoDeskPlayerInfo();
// }
// Debug.Info("GameManager 定时器:" + System.DateTime.Now.Ticks);
foreach (RoomManager rm in rooms)
{
rm.OnTime(Interval);
}
foreach (TingManager tm in tings)
{
tm.OnTime(Interval);
}
}
/// <summary>
/// 秒级定时器
/// </summary>
public virtual void SecondTime()
{
// Debug.Info("秒级定时器:" + System.DateTime.Now.Ticks);
try
{
//var xxx = Debug.StartTiming();
//SaveClubWarRecordToRedis();
//double runtimexx = Debug.GetRunTime(xxx);
// if (runtimexx > 100)
// {
// Debug.Error($"保存数据xxx:{runtimexx}");
// }
//BisaiManager.instance.SecondTime(); //暂时没有比赛
foreach (RoomManager rm in rooms)
{
rm.SecondTime();
}
foreach (TingManager tm in tings)
{
tm.SecondTime();
}
}
catch (Exception e)
{
Debug.Error($"定时器出错,msg:{e.Message},code:{e.StackTrace}");
}
}
public virtual async void DayInit()
{
ShangPings = await ChongZhiShangPingDal.GetAllShangPingsAsync();
}
#endregion
#region
/// <summary>
/// 是否存在某个房间
/// </summary>
/// <param name="roomid">房间id</param>
/// <returns>true 表示存在房间 false 表示不存在房间</returns>
public bool isExistsRoom(int roomid)
{
return roomid >= 0 && roomid < roomCnt;
}
/// <summary>
/// 获取城堡
/// </summary>
/// <param name="roomid"></param>
/// <returns></returns>
public RoomManager FindRoom(int roomid)
{
if (!isExistsRoom(roomid))
return null;
return rooms[roomid];
}
/// <summary>
/// 是否存在某个厅
/// </summary>
/// <param name="tingid"></param>
/// <returns></returns>
public bool isExistsTing(int tingid)
{
return tingid >= 0 && tingid < tingCnt;
}
/// <summary>
/// 查找厅
/// </summary>
/// <param name="tingid"></param>
/// <returns></returns>
public TingManager FindTing(int tingid)
{
if (!isExistsTing(tingid))
return null;
return tings[tingid];
}
/// <summary>
/// 获取桌子
/// </summary>
/// <param name="tingid">厅id</param>
/// <param name="deskid">桌子id</param>
/// <returns>获取桌子</returns>
public Desk FindDesk(int tingid, int deskid)
{
if (!isExistsTing(tingid) || !tings[tingid].isExists(deskid))
{
return null;
}
return tings[tingid].desks[deskid];
}
#endregion
/// <summary>
/// Rpc 逻辑
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public virtual bool DoRPC(WaitBeMsg msg)
{
switch (msg.head.packlx)
{
case ServerPackAgreement.AddPlayerZiChanNum: //给用户加资产信息
DoAddPlayerZiChanNum(msg.head, msg.jsondata);
break;
case ServerPackAgreement.RechargeOrders: //处理充值订单
break;
default:
Debug.Fatal("未处理的服务器内部消息" + msg.head.packlx);
break;
}
return true;
}
/// <summary>
/// 给用户加资产信息--目的只是为了同步服务器的内存
/// </summary>
/// <param name="head"></param>
/// <param name="jsondata"></param>
public virtual void DoAddPlayerZiChanNum(PackHead head, string jsondata)
{
if (string.IsNullOrWhiteSpace(jsondata)) return;
AddZiChanPack data = JsonPack.GetData<AddZiChanPack>(jsondata);
if (data.datas == null || data.datas.Count <= 0) return;
foreach (var item in data.datas)
{
AddPlayZiChan(item);
}
}
void AddPlayZiChan(AddZiChanInfo data)
{
if (data == null || data.UserId <= 0) return;
Debug.ImportantLog($"收到给玩家加资产包:{data}");
var pl = PlayerCollection.Instance.FindPlayerByUserId(data.UserId);
if (pl == null) return;
switch (data.lx)
{
// 类型 1游戏币 2保险柜*1万 3参赛卷 4复活卡 5门票 6礼券 7金砖
case 1:
pl.money += data.Num;
break;
case 6:
pl.coupon += (int)data.Num;
break;
case 7:
pl.MatchRoll += (int)data.Num;
break;
default:
Debug.Info($"GameManager 给用户加资产有未处理的类型:{pl.userid} {data.lx}");
break;
}
}
private void OnCurrencyChange(object param)
{
if (param is UserCurrencyChangeMessage currencyChangeMessage)
{
if (currencyChangeMessage.ResDatas == null)
{
Debug.Info("resData is null!");
return;
}
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(currencyChangeMessage.UserId);
if (pl == null)
{
Debug.Info($"not find Player:{currencyChangeMessage.UserId}");
return;
}
foreach (var resData in currencyChangeMessage.ResDatas)
{
switch (resData.Id)
{
case ResName.RoomCard:
pl.fangka += (int)resData.Count;
break;
case ResName.Diamond:
pl.MatchRoll += (int)resData.Count;
break;
case ResName.Gold:
pl.money += resData.Count;
break;
case ResName.Wincoupon:
pl.coupon += (int)resData.Count;
break;
default:
Debug.Error($"同步货币数据失败,未知的资源类型:{resData.Id}");
break;
}
}
}
}
/// <summary>
/// 是否写金币扣税日志
/// </summary>
/// <param name="pl"></param>
/// <returns></returns>
public virtual bool IsWriteKouShuiLog(PlayerDataAsyc pl)
{
return true;
}
/// <summary>
/// 收包处理
/// </summary>
/// <param name="pk"></param>
public virtual bool DoPack(GamePack pk)
{
//Debug.Info($"收到包类型:{pk.head.packlx}");
bool doRlt = true;
switch (pk.Head.packlx)
{
case GameSeverAgreement.Login: //玩家登录包
if (!LoginManager.Instance.IsCanLogin) //服务器维护,不让登录
{
//ServerHead head = pk.head;
//head.packlx = GamePackAgreement.pack_error;
//GameNet.SendPack(pk.head.userid,head,new TipInfo(0,1));
//ServerHeadPool.PutServerHead(ref head);
return true;
}
DoLogin(pk);
break;
case GameSeverAgreement.createFriendRoom: //玩家创建房间
FriendRoomManager.instance.CreatFriendRoom(pk);
break;
case GameSeverAgreement.joinWay: //快速加入
FriendRoomManager.instance.DoWanFa(pk);
break;
case GameSeverAgreement.CreateClubDesk: //创建竞技比赛桌子
FriendRoomManager.instance.DoClubCreateDesk(pk);
break;
case GameSeverAgreement.JoinClubDesk: //加入竞技比赛桌子
//进入俱乐部桌子
FriendRoomManager.instance.JoinClubDesk(pk);
break;
case GameSeverAgreement.ClubDisBankCmd: //会长解散桌子
FriendRoomManager.instance.ClubDisBankCmd(pk);
break;
case GameSeverAgreement.ClubMatchDisBankDeskByBurs: //小局结算不够房间最低分,解散桌子
Debug.Log("收到小局解散包");
FriendRoomManager.instance.ClubMatchDisBankByBurs(pk);
break;
case GameSeverAgreement.ClubOutPlayer: //竞技比赛踢出玩家
FriendRoomManager.instance.DoClubOutPlayer(pk);
break;
case GameSeverAgreement.SwitchClubRoom: //切换俱乐部房间
FriendRoomManager.instance.QuitGameJoinOther(pk);
break;
/*
* 0720 吴补 加入玩法拆分成3个
* 1.指定桌子加入房间
* 2.创建桌子加入房间
* 3.优先加入房间,没有加入再创建桌子加入房间
*
* */
case GameSeverAgreement.joinFriendRoom: //玩家加入朋友房
FriendRoomManager.instance.DoJoinRoom(pk);
break;
case ServerPackAgreement.DisConnection: //有玩家离线
// Debug.Error("接收到玩家离线包!");
DisConnection(pk);
break;
case GameSeverAgreement.friendlastInfo: //朋友房上场信息
break;
case GameSeverAgreement.friendfightdata: //回放包
FriendRoomManager.instance.DoHuiFang(pk);
break;
case GameSeverAgreement.DeviceInfoPack: //设备信息包
DoDeviceInfoPack(pk);
break;
case GameSeverAgreement.outlineGuji: //离线挂机包
DoGuaJi(pk);
break;
case GameSeverAgreement.PlayerDePosit: //玩家托管包
DoTuoGuan(pk);
break;
//新增竞技比赛主动解散桌子 需要的参数竞技比赛id 玩法id 桌子唯一码
default:
doRlt = false;
break;
}
if (doRlt)
return true;
if (!CheckPack(pk))
return false;
switch (pk.Head.packlx)
{
case GameSeverAgreement.AddBalanceConfig:
LuckPlayerManager.Instance.AddBalanceConfig(pk);
break;
case GameSeverAgreement.RemoveBalanceConfig:
LuckPlayerManager.Instance.RemoveBalanceConfig(pk);
break;
case GameSeverAgreement.EditorBalanceConfig:
LuckPlayerManager.Instance.EditorBalanceConfig(pk);
break;
case GameSeverAgreement.GetBalanceConfigs:
LuckPlayerManager.Instance.GetBalanceConfig(pk);
break;
case GameSeverAgreement.AddBalancePlayerConfig:
LuckPlayerManager.Instance.AddBalancePlayerConfig(pk);
break;
case GameSeverAgreement.RemoveBalancePlayerConfig:
LuckPlayerManager.Instance.RemoveBalancePlayerConfig(pk);
break;
case GameSeverAgreement.EditorBalancePlayerConfig:
LuckPlayerManager.Instance.EditorBalancePlayerConfig(pk);
break;
case GameSeverAgreement.GetBalancePlayerConfig:
LuckPlayerManager.Instance.GetBalancePlayerConfig(pk);
break;
case GameSeverAgreement.AddRoomRateRule:
LuckPlayerManager.Instance.AddRoomRateRuleConfig(pk);
break;
case GameSeverAgreement.RemoveRoomRateRule:
LuckPlayerManager.Instance.RemoveRoomRateRuleConfig(pk);
break;
case GameSeverAgreement.AddRoomRateRuleItem:
LuckPlayerManager.Instance.AddRoomRateRuleItemConfig(pk);
break;
case GameSeverAgreement.RemoveRoomRateRuleItem:
LuckPlayerManager.Instance.RemoveRoomRateRuleItemConfig(pk);
break;
case GameSeverAgreement.GetRoomRateRuleItem:
LuckPlayerManager.Instance.GetRoomRateRuleConfig(pk);
break;
case GameSeverAgreement.getPlayerData_Test: //获取玩家数据,测试用
GameNet.SendPack(pk.pl, pk.Head, pk.pl);
break;
case GameSeverAgreement.InDesk: //上桌包
DoInDesk(pk);
break;
case GameSeverAgreement.comBack: //返回
DoComBack(pk);
break;
case GameSeverAgreement.readyPk: //准备包
ReadyPack(pk);
break;
case GameSeverAgreement.UsingHandTracker: //使用记牌器
UsingHandTracker(pk);
break;
case GameSeverAgreement.chatDesk: //聊天包
DoChatPack(pk);
break;
case GameSeverAgreement.GiveProps: //赠送道具包
DoProps(pk);
break;
case GameSeverAgreement.zyxPack: //子游戏包
DoZyxPack(pk);
break;
case GameSeverAgreement.Props: //发送道具包
break;
case GameSeverAgreement.dissFriendRoomCmd: //解散房间包
FriendRoomManager.instance.DisBankDesk(pk);
break;
case GameSeverAgreement.placedissRoom: //请求解散包
FriendRoomManager.instance.placeDisBank(pk);
break;
case GameSeverAgreement.disreponse: //解散回复
FriendRoomManager.instance.DisReponse(pk);
break;
case GameSeverAgreement.questOnceFight: //请求立即开战
FriendRoomManager.instance.placeOnceFight(pk);
break;
case GameSeverAgreement.voiceData: //语音包
_DoVoice(pk);
break;
default:
Debug.Error("未解析的包:" + pk.Head.packlx);
return false;
}
return true;
}
#region
/// <summary>
/// 玩家登录收包处理
/// </summary>
protected async Task DoLogin(GamePack pack)
{
//过滤包,不是本模块处理抛出
Debug.Info("收到登录包:" + pack.Head.userid);
DeviceInfo deviceinfo = JsonPack.GetData<DeviceInfo>(pack.JsonData);
if (deviceinfo == null)
{
Debug.Error("登录失败,玩家的设备信息是null");
return;
}
if (string.IsNullOrEmpty(pack.Head.ip))
{
Debug.Error("玩家的ip 地址怎么会是空......");
}
//var ip = GetNoDeskPlayerInfoById(pack.head.userid);//如果是禁止同桌的人就设置相同Ip
//Debug.Info("ip:" + ip + "," + pack.head.ip);
LoginInfo loginInfo = LoginInfo.Create(pack.Head.userid, false, pack.Head.GetUtil(), pack.Head.ip,
deviceinfo,
pack.Head.clientVer, pack.Head);
await LoginManager.Instance.Start(loginInfo);
loginInfo.Dispose();
}
#endregion
#region
/// <summary>
/// 处理设备信息包
/// </summary>
protected void DoDeviceInfoPack(GamePack pk)
{
Debug.Info("接收到设备信息!" + pk.JsonData);
pk.pl = PlayerCollection.Instance.FindPlayerByUserId(pk.Head.userid);
if (pk.pl == null)
{
//玩家信息为空!
Debug.Warning("收到设备信息包,玩家数据为空!" + pk.Head.userid);
return;
}
DeviceInfo info = JsonPack.GetData<DeviceInfo>(pk.JsonData);
var pl = pk.pl;
//更新设备信息
pl.UpdateDeviceInfo(info);
var desk = FindDesk(pl.tingid, pl.deskid);
if (desk != null)
{
//有桌子则更新 没桌子不处理
desk.ChangePosition();
}
}
/// <summary>
/// 处理离线挂机包
/// </summary>
protected void DoGuaJi(GamePack pack)
{
int userid = pack.Head.userid;
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(userid);
if (pl == null)
{
Debug.Error("处理挂机包时 玩家已离线:" + pl.userid);
}
else
{
pl.isGuaji = !pl.isGuaji;
}
}
/// <summary>
/// 语音包
/// </summary>
/// <param name="pk"></param>
protected void _DoVoice(GamePack pk)
{
int userid = pk.Head.userid;
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(userid);
if (pl == null)
{
Debug.Error("处理语音包时,未找到玩家!");
}
else
{
var desk = FindDesk(pl.tingid, pl.deskid);
if (desk == null)
{
Debug.Error("未找到玩家所在的桌子-发送语音失败:" + pl.ToString());
return;
}
Debug.Info("收到语音包!!!!");
desk.SendAllPack(pk.Head, pk.JsonData, pl.userid);
}
}
/// <summary>
/// 玩家网络连接中断处理
/// </summary>
/// <param name="pk"></param>
protected void DisConnection(GamePack pk)
{
}
/// <summary>
/// 退出房间
/// </summary>
/// <param name="pl"></param>
public virtual bool QuitRoom(PlayerDataAsyc pl)
{
//退出房间
RoomManager room = FindRoom(pl.roomid);
if (room == null)
{
//房间为null
Debug.Error("数据错误,没找到这个房间!roomid:{0},state:{1},id:{2}", pl.roomid, pl.state, pl.userid);
return false;
}
else
{
if (room.Quit(pl))
{
//退出房间!
GeneralSendPack.SendSceneChange(pl, SceneType.InGame); //把玩家扔到选城堡
return true;
}
else
{
return false;
}
}
}
#endregion
/// <summary>
/// 处理玩家托管逻辑
/// </summary>
/// <param name="pl"></param>
/// <param name="isDeposit">true托管 false取消托管</param>
public void DoTuoGuanCalc(PlayerDataAsyc pl, bool isDeposit)
{
if (pl == null || pl.isRobot) return;
if (isDeposit)
{
//托管
//托管次数增加 2、记录开始托管时间
if (pl.isDePosit)
{
Debug.ImportantLog($"托管中又收到托管包 id:{pl.userid} name:{pl.nickname}");
}
else
{
pl.DePositCount++;
pl.DePositTime = DateTime.Now;
}
}
else
{
//取消托管 //根据开始时间和取消托管的时间来计算托管时长
if (!pl.isDePosit)
{
Debug.ImportantLog($"是取消托管状态,又取消托管 id:{pl.userid} name:{pl.nickname}");
}
if (pl.DePositTime != default(DateTime))
{
pl.DePositSecon += (int)DateTime.Now.Subtract(pl.DePositTime).TotalSeconds;
pl.DePositTime = default(DateTime);
}
}
pl.SetDeposit(isDeposit);
pl.AutoDepositTime = 0;
Debug.Info($"收到玩家userid{pl.userid} nickname{pl.nickname} {(isDeposit ? "" : "")}");
}
/// <summary>
/// 玩家托管
/// </summary>
/// <param name="pk">head.otherInt 1托管 2取消托管</param>
protected virtual void DoTuoGuan(GamePack pk)
{
if (pk.Head.otherInt == null || pk.Head.otherInt.Length != 1) return;
if (pk.pl == null)
pk.pl = PlayerCollection.Instance.FindPlayerByUserId(pk.Head.userid);
if (pk.pl == null) return;
var desk = FindDesk(pk.pl.tingid, pk.pl.deskid);
if (desk != null && pk.Head.otherInt[0] == 1 && desk.state != DeskState.War)
{
return;
}
DoTuoGuanCalc(pk.pl, pk.Head.otherInt[0] == 1);
if (desk != null)
{
foreach (var item in desk)
{
if (item == null) continue;
if (item.isRobot) continue;
desk.SendAllPlayerInfo(item);
}
//todo 发送玩家托管状态 上面的发送所有玩家信息可以屏蔽 20250211
//desk.SendPlayerDePositChange(pk.pl.seat);
}
}
#region
/// <summary>
/// 处理进入桌子
/// </summary>
/// <param name="pk"></param>
protected virtual void DoInDesk(GamePack pk)
{
if (pk.pl == null)
{
Debug.Error("玩家进入桌子数据错误 pl is null:" + pk.Head.userid);
return;
}
//先判断能不能进入桌子
InDeskPack idp = JsonPack.GetData<InDeskPack>(pk.JsonData);
Debug.Info($"原始的房间:{idp.roomid}");
if (pk.pl.ClientVer < VersionConfigCategory.Instance.CVersion48) //转换成真实的房间id
{
idp.roomid = CastleHelper.GetRealCastle(idp.roomid);
Debug.Info($"转换成真实的房间:{idp.roomid}");
}
//int idroom = FindRightRoom(pk.pl.money);
//Debug.ImportantLog($"idroom:{idroom} idproom{idp.roomid} ");
//xu添加如果客户端发送过来的房间ID不合适就服务器给他找一个合适的房间ID
idp.roomid = isRightRoom(pk.pl.money, idp.roomid) ? idp.roomid : FindRightRoom(pk.pl.money);
Debug.Info($"最终计算出正确的房间:{idp.roomid} {pk.pl.money}");
if (!isExistsRoom(idp.roomid))
{
Debug.Warning("Client Pack Error roomCnt:{0},inRoomid:{1}", roomCnt, idp.roomid);
return;
}
//判断玩家游戏币是否超过上限
if (pk.pl.money < ServerConfigManager.Instance.Castles[idp.roomid].MinMoney)
{
Debug.Error($"MinMoney Error:{pk.pl.money} {idp.roomid}");
}
RoomManager rm = rooms[idp.roomid];
rm.InRoom(pk.pl, idp.tingid, idp.deskid);
}
/// <summary>
/// 查找合适的房间
/// </summary>
/// <param name="mymoney"></param>
/// <returns></returns>
public int FindRightRoom(long mymoney)
{
int len = config.OpenFriend > 0 ? ServerConfigManager.Instance.Castles.Length - 2 : ServerConfigManager.Instance.Castles.Length - 1;
//-2 是去掉一个朋友房
for (int i = len; i >= 0; i--)
{
if (i == len)
{
if (mymoney >= ServerConfigManager.Instance.Castles[i].MinMoney)
{
return i;
}
}else if (mymoney < ServerConfigManager.Instance.Castles[i].MaxMoney && mymoney >= ServerConfigManager.Instance.Castles[i].MinMoney)
{
return i;
}
}
Debug.Error($"未找到正确的房间 {len}");
return len; // mymoney > config.castles[len].maxMoney ? len:-1;
}
public bool isRightRoom(long mymoney, int roomid)
{
if (roomid < 0 || roomid >= ServerConfigManager.Instance.Castles.Length) return false;
int len = config.OpenFriend > 0 ? ServerConfigManager.Instance.Castles.Length - 2 : ServerConfigManager.Instance.Castles.Length - 1;
if (roomid > len) return false;
//最后一个房间
if (roomid == len && mymoney >= ServerConfigManager.Instance.Castles[roomid].MaxMoney) return true;
return mymoney < ServerConfigManager.Instance.Castles[roomid].MaxMoney && mymoney >= ServerConfigManager.Instance.Castles[roomid].MinMoney;
}
#endregion
#region
/// <summary>
/// 准备
/// </summary>
/// <param name="pk"></param>
protected virtual void ReadyPack(GamePack pk)
{
var ting = FindTing(pk.pl.tingid);
if (ting != null)
ting.Ready(pk.pl);
else
Debug.Warning("玩家准备出错,没有玩家所在的厅:" + pk.pl.tingid);
}
#endregion
/// <summary>
/// 使用记牌器
/// </summary>
/// <param name="pk"></param>
protected virtual void UsingHandTracker(GamePack pk)
{
UsingHandTrackerData pack = MessagePackHelper.Deserialize<UsingHandTrackerData>(pk.Data);
var ting = FindTing(pk.pl.tingid);
if (ting != null)
ting.UsingHandTracker(pk.pl,pack);
else
Debug.Warning("玩家准备出错,没有玩家所在的厅:" + pk.pl.tingid);
}
/// <summary>
/// 检查包裹的正确性
/// </summary>
/// <param name="pk"></param>
/// <returns></returns>
protected virtual bool CheckPack(GamePack pk)
{
if (pk.Head.packlx != GameSeverAgreement.Login)
{
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(pk.Head.userid);
if (pl == null)
{
Debug.Error("没找到发包的人:" + pk.Head.packlx + "," + pk.Head.userid);
return false;
}
if (pl.userid != pk.Head.userid)
{
Debug.Error("userid不对!" + pl.userid + "," + pk.Head.userid);
return false;
}
if (pl.outline == 1 || pl.state == (int)PlayerState.NOGame)
{
Debug.Warning("玩家没在线!!");
return false;
}
pk.pl = pl;
return true;
}
return true;
}
/// <summary>
///
/// </summary>
protected readonly DistributedLock loginLock = new DistributedLock(100);
private void resumePlayer(PlayerDataAsyc pl)
{
long key = Debug.StartTiming();
var playerData = PlayerFun.GetPlayerData(pl.userid);
if (playerData != null)
{
pl.money = playerData.money + pl.moneyChange;
pl.fangka = playerData.fangka;
pl.gold = playerData.gold;
}
double runtime = Debug.GetRunTime(key);
if (runtime > 200)
Debug.Error("玩家重连,获取玩家数据慢!" + runtime);
}
/// <summary>
/// 玩家重连
/// </summary>
/// <param name="pl"></param>
/// <param name="socket"></param>
public void Reconnect(PlayerDataAsyc pl, ServerNode socket)
{
Debug.Info("重连进入游戏:" + pl.userid);
reConnection++;
#region 2019/11/10
if (pl.userid > 0)
{
resumePlayer(pl);
}
#endregion
//处理重连
pl.outline = 0;
pl.OutLineTime = 0;
pl.socketUtil = socket;
GeneralSendPack.SendGameInfo(pl); //游戏信息
if (pl.deskid >= 0)
{
Desk desk = FindDesk(pl.tingid, pl.deskid);
if (desk == null)
{
Debug.Error("玩家的厅或桌子id 错误:" + pl.tingid + "," + pl.deskid);
return;
}
if (pl.friendRoomNum > 0)
{
//朋友房发送朋友房信息
desk.SendDeskInfo(pl);
}
if (pl.shadows == null)
{
if (friendTing == null || friendTing.id != pl.tingid)
Debug.Error("玩家在桌上却没有影子:" + pl.userid + "," + pl.deskid
+ "," + pl.seat + "," + pl.roomid + "," + pl.tingid + ","
+ pl.friendRoomNum + "," + pl.doShadows);
}
GeneralSendPack.SendSceneChange(pl, SceneType.Desk); //有桌子进入桌子
tings[pl.tingid].Reconnect(pl.deskid, pl.seat);
}
else
{
//Debug.Error($"怎么会没桌子 {pl.userid} {pl.deskid}");
GeneralSendPack.SendSceneChange(pl, SceneType.InGame); //没桌子就是进入游戏
}
}
/// <summary>
/// 检查玩家数据是否与数据空中的一致
/// </summary>
private void CheckPlayerdata(PlayerDataAsyc pl)
{
//验证玩家的游戏币是否与Redis 中的一致
Thread thread = new Thread(
() =>
{
var pldata = PlayerFun.GetPlayerData(pl.userid);
Debug.ImportantLog("检查玩家数据是否与数据空中的一致 xxuu");
if (pldata == null)
{
Debug.Warning("未取得玩家数据!");
}
else
{
if (pl.money != pldata.money || pl.fangka != pldata.fangka || pl.gold != pldata.gold ||
pl.coupon != pldata.coupon)
Debug.Error("玩家数据与数据库中的值不一致:" + pl.userid + "," + pl.nickname + ",money:" + pl.money
+ "," + pldata.money + ",fangka:" + pl.fangka + "," + pldata.fangka + ",gold:" +
pl.gold + "," + pldata.gold
+ "coupon:" + pl.coupon + "," + pldata.coupon);
}
}
);
}
/// <summary>
/// 退出游戏-在线列表中删除
/// </summary>
/// <param name="pl"></param>
/// <param name="tag">标记,哪个入口来的,为了查询问题用</param>
/// <param name="isSendPack">是否发送场景切换包</param>
public virtual void QuitGame(PlayerDataAsyc pl, string tag = "", bool isSendPack = true)
{
if (pl.isRobot)
{
Debug.Error("机器人哪有退出游戏的概念???");
return;
}
if (isSendPack)
{
GeneralSendPack.SendSceneChange(pl, SceneType.Main); //把玩家扔到大厅
Debug.Info("退出游戏发包!");
}
if (pl.deskid >= 0)
{
Debug.Error("玩家离线时玩家deskid 还有值:" + pl.userid + "," + pl.deskid + "," + pl.roomid + "," + tag);
}
if (pl.state != (int)PlayerState.INGame)
{
Debug.Error("玩家离线时,玩家的状态不对:" + pl.userid + "," + pl.state + "," + tag);
}
pl.outline = 1;
pl.OutLineTime = 0;
//如果这个玩家本来就下线了,那就不执行下面的逻辑
if (pl.id >= 0 && PlayerCollection.Instance.RemovePlayer(pl) == 1)
{
//移除在线玩家
if (pl.shadowsInfo != null) //退出游戏放回替身
shadowPool.PutShadows(pl.shadowsInfo);
PlayerFun.SavePlayerData(pl.userid);
if (!PlayerFun.UnLockPlayer(pl.userid, GameBase.instance.myUtil))
{
//解锁玩家
Debug.Error("玩家未能正常解锁!" + pl.userid);
}
PropManager.Instance.SaveUserPropDataRedis(pl.userid,true);
//保存玩家输赢战绩
_ = SaveUserWarDataAsync(pl);
//TODO 玩家下线行为 上报
Task.Factory.StartNew(() =>
{
var temp = pl;
Debug.ImportantLog($"玩家下线 1 userid:{temp.userid} money:{temp.money}");
SaveGameLog(temp);
});
}
}
private async Task SaveUserWarDataAsync(PlayerDataAsyc pl)
{
if (pl.WarData != null)
{
UserWarDataModel model = pl.WarData;
pl.WarData = null;
await UserWarDataDal.SaveUserWarDataAsync(model).ConfigureAwait(false);
ReferencePool.Recycle(model);
}
}
public readonly dbbase sqldb = dbbase.gamedb;
/// <summary>
/// 保存玩家游戏金钱日志
/// </summary>
/// <param name="pl"></param>
void SaveGameLog(PlayerDataAsyc pl)
{
if (pl == null || pl.userid <= 0 || config == null) return;
if (Math.Abs(pl.WinMoney + pl.BiSiMoney) <= 10000000) return;
var sql =
$"insert into sh_log4(userid,money_bak,money_pay,game_id,hjha_loginmoney,hjha_playcount,kxgc_change) values({pl.userid},{(pl.money)},{pl.WinMoney},{config.GameId},{pl.MoneyBak},{pl.Pan},{pl.BiSiMoney})";
int i = 0;
try
{
i = sqldb.ExecuteNonQuery(sql);
}
catch (Exception e)
{
Debug.Error($"保存玩家游戏金钱日志 数据出错,sql:{sql} msg:{e.Message}, code:{e.StackTrace}");
}
}
/// <summary>
/// 玩家离线-只修改状态
/// </summary>
/// <param name="pl"></param>
/// <param name="sendSceneChange">是否发送场景切换包</param>
public virtual void OutLine(PlayerDataAsyc pl, bool sendSceneChange = true)
{
if (sendSceneChange)
GeneralSendPack.SendSceneChange(pl, SceneType.Main);
pl.outline = 1;
pl.OutLineTime = 0;
pl.socketUtil = null;
//玩家在桌子上 通知桌子某个玩家掉线了
var desk = FindDesk(pl.tingid, pl.deskid);
Debug.Info($"离线离线:{pl.userid}");
if (desk != null)
{
desk.OutLine(pl.seat);
}
}
/// <summary>
/// 设置玩家影子
/// </summary>
/// <param name="pl"></param>
/// <param name="roomid"></param>
public bool SetPlayerShadow(PlayerDataAsyc pl, int roomid)
{
return shadowPool.SetPlayerShadow(pl, roomid, roomCnt, rooms);
}
/// <summary>
/// 获取有这个厅的房间id
/// </summary>
/// <param name="tingid"></param>
/// <param name="roomid">在哪个房间中找</param>
/// <returns></returns>
public int GetTingRoom(int tingid, int roomid = -1)
{
if (roomid >= 0)
return rooms[roomid].isExists(tingid) ? roomid : -1;
foreach (var rm in rooms)
{
if (rooms[rm.id].isExists(tingid))
return rm.id;
}
return -1;
}
/// <summary>
/// 处理消息数据
/// </summary>
/// <param name="head"></param>
/// <param name="jsondata"></param>
public virtual void DoMessageData(PackHead head, string jsondata)
{
MessageData msgdt = JsonPack.GetData<MessageData>(jsondata);
if (msgdt.msgStyle == 1)
{
//全游戏
//开一个协程去做
Debug.Error("未实现对全玩家发送消息");
//Coroutine.StartCoroutine(DoMessageData(msgdt));
}
else if (msgdt.msgStyle == 2)
{
//全桌
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(msgdt.receiveId);
if (pl == null) //玩家已经下线
return;
Desk desk = FindDesk(pl.tingid, pl.deskid);
if (desk != null)
desk.DoMessageData(msgdt);
}
else
{
Debug.Error("类型错误,该消息不是游戏服务器处理:{0}", msgdt.msgStyle);
}
}
#region IGameMessage
/// <summary>
/// 处理字游戏包
/// </summary>
public virtual void DoZyxPack(GamePack pack)
{
//没有厅 不在开战
if (!isExistsTing(pack.pl.tingid) || pack.pl.state != (int)PlayerState.War)
{
Debug.ImportantLog("子游戏收包ting:" + pack.pl.tingid + ",state:" + pack.pl.state + "," + pack.Head.userid +
" len:" + (pack.JsonData == null ? -1 : pack.JsonData.Length));
return;
}
if (config.GameMode == 1)
{
//百家乐包
if (pack.Head.otherInt != null && pack.Head.otherInt.Length > 0)
{
Debug.Log("牛牛包:" + pack.Head.otherInt[0]);
}
}
tings[pack.pl.tingid].DoZyxPack(pack);
}
/// <summary>
/// 处理聊天包
/// </summary>
/// <param name="pack"></param>
public virtual bool DoChatPack(GamePack pack)
{
if (!isExistsTing(pack.pl.tingid))
{
Debug.Warning("收到聊天包:" + pack.pl.tingid + ",state:" + pack.pl.state);
return false;
}
return tings[pack.pl.tingid].DoChatPack(pack);
}
/// <summary>
/// 处理道具包
/// </summary>
/// <param name="pack"></param>
/// <returns></returns>
public virtual bool DoProps(GamePack pack)
{
if (!isExistsTing(pack.pl.tingid))
{
Debug.Warning("收到道具包:" + pack.pl.tingid + ",state:" + pack.pl.state);
return false;
}
return tings[pack.pl.tingid].Drops(pack);
}
#endregion
/// <summary>
/// 强制结束
/// </summary>
/// <param name="userid">强制解散的玩家</param>
public void ForceOver(int userid)
{
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(userid);
if (pl == null)
{
Debug.Info("无此玩家:{0}", userid);
return;
}
var desk = FindDesk(pl.tingid, pl.deskid);
if (desk == null)
{
Debug.Error("强制结束时,未找到桌子数据:" + pl.ToString());
return;
}
desk.ForceWarOver();
}
#region IGameUtil
/// <summary>
/// id
/// </summary>
int IGameUtil.id
{
get { return 0; }
}
/// <summary>
/// 是否是朋友房的游戏
/// </summary>
public bool isFriend
{
get { return config.OpenFriend == 1; }
}
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
ServerInfoHelper.IsGameServer = true;
//开启朋友房,多创建一个厅
dllUtil.CreateTing(ServerConfigManager.Instance.Tings.Length, 6);
CreatTing();
CreateRoom();
shadowPool.Init();
//GetClubWarRecord();
if (isFriend)
FriendRoomManager.instance.Init(rooms[roomCnt - 1], tings[tingCnt - 1]);
void CreatTing()
{
int len = tingCnt;
for (int i = 0; i < len; i++)
{
tings[i] = factory.CreateTing(ServerConfigManager.Instance.Tings[i], isFriend && (i == len - 1)); //开启朋友房,最后一个给朋友房使用
tings[i].Init();
}
}
void CreateRoom()
{
int len = roomCnt;
for (int i = 0; i < len; i++)
{
try
{
CastlesConfig rmConfig = ServerConfigManager.Instance.Castles[i];
Debug.Log($" --- :{ServerConfigManager.Instance.Castles.Length} {rooms.Length} {rmConfig.Tings.Length}");
rooms[i] = factory.CreateRoom(i, rmConfig, isFriend && (i == len - 1)); //开启朋友房,最后一个给朋友房使用
int cnt = rmConfig.Tings.Length;
for (int j = 0; j < cnt; j++)
{
Debug.Log($"得到tingIDs:{rmConfig.Tings[j]} {tings.Length}");
rooms[i].AddTing(j, tings[rmConfig.Tings[j]]);
rooms[i].Init();
}
}
catch (Exception e)
{
Debug.Error($"创建房间报错:{e.Message} {i}");
throw e;
}
}
}
GameDispatcher.Instance.AddListener(GameMsgId.DisConnected, OnDisConnected);
}
/// <summary>
/// 获取整数的数据
/// </summary>
/// <param name="lx"></param>
/// <returns></returns>
public virtual int GetIntValue(string lx)
{
if (lx == null)
return 0;
string[] spt = lx.Split('|');
if (spt.Length <= 0)
return 0;
var gmconfig = GameManager.instance.config;
switch (spt[0])
{
case "0": //游戏规则 --游戏通用参数
int idx = int.Parse(spt[1]);
if (idx < 0 || idx > gmconfig.GameGz.Length)
return -1;
return gmconfig.GameGz[idx - 1] - 48;
case "1": //游戏通用设置 暂时废弃
break;
case "2": //是否发布版
return 1;
case "3": //在线玩家数量
return PlayerCollection.Instance.PlayerCnt;
case "4": //窗体是否可见 废弃
return 0;
case "5": //假房间总数 废弃
Debug.Error("已经没有假房间了!");
break;
case "6": //私房信息
Debug.Error("转到桌子信息!");
string lxstr = string.Empty;
switch (spt[1])
{
case "0":
Debug.Warning("房间号:" + spt[2] + ",桌号:" + spt[3] + ",获取的数据类型:" + spt[4]);
lxstr = spt[4];
break;
case "1":
Debug.Warning("根据时间" + spt[2] + ",房号:" + spt[3] + ",获取的数据类型:" + spt[4]);
lxstr = spt[4];
break;
case "2":
Debug.Warning("获取当前桌子的数据类型:" + spt[2]);
lxstr = spt[2];
break;
case "3":
Debug.Warning("根据指针获取数据类型:" + spt[3]);
lxstr = spt[3];
break;
}
switch (lxstr)
{
case "0":
Debug.Info("获取已完成局数!");
break;
case "1":
Debug.Info("获取当前正在进行的局数(-1)!");
break;
case "2":
Debug.Info("获取朋友房是否是VIP房间!");
break;
//case "3":
//break;
case "4":
Debug.Info("获取创建的id");
break;
case "5":
Debug.Info("获取总共打多少局!");
break;
case "6":
Debug.Info("获取朋友房是几人的房间!");
break;
case "7":
Debug.Error("获取朋友房的创建类型,这里要非常注意,数据已经改变 原来的定义(0玩家开 1是竞技比赛开 2是代开房间)");
break;
case "8":
Debug.Info(
"0默认 -1个人托管[man[x].tuoguan 个人按钮]开启 >0全房托管[配置]开启 tuoguan>0则自动准备其他子游戏控制");
break;
}
/*
* 0朋友房结束的局数
* 1当前是第几局
* 2是否是vip
* 4创建者id
* 5需要打的局数
* 6.房间信息
* case 2 of
* 0: 已完成局数
*
*
*
* 7.创建者类型
* 8.是否托管
*
* */
break;
case "7": //游戏版本
break;
case "8": //全服人数
break;
case "44": //服务器是否关闭中
break;
case "444": //服务器是否开启测试
break;
}
Debug.Error("游戏整数信息未解析,待解析!" + lx);
return 0;
}
/// <summary>
/// 获取字符串的类型数据
/// </summary>
/// <param name="lx"></param>
/// <returns></returns>
public virtual string GetStringValue(string lx)
{
if (lx == null)
return string.Empty;
string[] sqt = lx.Split('|');
if (sqt.Length <= 0)
{
return string.Empty;
}
switch (sqt[0])
{
case "0": //获取全游戏规则
//Debug.Warning("单个规则找厅, 每个厅都是单独分开的!");
string allgz = string.Empty;
int len = ServerConfigManager.Instance.TingCnt;
for (int i = 0; i < len; i++)
{
allgz += ServerConfigManager.Instance.Tings[i].TingGz;
}
//Debug.Log(" 读取到所有规则:" + allgz);
return allgz;
case "1": //获取朋友房规则 100个字符串
if (sqt.Length < 1)
{
Debug.Error("获取游戏字符串信息错误:" + lx);
break;
}
switch (sqt[1])
{
case "0":
//看桌子是否是朋友房,是直接拿朋友房规则返回,不是则拼接通用规则与厅规则合成100个字符串返回
Debug.Error("根据桌子房间号 与桌子 来包获取朋友房的一百个规则!!!!!", lx[2], lx[3]);
break;
case "1":
Debug.Error("根据房间号根据日期和时间 来包获取朋友房的一百个规则!!!!");
break;
case "2":
//现在没100个了-就只有50个
Debug.Error("获取当前桌子的100个规则");
break;
}
break;
}
Debug.Error("游戏字符串信息未解析:" + lx);
return string.Empty;
}
/// <summary>
/// 获取游戏数据
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public virtual object GetData(string tag)
{
return null;
}
/// <summary>
/// 关闭服务器执行的代码
/// </summary>
public virtual void Close()
{
GameDispatcher.Instance.RemoveListener(GameMsgId.DisConnected, OnDisConnected);
Debug.ImportantLog($"关闭服务器 GameManager!");
//保存战绩
_SavePlayerData();
//SaveClubWarRecord(); //保存俱乐部的战斗数据
if (rooms != null)
{
for (int i = 0; i < tings.Length; i++)
{
tings[i].Close();
}
}
}
/// <summary>
/// 保存玩家的战斗数据
/// </summary>
void _SavePlayerData()
{
var users = PlayerCollection.Instance.GetPlayerUserIds();
Parallel.ForEach(users, id =>
{
if (id <= 0) return;
var u = PlayerCollection.Instance.FindPlayerByUserId(id);
CloseServerSavePlayerData(u);
});
}
/// <summary>
/// 关闭服务器保存玩家数据
/// </summary>
/// <param name="u"></param>
public virtual void CloseServerSavePlayerData(PlayerDataAsyc u)
{
if (u == null || u.isRobot) return;
if (u.WarData != null)
{
UserWarDataDal.SaveUserWarData(u.WarData);
}
}
#endregion
public bool DeleFriendRoom(int roomid, out string msg)
{
msg = string.Empty;
string weiyima2 = string.Empty;
ServerNode node = new ServerNode();
if (!GameDAL.FriendRoom.Room.GetWeiyima(roomid, ref weiyima2, ref node))
{
msg = "解散失败,桌子不存在!";
return false;
}
if (ServerHeart.instanece.IsDie(node.id, node.nodeNum))
{
msg = "解散失败,游戏维护中!";
return false;
}
PackHead head = PackHead.Create();
head.packlx = node.id * Game.Data.GameData.PackCardInt +
GameSeverAgreement.ClubDisBankCmd;
head.otherString = new string[] { weiyima2 };
GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head), true);
head.Dispose();
return true;
}
protected virtual void OnDisConnected(object param)
{
int userid = (int)param;
//先看玩家是不是本模块的
PlayerDataAsyc pl = PlayerCollection.Instance.FindPlayerByUserId(userid);
if (pl == null)
{
//Debug.Error("玩家离线未获取到玩家:" + pk.head.userid);
return;
}
Debug.Info("玩家离线处理-------!" + userid + "," + (pl.socketUtil == null));
pl.outline = 1;
pl.OutLineTime = 0;
if (pl.roomid >= 0)
{
//没在房间,直接退出
RoomManager room = FindRoom(pl.roomid);
if (room == null)
{
Debug.Error("服务器错误-没有这个房间GameManager:" + pl.roomid);
return;
}
else
{
if (pl.friendRoomNum <= 0)
{
if (!room.Quit(pl))
{
//成功退出的房间
OutLine(pl); //没能退出房间,则掉线处理
return;
}
}
else
{
OutLine(pl); //没能退出房间,则掉线处理
return;
}
}
}
GameManager.instance.QuitGame(pl, "DisConnection", false);
}
/// <summary>
/// 刷新AI榜单
/// </summary>
public virtual void RefreshAiBangDan()
{
}
/// <summary>
/// 刷新比赛机器人
/// </summary>
public virtual void RefreshAiRobot()
{
}
}
}