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
2008 lines
67 KiB
C#
2008 lines
67 KiB
C#
/*
|
||
* 由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()
|
||
{
|
||
|
||
}
|
||
|
||
|
||
}
|
||
} |