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

764 lines
24 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.

using GameData;
using MrWu.Debug;
using Server.AliyunSDK.Logic;
using Server.Data;
using System;
using System.Collections.Generic;
using System.Text;
using GameMessage;
using MrWu.Basic;
namespace Server
{
/// <summary>
/// 金币场桌子
/// </summary>
public partial class Desk_gold : Desk
{
/// <summary>
/// 是否是朋友房
/// </summary>
public override bool isFriend => false;
/// <summary>
/// 构造器
/// </summary>
/// <param name="ting"></param>
/// <param name="tingConfig"></param>
/// <param name="id"></param>
/// <param name="info"></param>
public Desk_gold(TingManager ting, Server.Config.TingConfig tingConfig, int id, DeskInfo info = null) : base(ting, tingConfig,
id, info)
{
}
/// <summary>
/// 桌子上添加玩家
/// </summary>
/// <param name="pl">玩家</param>
/// <param name="roomid">房间id</param>
/// <returns></returns>
protected override int AddPlayerArray(PlayerDataAsyc pl, int roomid)
{
int seat = -1;
int len = Count;
for (int i = 0; i < len; i++)
{
if (pls[i] != null && pls[i].userid == pl.userid)
{
Debug.Error("桌上有相同玩家:" + pl.userid);
return seat;
}
if (pls[i] == null)
{
PlayerChange(pl, false);
if (!GameManager.instance.SetPlayerShadow(pl, roomid)) //2020/02/22 增加 判断,没获取到影子就跳走
return seat;
if (gameMode == 1 && pl.isRobot)
{
pl.nickname = pl.shadows[0].nickname;
}
pls[i] = pl;
seat = i;
pl.DepositChange = PlayerDepositChange;
break;
}
}
return seat;
}
/// <summary>
/// 添加玩家
/// </summary>
/// <param name="pl"></param>
/// <param name="roomid"></param>
/// <returns></returns>
public override bool AddPlayer(PlayerDataAsyc pl, int roomid)
{
StringBuilder logStringBuilder = new StringBuilder();
try
{
if (PlayerCnt >= tingConfig.MaxPlayerCnt)
{
Debug.Error("玩家数量超过最大值!" + PlayerCnt + "," + id + "," + state);
return false;
}
long key1 = Debug.StartTiming();
pl.seat = AddPlayerArray(pl, roomid);
//Debug.Info("玩家上桌:" + pl.seat + ",userid:" + pl.userid);
logStringBuilder.AppendLine("AddPlayerArray time:" + Debug.GetRunTime(key1));
if (pl.seat < 0)
{
Debug.Error("程序错误,上桌失败!");
return false;
}
//在桌上
pl.state = (int)PlayerState.Desk;
pl.SetDeposit(false);
pl.tingid = tingConfig.TingId;
pl.deskid = id;
if (roomid < 0)
{ //如果是机器人则自动获取房间id
//如果是机器人则自动获取房间id
if (!pl.isRobot)
Debug.Error("程序错误,只有机器人排队才能传递小于0的值");
long key2 = Debug.StartTiming();
int len = pls.Length;
for (int i = 0; i < len; i++)
{
PlayerDataAsyc pda = pls[i];
if (pda == null)
continue;
if (!pda.isRobot)
{
pl.roomid = pda.roomid;
}
}
logStringBuilder.AppendLine("GetRoomid:" + Debug.GetRunTime(key2));
}
else
pl.roomid = roomid;
RedressRobotMoney(pl);
long key3 = Debug.StartTiming();
if (!pl.isRobot && GameManager.instance.isExistsRoom(roomid))
{
var room = GameManager.instance.FindRoom(roomid);
room.SetRoomPlayerCnt(pl);
}
logStringBuilder.AppendLine("SetRoomPlayerCnt time:" + Debug.GetRunTime(key3));
if (gameMode == 1)
{
//百家乐,发送桌上玩家信息给客户端
//发送添加玩家包
SendAddPlayer(pl);
//发送所有玩家信息给玩家
SendAllPlayerInfo(pl);
//开战
pl.state = (int)PlayerState.War;
}
else
{
//其他模式,发送自己信息给客户端
long key4 = Debug.StartTiming();
SendAllPlayerInfo(pl, true);
logStringBuilder.AppendLine("SendAllPlayerInfo time:" + Debug.GetRunTime(key4));
}
long key5 = Debug.StartTiming();
//发送场景切换
GeneralSendPack.SendSceneChange(pl, SceneType.Desk);
if ((state & DeskState.War) > 0)
{
Debug.Error("进入桌子桌子正在开战!");
Reconnect(pl.seat);
}
logStringBuilder.AppendLine("SendPack time:" + Debug.GetRunTime(key5));
return true;
}
finally
{
}
}
protected virtual void RedressRobotMoney(PlayerDataAsyc pl)
{
if (pl.isRobot)
{
RoomManager roomManager = GameManager.instance.FindRoom(pl.roomid);
if (roomManager != null)
{
if (pl.money < roomManager.config.MinMoney || pl.money > roomManager.config.MaxMoney)
{
if (roomManager.config.MinMoney < 10000)
{
pl.money = BaseFun.random.Next(roomManager.config.MinMoney, roomManager.config.MaxMoney);
}
else
{
int minValue = roomManager.config.MinMoney / 10000;
int maxValue = roomManager.config.MaxMoney / 10000;
pl.money = BaseFun.random.Next(minValue, maxValue) * 10000;
}
Debug.ImportantLog("纠正机器人身上的钱!");
}
}
else
{
Debug.Error($"纠正机器人Money时不存在房间:{pl.roomid}");
}
}
}
/// <summary>
/// 从玩家列表中移除玩家
/// </summary>
/// <param name="pl"></param>
/// <returns></returns>
public override bool RemovePlayer(PlayerDataAsyc pl)
{
if ((state & DeskState.Idle) > 0)
{
return false;
}
PlayerDataAsyc tmppl;
int len = Count;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null)
continue;
if (pl.userid == tmppl.userid)
{
pl.seat = -1;
pl.DepositChange = null;
pls[i] = null;
PlayerChange(pl, true);
Quit(i); //玩家退出事件
//设置玩家数量
SendRemovePlayer(i);
return true;
}
}
return false;
}
bool strartWarError = false;
/// <summary>
/// 开战检查定时器
/// </summary>
protected void StartWarTimer()
{
if (gameMode == 1)
{
//百家乐,有人就开战
if ((state & DeskState.Idle) > 0)
return;
if ((state & DeskState.War) == 0)
{ //未开战
//未开战
if (PlayerCnt > 0)
{
//闲置 但是有人,开战
Debug.Info("游戏开战:" + this.id);
StartWar();
}
}
return;
}
else
{
//匹配模式,满人就开战
if ((state & DeskState.Queue) == 0)
{
//状态不是排队,跳走
return;
}
PlayerDataAsyc tmppl;
if (PlayerCnt >= ting.config.MinPlayerCnt)
{
//大于最小可开战的人,全部自动准备
//Debug.Log("人到齐了,自动准备!");
int len = Count;
for (int i = 0; i < len; i++)
{
//全部自动准备
tmppl = pls[i];
if (tmppl == null)
continue;
Ready(tmppl, false); //--准备 自动准备,迎合原先的设计
}
//检查是否开战
bool war = true;
for (int i = len - 1; i >= 0; i--)
{
tmppl = pls[i];
if (tmppl == null)
continue;
if (tmppl.state != (int)PlayerState.Ready)
{
war = false;
if (!strartWarError)
{
Debug.Fatal("不该出现有人没准备的情况" + tmppl.ToString());
strartWarError = true;
}
break;
}
}
if (war)
{
//开战
StartWar();
}
else
{
Debug.Error("不应该存在的情况!");
ting.AddIdleing(this);
}
}
}
}
/// <summary>
/// 检查战斗超时的定时器
/// </summary>
private int CheckWarTimeOutTimeCnt = 0;
/// <summary>
/// 检查战斗超时的时间间隔
/// </summary>
private const int DoCheckTimeOutInterval = 60;
/// <summary>
/// 战斗检查超时
/// </summary>
private void CheckWarTimeOutTimer()
{
if (gameMode == 1) //百家乐模式不检查
return;
if ((state & DeskState.War) == 0)
return;
CheckWarTimeOutTimeCnt++;
if (CheckWarTimeOutTimeCnt < DoCheckTimeOutInterval)
{
return;
}
CheckWarTimeOutTimeCnt = 0;
DateTime wartimeout = DateTime.Now.AddMinutes(-warTimeOut);
//Debug.Error("检查桌子是否超时:" + warTime + "," + wartimeout);
//检查是否超时
if (warTime < wartimeout) //开战时间在超时之前
{
//先拿到所有的玩家
List<PlayerDataAsyc> tmps = new List<PlayerDataAsyc>(pls);
this.WarOver();
if (gameLogic.TimeOutWarOver())
{
int cnt = tmps.Count;
for (int i = cnt - 1; i >= 0; i--)
{
//循环所有的玩家在-在线的强制离线
if (tmps[i] != null && !tmps[i].isRobot)
{
Debug.Error("超时未打完!!!" + tmps[i].userid + "," + tmps[i].state + "," + tmps[i].id);
GameManager.instance.QuitGame(tmps[i], "CheckWarTimeOutTimer");
}
}
}
}
}
/// <summary>
/// 金币场秒级定时器
/// </summary>
public override void SecondTime()
{
//金币场模式
StartWarTimer();
CheckWarTimeOutTimer();
if ((state & DeskState.War) > 0)
{
PlayerDataAsyc tmppl;
for (int i = Count - 1; i >= 0; i--)
{
tmppl = pls[i];
if (tmppl == null)
{
continue;
}
if (!tmppl.isDePosit && tmppl.outline > 0)
{
tmppl.OutLineTime++;
if (tmppl.OutLineTime > 10)
{
GameManager.instance.DoTuoGuanCalc(tmppl, true);
}
}
}
}
}
/// <summary>
/// 开战处理
/// </summary>
public override void StartWar()
{
if (!GlobalManager.instance.IsCanWar)
{
SendNoWarPack();
return;
}
base.StartWar();
CheckWarTimeOutTimeCnt = 0;
if (gameMode != 1)
{
PlayerDataAsyc tmppl;
int len = Count;
for (int i = 0; i < len; i++)
{
tmppl = pls[i];
if (tmppl == null)
continue;
if (!tmppl.isRobot)
{
// Debug.Error("开战发送全桌玩家信息:" + tmppl.userid);
SendAllPlayerInfo(tmppl);
}
tmppl.state = (int)PlayerState.War;
tmppl.WarMoney = 0;
}
}
SendStartWar();
gameLogic.StartWar();
}
/// <summary>
///
/// </summary>
public override void WarOver()
{
//战斗结束 处理完,
// 桌子放入限制的桌子列表, 玩家状态全部在房间中, 客户端记录上次房间进入的厅,发送过来...
// 人进入房间
//
//要把人全部踢出桌子!
/*
* 1.修改房间状态
* 2.修改厅中的列表
* 3.处理玩家信息
* 4.检查房间重新排队
*
* */
try
{
SaveGoldRecordData();
}
catch (Exception e)
{
Debug.Error($"保存战绩出错:{e.Message}");
}
if (CalculateIsRobotWin())
{
ting.robotWinCnt++;
}
base.WarOver();
GetOverHandle().WarOver();
//发送结束信号
}
/// <summary>
/// 计算是否机器人胜利
/// </summary>
private bool CalculateIsRobotWin()
{
long winMoney = 0;
for (int i = 0; i < Count; i++)
{
if (pls[i] == null || !pls[i].isRobot)
continue;
winMoney += pls[i].WarMoney;
}
return winMoney > 0;
}
protected WarOverHandle generalHandle;
protected WarOverHandle baijialeHandle;
protected virtual WarOverHandle GetOverHandle()
{
if (generalHandle == null)
generalHandle = new GeneralWarOver(this);
if (baijialeHandle == null)
baijialeHandle = new BaiJiaLeWarOver(this);
if (gameMode != 1)
return generalHandle;
return baijialeHandle;
}
/// <summary>
/// 保存金币场战绩记录
/// </summary>
public void SaveGoldRecordData()
{
// 这里还要看影子数据 - 这样存下去就是真实数据
// 分类 金币模式,比赛模式,朋友房模式 与回放数据绑定
List<WarGoldRecordItemData> datas = new List<WarGoldRecordItemData>();
List<WarRecordPlayerData> players = new List<WarRecordPlayerData>();
for (int i = 0; i < Count; i++)
{
if (pls[i] == null || pls[i].isRobot || pls[i].MatchObj != null)
continue;
players.Clear();
for (int j = 0; j < Count; j++)
{
pls[j].UpdateShadow(pls[i].roomid,IsMatchDesk && !pls[i].IsJoinMatch);
players.Add(new WarRecordPlayerData()
{
UserId = pls[j].userid, //这里有鬼的问题后面把鬼的ID 头像固定化。不然显示要穿帮
Score = 0, //金币场暂时不存这个,这个现在统计不到
});
}
RoomManager roomManager = GameManager.instance.FindRoom(pls[i].roomid);
Server.Config.CastlesConfig config = roomManager?.config;
WarGoldRecordItemData data = new WarGoldRecordItemData();
int shui = GameManager.instance.FindRoom(pls[i].roomid).config.Tax;
data.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
data.GameId = ServerConfigManager.Instance.ClientId;
data.UserId = pls[i].userid;
data.Score = pls[i].WarMoney;
data.Tax = shui;
if (config != null)
{
data.BeiLv = config.BeiLv;
data.Tax = config.Tax;
}
data.Content = players;
datas.Add(data);
Debug.Info($"上传玩家{pls[i].userid}金币场战绩数据");
}
if (datas.Count > 0)
{
WarRecordSLSManager.Instance.ReportGoldAsync(datas);
}
}
/// <summary>
/// 加载桌子
/// </summary>
/// <returns></returns>
public override bool LoadDesk()
{
return true;
}
/// <summary>
///
/// </summary>
/// <param name="seat"></param>
/// <param name="lx"></param>
/// <param name="num"></param>
public override void IncMoney(int seat, int lx, int num)
{
return;
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
public override void LoadMem(byte[] data, bool isOld)
{
Debug.Error("金币场不存在加载桌子内存!");
}
/// <summary>
/// 战斗结束的处理
/// </summary>
protected interface WarOverHandle
{
/// <summary>
/// 桌子
/// </summary>
Desk_gold desk { get; }
/// <summary>
/// 战斗结束
/// </summary>
void WarOver();
}
/// <summary>
/// 普通游戏的战斗结束
/// </summary>
protected class GeneralWarOver : WarOverHandle
{
/// <summary>
/// 桌子
/// </summary>
public Desk_gold desk { get; private set; }
/// <summary>
/// 构造器
/// </summary>
/// <param name="desk"></param>
public GeneralWarOver(Desk_gold desk)
{
this.desk = desk;
}
/// <summary>
/// 战斗结束处理
/// </summary>
public void WarOver()
{
Debug.Log("普通游戏战斗结束!!!!");
//金币场超过上限检测在 进入桌子的时候
if (!desk.ting.RemoveWaring(desk))
{
Debug.Error("竟然没能移出桌子!");
}
bool isAllRobot = desk.RealPerson == 0;
PlayerDataAsyc tmppl;
int len = desk.Count;
for (int i = len - 1; i >= 0; i--)
{
tmppl = desk[i];
if (tmppl == null)
continue;
if (tmppl.state == (int)PlayerState.War)
{
tmppl.state = (int)PlayerState.Desk;
}
else
{
Debug.Error("不可能存在的情况asdasjbdkjasb!" + tmppl.state);
tmppl.state = (int)PlayerState.Desk;
}
if (tmppl.outline != 1)
desk.SendWarOver(tmppl);
if (!tmppl.isRobot) //玩家不是机器人-打完就退出桌子,此处会检查回收
desk.ting.QuitDesk(tmppl, false);
if (tmppl.outline == 1)
{
//Debug.Error("玩家已经离线,退出桌子处理:" + tmppl);
GameManager.instance.QuitGame(tmppl, "WarOver");
}
}
if (isAllRobot)
{
for (int i = len - 1; i >= 0; i--)
{
tmppl = desk[i];
if (tmppl == null) continue;
desk.ting.QuitDesk(tmppl, false);
}
desk.ClearPlayer();
}
}
}
/// <summary>
/// 百家乐战斗结束
/// </summary>
public class BaiJiaLeWarOver : WarOverHandle
{
/// <summary>
/// 桌子
/// </summary>
public Desk_gold desk { get; private set; }
/// <summary>
/// 构造器
/// </summary>
/// <param name="desk"></param>
public BaiJiaLeWarOver(Desk_gold desk)
{
this.desk = desk;
}
/// <summary>
/// 战斗结束处理
/// </summary>
public void WarOver()
{
Debug.Info("百家乐战斗结束!!!!!!" + desk.id);
//检查游戏币是否超过上限,超过则把玩家踢出去-让他手动去存金币
int len = desk.Count;
for (int i = len - 1; i >= 0; i--)
{
if (desk[i] == null)
continue;
if (desk[i].money >= playerData.MaxMoney)
{
if (desk[i].isRobot)
desk[i].money -= 500000000;
}
}
if (desk.PlayerCnt == 0)
{
if (desk.ting.RemoveWaring(desk))
{
Debug.Error("没有人的桌子移出开战列表却失败!");
}
}
}
}
}
}