using System;
using GameDAL.FriendRoom;
using Server.Data.Module;
using Server.Data;
using GameData;
using Server.Pack;
using MrWu.Debug;
using Server.MQ;
using Game.Player;
using MrWu.Basic;
using System.Collections;
using System.Threading.Tasks;
using System.Collections.Generic;
using StackExchange.Redis;
using System.Linq;
using GameDAL;
using GameMessage;
using Server.AliyunSDK.SLSLog;
using Server.Config;
namespace Server
{
///
/// 朋友房管理
///
public partial class FriendRoomManager
{
///
/// 实例
///
public static FriendRoomManager instance { get; private set; }
private FriendRoomManager()
{
int len = allDesks.Length;
for (int i = 0; i < len; i++)
{
allDesks[i] = new Dictionary();
}
}
static FriendRoomManager()
{
instance = new FriendRoomManager();
}
///
/// 朋友房所在的厅
///
private TingManager_Friend ting;
///
/// 朋友房所在的城堡
///
private RoomManager_Friend room;
///
/// 朋友房的桌子
///
public readonly Dictionary[] allDesks = new Dictionary[10];
///
/// 初始化
///
///
///
public void Init(RoomManager room, TingManager ting)
{
this.room = room as RoomManager_Friend;
this.ting = ting as TingManager_Friend;
}
///
/// 得到一个新的房间号
///
///
private int GetNewRoomNum()
{
int roomnum = Room.GetRoomNum();
return CheckRoom(roomnum, 0);
}
///
/// 检查房间号是否可用 循环检查连续100个房间,检查到可用即返回
///
/// 房间号
/// 检查次数
/// 小于0表示未查到可用房间(这时候应该把修改上次检查房间的值,以便下次检查) 大于表示查到某房间可用
private int CheckRoom(int roomNum, int checkCount)
{
if (checkCount >= 100) //没有查询到
return -1;
checkCount++;
string weiyima = null;
ServerNode node = null;
if (!Room.GetWeiyima(roomNum, ref weiyima, ref node))
{
//房间号可用
return roomNum;
}
else
{
DeskInfo dt = null;
if (Room.LoadRoom(weiyima, out dt))
{
int isSendDis = dt.CheckDisBank();
if (isSendDis > 0)
{
//发送解散命令
PackHead head = PackHead.Create(ServerPackAgreement.disbank);
if (ServerHeart.instanece.IsDie(node.id, node.nodeNum))
{
Debug.Error("管理该房间的模块不在线!");
}
else
{
GlobalMQ.instance.DeliveryOne(node,
GlobalMQ.CreateMessage(head,
JsonPack.GetJson(new KeyValuePair(roomNum, 2 + isSendDis))), true);
Debug.Warning("发送解散命令!" + roomNum);
}
head.Dispose();
head = null;
}
}
else
{
Debug.Warning("房间数据未加载成功!" + weiyima);
}
do
{
roomNum++;
roomNum = roomNum % Room.MaxCnt;
} while (roomNum == 0); //房间号从1开始
return CheckRoom(roomNum, checkCount); // 继续找
}
}
///
/// 玩家退出
///
///
private bool QuitGame(int userid)
{
var tmp = PlayerCollection.Instance.FindPlayerByUserId(userid);
if (tmp == null)
{
Debug.Error("玩家退出未找到玩家:" + userid);
return false;
}
else
GameManager.instance.QuitGame(tmp, "QuitGame");
return true;
}
///
/// 获取朋友房房间号
///
///
///
/// true 表示可以创建
private bool GetFriendRoomNum(PackHead head, CreateRoomPack rmdata)
{
//判断是否被锁,被锁,提示玩家被锁,并提示玩家去被锁的游戏
try
{
int roomnum = GetNewRoomNum(); //房间号
if (roomnum < 0)
{
//服务器爆满,创建失败,回包给玩家 提示玩家
GeneralSendPack.SendErrorInfo_Socket(head.userid, 0, 3, head.GetUtil());
if (rmdata.isAuto == 1)
{
QuitGame(head.userid);
}
return false;
}
else
{
Debug.Info("创建的房间号:" + roomnum + "," + rmdata.deskinfo.weiyima);
//按照房间号分发给模块处理,如果是本模块的直接处理
rmdata.deskinfo.roomNum = roomnum.ToString();
return true;
}
}
catch (Exception e)
{
Debug.Error("C480D7D2-B680-4321-924F-5C8AF7DAA2B6:" + e.ToString());
GeneralSendPack.SendErrorInfo_Socket(head.userid, 1, 37, head.GetUtil());
return false;
}
}
///
/// 处理创建朋友房的包
///
/// 包裹
public void CreatFriendRoom(GamePack pack)
{
if (ting == null)
{
Debug.Error("游戏未开启朋友房功能!");
return;
}
PackHead head = pack.Head;
CreateRoomPack rmdata = JsonPack.GetData(pack.JsonData);
if (head == null || rmdata == null)
{
Debug.Error("客户端发送的数据有问题!创建失败!");
return;
}
//判断是否被锁,被锁,提示玩家被锁,并提示玩家去被锁的游戏
if (GetFriendRoomNum(head, rmdata))
CreatRoomLogin(head, rmdata, false, true);
}
///
/// 俱乐部踢出玩家
///
/// 状态码
public int DoClubOutPlayer(string weiyima, int userId)
{
string roomnumStr = Room.GetRoomNum(weiyima);
int roomnum = 0;
if (!int.TryParse(roomnumStr, out roomnum))
{
return MessageErrCode.KickOutPlayerOfDesk_NoDesk;
}
Desk desk = FindDesk(roomnum);
if (desk == null || desk.deskinfo.weiyima != weiyima)
{
return MessageErrCode.KickOutPlayerOfDesk_NoDesk;
}
if (!desk.deskinfo.noWar)
{
return MessageErrCode.KickOutPlayerOfDesk_GameInWar;
}
for (int i = 0; i < desk.Count; i++)
{
if (desk[i] == null) continue;
if (desk[i].userid == userId)
{
PackHead headp = PackHead.Create();
headp.userid = userId;
headp.packlx = GamePackAgreement.autoTipInfo;
headp.otherString = new string[] { "您被管理员踢出房间!" };
GeneralSendPack.SendPackToPlayer(headp, desk[i], null);
GameManager.instance.DoComBack(desk[i]);
headp.Dispose();
break;
}
}
return MessageErrCode.Success;
}
///
/// 竞技比赛踢出玩家
///
///
public void DoClubOutPlayer(GamePack pack)
{
var head = pack.Head;
string weiyima = head.otherString[0];
int userid = head.otherInt[0];
string roomnumStr = Room.GetRoomNum(weiyima);
int roomnum = 0;
if (!int.TryParse(roomnumStr, out roomnum))
{
head.transfer = ServerPackAgreement.OutPlayer;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherString = new string[] { "房间不存在!"};
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null), true);
return;
}
Desk desk = FindDesk(roomnum);
if (desk == null || desk.deskinfo.weiyima != weiyima)
{
head.transfer = ServerPackAgreement.OutPlayer;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherString = new string[] { "房间不存在!"};
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null), true);
return;
}
if (!desk.deskinfo.noWar)
{
head.transfer = ServerPackAgreement.OutPlayer;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherString = new string[] { "桌子已开战,踢出失败!"};
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null), true);
return;
}
for (int i = 0; i < desk.Count; i++)
{
if (desk[i] == null) continue;
if (desk[i].userid == userid)
{
PackHead headp = PackHead.Create();
headp.userid = userid;
headp.packlx = GamePackAgreement.autoTipInfo;
headp.otherString = new string[] { "您被管理员踢出房间!" };
GeneralSendPack.SendPackToPlayer(headp, desk[i], null);
GameManager.instance.DoComBack(desk[i]);
head.Dispose();
break;
}
}
head.transfer = ServerPackAgreement.OutPlayer;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherString = new string[] { "踢出成功!"};
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null), true);
}
public void QuitGameJoinOther(GamePack pack)
{
var head = pack.Head;
if (head.otherInt == null || head.otherInt.Length <= 0)
{
SendManager.SendErrotInfo_Http(head, 0, "数据错误!");
return;
}
var player = PlayerCollection.Instance.FindPlayerByUserId(head.userid);
if (player == null)
{
Debug.Error("未找到玩家!" + head.userid);
SendManager.SendErrotInfo_Http(head, 0, "未找到玩家!");
return;
}
JoinFriendRoom jfr = JsonPack.GetData(pack.JsonData);
if (head == null || jfr == null)
{
Debug.Error("客户端发来的数据有问题,加入玩法失败!");
return;
}
PlayerState playerState = (PlayerState)player.state;
if (playerState == PlayerState.Desk || playerState == PlayerState.Ready)
{
if (string.IsNullOrEmpty(player.friendWeiYiMa) || player.friendRoomNum == 0)
{
SendManager.SendErrotInfo_Http(head, 0, $"你不在朋友房,不能切换房间!");
}
else
{
//玩家退出当前游戏
GameManager.instance.DoComBack(player);
//去处理进入房间
head.packlx = head.otherInt[0];
int dealModuleId = head.packlx / Game.Data.GameData.PackCardInt;
Debug.Log("转发给游戏服务器:" + head.packlx);
GlobalMQ.instance.DeliveryEveryOne(dealModuleId, GlobalMQ.CreateMessage(head, jfr), true);
}
}
else
{
SendManager.SendErrotInfo_Http(head, 0, $"当前状态{playerState}不能切换玩法!");
}
}
///
/// 竞技比赛会长解散房间
///
public int ClubDisBankCmd(string weiyima)
{
string roomnumStr = Room.GetRoomNum(weiyima);
int roomnum = 0;
if (!int.TryParse(roomnumStr, out roomnum))
{
return MessageErrCode.ClubDisbandNotFindDesk;
}
Desk desk = FindDesk(roomnum);
if (desk == null || desk.deskinfo.weiyima != weiyima)
{
return MessageErrCode.ClubDisbandNotFindDesk;
}
DisBank(desk, 7);
return MessageErrCode.Success;
}
///
/// 竞技比赛会长解散房间
///
///
public void ClubDisBankCmd(GamePack pack)
{
var head = pack.Head;
string weiyima = head.otherString[0];
string roomnumStr = Room.GetRoomNum(weiyima);
int roomnum = 0;
if (!int.TryParse(roomnumStr, out roomnum))
{
SendManager.SendErrotInfo_Http(head, 2, 74);
return;
}
Desk desk = FindDesk(roomnum);
if (desk == null || desk.deskinfo.weiyima != weiyima)
{
SendManager.SendErrotInfo_Http(head, 2, 74);
return;
}
DisBank(desk, 7);
SendManager.SendErrotInfo_Http(head, 2, 75);
}
///
/// 竞技比赛因玩家比赛积分不够解散桌子
///
///
public void ClubMatchDisBankByBurs(GamePack pack)
{
var head = pack.Head;
string weiyima = head.otherString[0];
string roomnumStr = Room.GetRoomNum(weiyima);
int roomnum = 0;
if (!int.TryParse(roomnumStr, out roomnum))
{
return;
}
Desk desk = FindDesk(roomnum);
if (desk == null || desk.deskinfo.weiyima != weiyima)
{
return;
}
DisBank(desk, 8);
}
///
/// 竞技比赛创建桌子
///
///
public void DoClubCreateDesk(GamePack pack)
{
if (ting == null)
{
Debug.Error("游戏未开启朋友房功能!");
return;
}
PackHead head = pack.Head;
JoinFriendRoom jfr = JsonPack.GetData(pack.JsonData);
if (head == null || jfr == null)
{
Debug.Error("客户端发来的数据有问题,加入玩法失败!");
return;
}
DeskInfo dskinfo = new DeskInfo();
dskinfo.wayid = jfr.way.weiyima;
dskinfo.creatStyle = 5;
dskinfo.creatUserid = jfr.way.Clubid;
dskinfo.rule = jfr.way.dskrule;
if (dskinfo.rule.RuleEx == null)
dskinfo.rule.RuleEx = new DeskRuleEx();
dskinfo.rule.RuleEx.ReadyTimeout = jfr.ReadyTimeOut;
CreateRoomPack crp = new CreateRoomPack();
crp.deskinfo = dskinfo;
crp.deviceInfo = jfr.deviceInfo;
crp.isAuto = jfr.isAuto;
crp.ClubId = jfr.ClubId;
crp.TaskId = jfr.TaskId;
//获取到房间号,去创建房间
if (instance.GetFriendRoomNum(head, crp))
{
instance.CreatRoomLogin(head, crp, true, true);
}
}
public async Task JoinClubDesk(GamePack pack)
{
PackHead head = pack.Head;
JoinFriendRoom jfr = JsonPack.GetData(pack.JsonData);
if (head == null || jfr == null)
{
Debug.Error("客户端发来的数据有问题,加入玩法失败!");
return;
}
if (DoingUserIds.Contains(head.userid))
{
Debug.Error($"正在处理别的事务:{head.userid}");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskDoing);
return;
}
if (ting == null)
{
Debug.Error("游戏未开启朋友房功能!");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotOpenFriend);
return;
}
int userid = head.userid;
try
{
DoingUserIds.Add(userid);
//有则尝试加入房间!
//先把房间找到->
string strRoomNum = Room.GetRoomNum(jfr.joinweiyima);
Debug.Info("找到房间:" + strRoomNum + "," + jfr.joinweiyima);
//管理该房间的节点
ServerNode node = null;
string weiyima = null;
//拿到房间号,先看本地有没有,没有的话则加载起来
int roomnum = 0;
if (int.TryParse(strRoomNum, out roomnum))
{
//有房间号
if (Room.GetWeiyima(roomnum, ref weiyima, ref node))
{
//拿到唯一码
if (weiyima == jfr.joinweiyima)
{
//唯一码一致
if (!GameBase.instance.myUtil.Equals(node))
{
//交给管理模块处理
GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
}
else
{
//本模块处理
//没在本地加载到本地
Debug.Info("本地处理");
DoJoinFriendRoom djfr = new DoJoinFriendRoom(head,
new JoinRoom(roomnum.ToString(), weiyima) { deviceinfo = jfr.deviceInfo }, jfr,
false, true);
await djfr.Start();
if (!djfr.result)
{
//进入失败 再来一次
/*
jfr.lastjoinweiyima = weiyima;
jfr.joinweiyima = null;
*/
Debug.Log("加入失败的提示:" + djfr.errinfo);
if (jfr.TaskId <= 0)
{
if (string.IsNullOrEmpty(djfr.errinfo))
{
SendManager.SendErrotInfo_Http(head, 1, 73);
}
else
{
SendManager.SendErrotInfo_Http(head, 0, djfr.errinfo);
}
}
else
{
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, djfr.errorCode);
}
/*
head.packlx = GlobalManager.instance.myUtil.id * 10000 + head.packlx;
GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
*/
Debug.Warning("进入失败,发包再试!" + head.ip);
}
else
{
if (jfr.TaskId <= 0)
{
//把玩家拉入桌子
head.transfer = ServerPackAgreement.ReConnection;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherInt = new int[] { ServerConfigManager.Instance.ClientId };
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null),
true);
}
else
{
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.Success);
}
}
}
return;
}
}
}
}
finally
{
DoingUserIds.Remove(userid);
}
}
///
/// 处理加入玩法包
///
///
public void DoWanFa(GamePack pack)
{
PackHead head = pack.Head;
JoinFriendRoom jfr = JsonPack.GetData(pack.JsonData);
if (head == null || jfr == null)
{
Debug.Error("客户端发来的数据有问题,加入玩法失败!");
return;
}
if (ting == null)
{
Debug.Error("加入玩法失败,游戏未开启朋友房功能!");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotOpenFriend);
return;
}
JoinWanFa djfr = new JoinWanFa(head, jfr);
djfr.Start(head);
}
///
/// 处理加入房间包
///
///
public async Task DoJoinRoom(GamePack pack)
{
if (ting == null)
{
Debug.Error("加入房间失败,游戏未开启朋友房功能!");
return;
}
PackHead head = pack.Head;
JoinRoom jr = JsonPack.GetData(pack.JsonData);
if (head == null || jr == null)
{
Debug.Error("客户端发来的数据有问题,加入房间失败!");
return;
}
DoJoinFriendRoom djfr = new DoJoinFriendRoom(head, jr, null, true, false);
await djfr.Start();
if (!djfr.result)
{
head.otherString = new string[] { djfr.errinfo };
head.packlx = GamePackAgreement.TransFerPack;
head.transfer = GameSeverAgreement.notJoinFriendRoom;
GlobalMQ.instance.DeliveryOne(head.GetUtil(), GlobalMQ.CreateMessage(head), true);
}
/*
* TTTT补: 加入房间房间的处理修改,需要外部发包通知
*
*
* */
}
///
/// 处理回放
///
///
[Obsolete("过时,不使用")]
public void DoHuiFang(GamePack pack)
{
//过时,不使用
//Task task = Task.Factory.StartNew(
// () =>
// {
// FightRecordData frd = JsonPack.GetData(pack.jsondata);
// frd.data = Room.LoadFightRecord(frd.weiyima, frd.index);
// pack.head.packlx = GameSeverAgreement.friendfightdata;
// //回放数据可能是空!
// GameNet.SendPack_Userid(pack.head.GetModuleUtil(), pack.head, frd);
// }
//);
}
///
/// 创建房间并登陆
///
///
///
protected async Task CreatRoomLogin(PackHead head, CreateRoomPack data, bool isClub, bool isCheckDoing)
{
Debug.Info("创建房间 赔率:" + data.deskinfo.rule.peilv);
await new FriendRoomManager.CreateRoom(head, head.userid, data, isClub, isCheckDoing).Start();
}
///
/// 解散房间包
///
///
public void DisBankDesk(GamePack pk)
{
if (ting == null)
{
Debug.Error("朋友房未开启!");
return;
}
if (pk.pl.tingid != ting.id)
{
Debug.Error("解散房间失败,没有这个房间!" + ting.id);
return;
}
DisBank(pk.pl);
}
///
/// 请求解散包
///
public void placeDisBank(GamePack pk)
{
placeDisBank(pk.pl);
}
///
/// 请求解散回复包
///
///
public void DisReponse(GamePack pk)
{
bool dis = JsonPack.GetData(pk.JsonData);
DisReponse(pk.pl, dis, false);
}
///
/// 解散房间命令
///
public void DisBankCmd(int roomnum, int style)
{
//先判断房间存在不存在,再判断是否是过期房间
//满足条件,解散房间
if (ting != null)
{
Desk desk = FindDesk(roomnum);
if (desk == null)
{
Debug.Warning("无此房间,可能已经被解散了!");
}
else
{
//判断房间是否过期解散
if (desk.deskinfo == null)
{
Debug.Error("大错误,桌子数据为空!");
return;
}
if (style == 7)
{
Debug.Info("收到强制解散房间命令!");
DisBank(desk, style);
}
else
{
int isDisBank = desk.deskinfo.CheckDisBank();
if (isDisBank > 0)
{
Debug.Info("检查解散房间!");
//解散
DisBank(desk, 2 + isDisBank);
}
else
{
Debug.Warning("收到假的解散指令!");
}
}
}
}
else
{
Debug.Error("未开启朋友房,收到解散指令!");
}
}
///
/// 获取玩家的桌子
///
///
///
public Desk GetPlayerDesk(PlayerDataAsyc pl)
{
//内存中如果没有桌子
Desk desk = FindDesk(pl.friendRoomNum);
if (desk != null)
return desk;
//去数据库中加载桌子
if (LoadFriendRoom(pl.friendRoomNum, pl.friendWeiYiMa))
{
desk = FindDesk(pl.friendRoomNum); //再从内存中加载起来
}
return desk;
}
///
/// 加载房间
///
///
protected bool LoadFriendRoom(int roomnum, string weiyima)
{
DeskInfo dskInfo = null;
//释放房间
void FreeRoom()
{
//没开启朋友房
Debug.Info("没开启朋友房!");
string _weiyima = null;
ServerNode node = null;
if (Room.GetWeiyima(roomnum, ref _weiyima, ref node)
&& weiyima == _weiyima)
{
if (Room.LoadRoom(_weiyima, out dskInfo))
{
//把数据从硬盘上加载起来
Debug.Info("加载朋友房数据:删除他!");
Desk.DisBank(dskInfo);
}
}
}
if (ting == null)
{
Debug.Error("未开启朋友房!");
FreeRoom(); //朋友房未开启,释放房间
return false;
}
//加载朋友房到内存
Desk dsk = FindDesk(roomnum);
if (dsk == null)
{
//内存中没有--去加载朋友房
Debug.Log("没找到这个朋友房:" + roomnum);
//去数据库中拿
DeskInfo dskinfo;
if (Room.LoadRoom(weiyima, out dskinfo))
{
//桌子数据处理完成!
Debug.Info($"加载朋友房数据! {dskinfo.weiyima}");
LoadDesk(dskinfo);
}
else
{
//数据库中也没有
return false;
}
}
return true;
}
private void SetPlayerScoreRecord(DeskInfo deskInfo)
{
try
{
if (!deskInfo.isAllOver || deskInfo.creatStyle != 5 || string.IsNullOrEmpty(deskInfo.wayid))
{
return;
}
LuckPlayerManager.FightScore[] fightScore = new LuckPlayerManager.FightScore[deskInfo.seat.Length];
for (int i = 0; i < deskInfo.seat.Length; i++)
{
fightScore[i] = new LuckPlayerManager.FightScore()
{
UserId = deskInfo.pls[i].userid,
Value = (int)deskInfo.SumBurs[i].Score
};
FriendRoomStatistics.Instance.AddSessionFight(deskInfo.wayid, deskInfo.rule.peilv,
deskInfo.pls[i].userid, (int)deskInfo.SumBurs[i].Score);
}
LuckPlayerManager.Instance.AddScoreRecord(deskInfo.wayid, deskInfo.rule.peilv, deskInfo.overCnt,
fightScore);
}
catch (Exception e)
{
Debug.Error($"SetPlayerScoreRecord:{e.Message}");
}
}
///
/// 解散桌子逻辑
///
/// 要解散的桌子
/// 1局数打完解散 2开战过-玩家申请解散 3超时解散(24小时未打完) 4超时解散(1小时内还没满员) 5房主解散 6玩法被删除 7竞技比赛管理解散房间 8因小局分不够解散 9托管自动解散
public void DisBank(Desk desk, int style)
{
// 上报
if (desk.deskinfo != null && !desk.deskinfo.noWar)
{
desk.AddWarTime(); // 重新计算一下战局时长,防止漏计算
List eLogs = new List();
for (int i = 0; i < desk.PlayerCnt; i++)
{
if (desk[i] != null)
{
// 用户游玩时长
eLogs.Add(StatisticsTrackingLogData.Create(
desk[i].userid.ToString(),
EventTrackConst.GameFriendPlayTime,
desk.totalWarTime,
ServerConfigManager.Instance.GameId.ToString()
));
}
}
if (desk.deskinfo.creatStyle == 5)
{
// 公会游玩局数
var clubIds = desk.Select(x => x.ClubId).Distinct();
foreach (var clubId in clubIds)
{
eLogs.Add(StatisticsTrackingLogData.Create(
clubId.ToString(),
EventTrackConst.GameClubPlayCount,
1,
ServerConfigManager.Instance.GameId.ToString()
));
}
}
// 解散原因
eLogs.Add(StatisticsTrackingLogData.Create(
ServerConfigManager.Instance.GameId.ToString(),
EventTrackConst.GameDisCount,
1,
style.ToString()
));
EventTrackingUtil.OnEvent(eLogs);
}
desk.DisBank(style);
DeskInfo deskinfo = desk.deskinfo;
//只要是解散,都应该要算输赢分
Room.SetSumBurs(deskinfo);
SetPlayerScoreRecord(deskinfo);
deskinfo.isClose = 1;
//先发包
desk.SendFriendRoomOver(style);
//Debug.Info($"解散原因:{deskinfo.GetDisBankMemo(style)}");
//修改玩家数据,修改桌子数据 --执行完玩家就离线了!
desk.DisBankAfter(style);
//修改链表数据
//添加到闲置的桌子!
ting.AddIdleing(desk);
if (deskinfo.creatStyle == 5)
{
WayManager.instance.WayDeskChangeSend(deskinfo.creatUserid, deskinfo.wayid, deskinfo.weiyima, 1);
}
int rm = 0;
if (!int.TryParse(desk.deskinfo.roomNum, out rm))
{
Debug.Error("房间号竟然不是数字!");
return;
}
Debug.Info("获取到房间号:" + rm);
int idx = rm % 10;
if (!allDesks[idx].Remove(rm))
{
Debug.Error("alldesk中竟然没有此房间!");
return;
}
}
///
/// 根据房间号查找桌子
///
///
public Desk FindDesk(int deskNum)
{
if (ting == null)
return null;
if (deskNum < 0)
return null;
int idx = deskNum % 10;
Desk desk = null;
if (allDesks[idx].TryGetValue(deskNum, out desk))
return desk;
return null;
}
///
/// 请求解散房间包
///
///
private void placeDisBank(PlayerDataAsyc pl)
{
if (pl.friendRoomNum <= 0)
{
Debug.Error("此玩家没有朋友房!");
return;
}
Desk dsk = FindDesk(pl.friendRoomNum);
if (dsk == null)
{
Debug.Error("逻辑错误,没找到这个桌子" + pl.friendRoomNum);
return;
}
if (dsk.deskinfo.noWar)
{
Debug.Error("未开战不处理!");
return;
}
if (dsk.deskinfo.isDising)
{
Debug.Warning("正在处理解散房间!");
return;
}
if (dsk.deskinfo.rule.RuleEx != null && dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt < 0)
{
Debug.Log("不支持解散!");
return;
}
if (dsk.deskinfo.rule.RuleEx != null && dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt > 0 &&
dsk.deskinfo.RequestDissolveCnt >= dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt)
{
Debug.Log("请求解散的次数达到上限!");
return;
}
dsk.deskinfo.isDising = true;
dsk.deskinfo.DisCount = DeskInfo.DisTimeOut;
dsk.deskinfo.RequestDissolveCnt++;
int len = dsk.deskinfo.plsDis.Length;
DisReponse(pl, true, true);
}
///
/// 请求立即开战
///
///
public void placeOnceFight(GamePack pack)
{
Debug.Info("得到立即开战包:");
placeOnceFight(pack.pl, pack.Head);
}
///
/// 请求开战
///
/// 玩家数据
/// 包头
private void placeOnceFight(PlayerDataAsyc pl, PackHead head)
{
if (ting == null)
return;
if (pl.friendRoomNum <= 0)
{
Debug.Error("玩家没有朋友房!");
return;
}
Desk dsk = FindDesk(pl.friendRoomNum);
if (dsk == null)
{
Debug.Error("逻辑错误,没找到这个桌子" + pl.friendRoomNum);
return;
}
if (dsk.deskinfo.rule.minCnt >= dsk.deskinfo.rule.maxCnt)
{
Debug.Error("没有设置立即开战!");
return;
}
if (!dsk.deskinfo.noWar)
{
Debug.Error("开战了不处理!");
return;
}
if (head.otherInt == null || head.otherInt.Length < 1)
return;
dsk.deskinfo.OnceFight[dsk.deskinfo.seat[pl.seat]] = head.otherInt[0];
dsk.SendOnceFight();
}
///
/// 解散回复包
///
/// 回复的玩家
/// 是否同意解散
/// 是否是发起者
public void DisReponse(PlayerDataAsyc pl, bool Dis, bool source)
{
if (pl.friendRoomNum <= 0)
return;
Desk dsk = FindDesk(pl.friendRoomNum);
if (!dsk.deskinfo.isDising)
return;
int len = dsk.deskinfo.plsDis.Length;
for (int i = 0; i < len; i++)
{
//这个位置有人 没投票过 是这个玩家
if (dsk.deskinfo.pls[i] != null && dsk.deskinfo.plsDis[i] == 0 &&
dsk.deskinfo.pls[i].userid == pl.userid)
{
if (Dis)
{
if (source)
{
dsk.deskinfo.DisUserId = pl.userid;
}
dsk.deskinfo.plsDis[i] = 1;
dsk.SendDisInfo(source ? 1 : 2, pl.userid, pl.nickname);
}
else
{
dsk.deskinfo.DisUserId = 0;
//拒绝解散
//dsk.deskinfo.plsDis[i] = -1;
dsk.deskinfo.isDising = false;
dsk.SendDisInfo(3, pl.userid, pl.nickname);
for (int j = 0; j < len; j++)
{
dsk.deskinfo.plsDis[j] = 0;
}
Debug.Log("告诉玩家,谁谁谁拒绝解散!");
return;
}
break;
}
}
//检查是否全部人都同意解散
bool isDis = true;
for (int i = 0; i < len; i++)
{
if (dsk.deskinfo.pls[i] != null)
{
//这个位置有人且不是同意
if (dsk.deskinfo.plsDis[i] != 1)
{
isDis = false;
break;
}
}
}
if (isDis)
{
//解散房间
Debug.Info("所有人同意解散!");
DisBank(dsk,2);
}
}
public void DeductCard(PlayerDataAsyc pl, DeskInfo info)
{
if (info.fangka == 0)
{
return;
}
if (info.creatStyle == 5)
{
//通知竞技比赛扣除竞技比赛房卡
ClubDataChange cdc = new ClubDataChange()
{
style = 1,
clubid = info.creatUserid,
value = -info.fangka
};
// PackHead head = PackHead.Create(ServerPackAgreement.ClubDataChange);
// ClubDataManager.AddClubCardAsyn(info.creatUserid, -info.fangka);
// GlobalMQ.instance.DeliveryEveryOne((int)ModuleType.ClubModule, GlobalMQ.CreateMessage(head, cdc), true,
// true);
// head.Dispose();
// 埋点
EventTrackingUtil.OnEvent(StatisticsTrackingLogData.Create(
info.creatUserid.ToString(),
EventTrackConst.GamePlayCardCount,
info.fangka,
ServerConfigManager.Instance.GameId.ToString()
));
}
else
{
if (pl == null)
{
return;
}
//通知数据中心,扣除玩家的房卡
if (info.fangka != 0)
{
PlayerDataChange pdc = PlayerDataChange.Create(info.creatUserid);
pdc.fangkaChange = -info.fangka;
PlayerFun.WritePlayerDataAsync(pdc);
pl.fangka -= info.fangka;
}
}
GameManager.instance.DelFangKa += info.fangka;
}
///
/// 创建桌子--这种是新创建的
///
/// 创建者
/// 桌子信息
///
public int CreateDesk(PlayerDataAsyc pl, DeskInfo info, ref string errinfo, ref int errcode)
{
//DeductCard(pl, info);
Debug.Info("创建所需的房卡数值:" + info.fangka);
Desk desk = ting.GetDesk(DeskState.Idle, info);
desk.Init();
Debug.Info("创建桌子实例!" + info.creatStyle + "," + info.creatUserid + "," + desk.id);
int deskNum = int.Parse(info.roomNum);
AddDesk(deskNum, desk);
Debug.Info("获取到房间号:" + deskNum);
ting.RemoveIdle(desk);
ting.AddQueueing(desk);
if (EnterDesk(deskNum, pl, info.rule.pwd, info.creatStyle == 5, ref errinfo, ref errcode) == 1)
{
Debug.Info("玩家进入房间成功! cccdd:" + pl.ClubId);
}
else
{
Debug.Error("自己创建的房间怎么还有进不去的情况?????" + info.roomNum + "," + errinfo);
return 0;
}
//Debug.Log("创建成功!");
Debug.Log(info.ToString());
return 1;
}
///
/// 添加desk
///
///
///
protected void AddDesk(int deskNum, Desk desk)
{
if (ting == null)
{
Debug.Error("非朋友房不得使用!");
return;
}
int idx = deskNum % 10;
Debug.Info("添加房间...." + deskNum);
allDesks[idx].Add(deskNum, desk);
}
///
/// 处理玩家解散房间包
///
///
public void DisBank(PlayerDataAsyc pl)
{
//先判断
if (pl.outline == 1)
{
Debug.Error("玩家离线哪里来的包!");
return;
}
if (pl.friendRoomNum <= 0)
{
Debug.Error("玩家没有房间号!");
return;
}
if (pl.state == (int)PlayerState.Desk || pl.state == (int)PlayerState.Ready)
{
if (!ting.isExists(pl.deskid))
{
Debug.Error("解散桌子错误!没有这个桌子!");
return;
}
var desk = ting[pl.deskid];
if (desk.CheckDisbank(pl))
{
Debug.Info("解散房间的收包!");
DisBank(desk, 5);
}
else
{
Debug.Warning("解散失败!");
}
}
else
{
Debug.Warning("玩家状态不符合解散桌子!");
return;
}
}
///
/// 本来就有的桌子
///
///
///
public void LoadDesk(DeskInfo info)
{
Desk desk = ting.GetDesk(DeskState.Idle, info);
desk.Init();
desk.LoadDesk();
AddDesk(int.Parse(info.roomNum), desk);
ting.RemoveIdle(desk);
if (desk.deskinfo.nowCnt == 0)
{
//0表示未开战 不等于0表示开战
ting.AddQueueing(desk);
}
else
{
desk.waitRecover = true;
ting.AddWaring(desk);
}
}
///
/// 删除玩法
///
public void DelWay(int clubid, string wayid)
{
//思路 把这个玩法的所有桌子的唯一码拿到手。
//获取到桌子信息, 判断桌子是否已经开战,如果没有开战则解散桌子
var weiyimaArray = WayManager.instance.GetDesksWeiYiMa(clubid, wayid).Select(p => (string)p.Name)
.ToArray(); //用这个得到唯一码
foreach (var weiyima in weiyimaArray)
{
if (!string.IsNullOrEmpty(weiyima))
{
var roomNum = Room.GetRoomNum(weiyima); //Room.GetRoomNum 传递唯一码获取房间号
if (int.TryParse(roomNum, out var roomnum))
{
var weiyimaOrig = string.Empty;
ServerNode node = null; //再根据房间号获取到唯一码 与 node. 返回值表示是否有这个房间。如果没这个房间输出错误信息。
if (Room.GetWeiyima(roomnum, ref weiyimaOrig, ref node))
{
//这个唯一码要与 刚才得到的唯一码进行对比,验证是否是同一个桌子 。 房间号是可以重复的, 桌子的唯一码却不会重复。
if (weiyima.Equals(weiyimaOrig))
{
//验证成功的话,FindDesk 查找到桌子
var desk = FindDesk(roomnum);
//桌子是空输出错误信息
if (desk == null)
{
Debug.Error(
$"DelWay desk is null! clubid: {clubid}, wayid: {wayid}, weiyima: {weiyima}, roomNum: {roomNum}.");
}
else if (!desk.isWar)
{
//再判断桌子是否已经开战 isWar 属性。
DisBank(desk, 6); //已经开战不处理,未开战调用 DisBank() 调用解散桌子
}
}
}
}
}
}
}
/*
* redis中的数据解构
*
* friendroom.lastRoomNum hash类型 lastDateTime 上次创建的时间 lastDateRoomNum 上次创建房间的房间号
* friendroom.room.num string类型 房间号表 -> 存储唯一吗值
* friendroom.唯一码 -> 房间数据
* friendroom.唯一码_playerdata_idx -> 存储房间的玩家数据
* friendroom.唯一码_score_idx -> 存储房间分数
*
* */
/*
*
* 朋友房唯一码 = 日期+时间+毫秒+房间号
*
{创建房间的算法}
{
1.房间号的算法{ --混淆游戏的火爆程度
变量 房间增量 当前检测房间号
1.房间增量 = 上次创建房间与当前时间的时间差 / 10 % 1000
2.当前检测的房间号 = (上次创建房间的房间号+房间增量) % 1000000
3.对比是否与上次创建的房间号一样,房间号+1
}
2.检测房间可用 传入检查的房间号 检查次数{
拿到房间号->去检查
检查次数+1;
如果检查房间号发现已经检查 100 次 返回未检查到可用房间->发包玩家重试
第一种情况2.1 房间号表有值
{
根据房间的唯一码去获取朋友房数据
{
1.房间已经超时 应该解散(未开战,过了半个小时->执行解散(发送解散命令) 开战了->过了24小时未战斗完(解散))
去执行解散房间
检查的房间号+1 -> 继续调用检测房间方法
2.房间正常
检查的房间号+1 -> 继续调用检测房间方法
}
第二种情况2.2 房间号表中没值
{
执行创建房间;
}
}
3.创建房间->检测次数
分布式加锁
再做检查,已防万一已被别的程序创建!
3.1检查发现不可用 返回创建失败->执行检查房间号,检测次数+1
cha
3.2检查可用
1. 根据房间数据创建桌子,生成房间数据
2. 根据房间数据,保存到房间分数表、房间玩家数据表,房间数据表,房间唯一吗表,上次创建房间的房间号表
分布式解锁
4.解散房间
判断房间号是否是自己模块管理的
1.不是本模块管理,发包给管理的模块处理 ->有可能模块不在线,(或者不开了.....手动清楚数据,一般不应该出现这种情况)
2.是本模块管理{
清楚桌子内存数据,
分布式 加锁
1.删除房间号表中的值,
分布式 借锁
2.redis桌子数据异步存储到sql.存储完成后删除redis中的桌子数据
}
}
*/
///
/// 快速加入
///
public class JoinWanFa
{
///
/// 包头
///
public readonly PackHead head;
///
/// 加入房间
///
public readonly JoinFriendRoom jfr;
///
/// 加入玩法
///
///
///
public JoinWanFa(PackHead head, JoinFriendRoom jfr)
{
this.head = head;
this.jfr = jfr;
}
///
/// 获取本次要计算的房间唯一码值
///
///
///
protected void GetRoomWeiYiMa(JoinFriendRoom jfr, HashEntry[] rooms)
{
bool isLast = jfr.lastjoinweiyima == null;
foreach (var item in rooms)
{
if (!isLast)
{
//还没找到上次计算的房间
isLast = item.Name == jfr.lastjoinweiyima;
} //else { //找到了,找本次要运算的房间 2020-06-17 号修改,这个应该写错了,会跳过第一个房间
int cnt = 0;
if (!item.Value.TryParse(out cnt))
{
Debug.Fatal("存储的值错误,怎么存储的值非整数类型!" + jfr.way.weiyima + "," + jfr.way.Clubid);
continue;
}
if (isLast && cnt < jfr.way.dskrule.maxCnt)
{
//房间没满人
jfr.joinweiyima = item.Name; //选定要运算的房间
break;
}
//}
}
}
///
/// 开始房间
///
///
public async Task Start(PackHead head)
{
if (jfr == null)
{
Debug.Error("936983A9-02C9-4B81-A7F4-C06C7385B06B:");
return;
}
if (jfr.deviceInfo == null)
{
Debug.Error("加入玩法时设备信息为空!!!");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotDeviceInfo);
return;
}
if (head.ip == null)
{
Debug.Error("玩家的ip 是 空!!!");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotIp);
return;
}
int userid = head.userid;
if (DoingUserIds.Contains(userid))
{
Debug.Error($"正在处理别的事务:{head.userid}");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskDoing);
return;
}
Debug.Info("进入玩法!");
HashEntry[] rooms = null;
try
{
DoingUserIds.Add(userid);
//如果当前进入房间有值,尝试进入房间
//如果当前进入房间没值,尝试计算当前要进入的房间
if (jfr.joinweiyima == null)
{
//没有想进入的房间,说明是从竞技比赛过来的
if (string.IsNullOrEmpty(jfr.way.weiyima))
{
Debug.Error("玩法的唯一码竟是空值!!!!");
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskParamError);
return;
}
//去找一个房间
rooms = WayManager.instance.GetDesksWeiYiMa(jfr.way.Clubid, jfr.way.weiyima);
Debug.Info("找到所有的房间:" + jfr.way.Clubid + "," + jfr.way.weiyima);
GetRoomWeiYiMa(jfr, rooms);
}
if (jfr.joinweiyima != null)
{
//有则尝试加入房间!
//先把房间找到->
string strRoomNum = Room.GetRoomNum(jfr.joinweiyima);
Debug.Info("找到房间:" + strRoomNum + "," + jfr.joinweiyima);
//管理该房间的节点
ServerNode node = null;
string weiyima = null;
//拿到房间号,先看本地有没有,没有的话则加载起来
int roomnum = 0;
if (int.TryParse(strRoomNum, out roomnum))
{
//有房间号
if (Room.GetWeiyima(roomnum, ref weiyima, ref node))
{
//拿到唯一码
if (weiyima == jfr.joinweiyima)
{
//唯一码一致
if (!GameBase.instance.myUtil.Equals(node))
{
//交给管理模块处理
GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
}
else
{
//本模块处理
//没在本地加载到本地
Debug.Info("本地处理");
DoJoinFriendRoom djfr = new DoJoinFriendRoom(head,
new JoinRoom(roomnum.ToString(), weiyima) { deviceinfo = jfr.deviceInfo },
jfr, false, true);
djfr.IsTestPack = jfr.IsTestPack;
await djfr.Start();
if (!djfr.result)
{
//进入失败 再来一次
Debug.Warning("进入失败,去创建一个房间!");
jfr.lastjoinweiyima = weiyima;
jfr.joinweiyima = null;
var crp1 = new CreateRoomPack()
{
deviceInfo = jfr.deviceInfo, isAuto = jfr.isAuto, ClubId = jfr.ClubId,
Score = jfr.Score,
TaskId = jfr.TaskId,
IsTestPack = jfr.IsTestPack,
deskinfo = new DeskInfo()
{
wayid = jfr.way.weiyima, creatStyle = 5,
creatUserid = jfr.way.Clubid,
rule = jfr.way.dskrule
}
};
if (instance.GetFriendRoomNum(head, crp1))
{
await instance.CreatRoomLogin(head, crp1, true, false);
}
/*
head.otherString = new string[] { djfr.errinfo};
head.packlx = ServerPackAgreement.TransFerHttp;
head.transfer = GameSeverAgreement.notJoinFriendRoom; */
/*
head.packlx = GlobalManager.instance.myUtil.id * 10000 + head.packlx;
GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
Debug.Warning("进入失败,发包再试!" + head.ip);*/
}
else
{
if (jfr.TaskId > 0)
{
GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.Success);
}
else
{
Debug.Info("把玩家拉入桌子!!!");
//把玩家拉入桌子
head.transfer = ServerPackAgreement.ReConnection;
head.packlx = ServerPackAgreement.TransFerHttp;
head.otherInt = new int[] { ServerConfigManager.Instance.ClientId };
GlobalMQ.instance.DeliveryOne(head.GetUtil(),
GlobalMQ.CreateMessage(head, null), true);
}
}
}
return;
}
}
}
}
DeskInfo dskinfo = new DeskInfo();
dskinfo.wayid = jfr.way.weiyima;
dskinfo.creatStyle = 5;
dskinfo.creatUserid = jfr.way.Clubid;
dskinfo.rule = jfr.way.dskrule;
if (dskinfo.rule.RuleEx == null)
dskinfo.rule.RuleEx = new DeskRuleEx();
dskinfo.rule.RuleEx.ReadyTimeout = jfr.ReadyTimeOut;
Debug.Info("去创建朋友房!" + dskinfo.wayid);
CreateRoomPack crp = new CreateRoomPack();
crp.deskinfo = dskinfo;
crp.deviceInfo = jfr.deviceInfo;
crp.isAuto = jfr.isAuto;
crp.ClubId = jfr.ClubId;
crp.Score = jfr.Score;
crp.TaskId = jfr.TaskId;
crp.IsTestPack = jfr.IsTestPack;
//获取到房间号,去创建房间
if (instance.GetFriendRoomNum(head, crp))
{
await instance.CreatRoomLogin(head, crp, true, false);
}
//(head, crp);
}
catch (Exception e)
{
Debug.Error($"报错:{e.Message} {e.StackTrace}");
}
finally
{
DoingUserIds.Remove(userid);
}
}
}
}
}