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
877 lines
31 KiB
C#
877 lines
31 KiB
C#
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using MrWu.Debug;
|
||
using Newtonsoft.Json;
|
||
using Server.Core;
|
||
|
||
namespace Server
|
||
{
|
||
//最近 100 场 最大输值的平均值
|
||
|
||
//N 倍
|
||
|
||
// 连输 3 场以上 每加1场 增加 %30 发好牌的几率
|
||
// 连赢 4 场以上 每加1场 增加 %20 发差牌的几率
|
||
|
||
// 输的局数 是平均值的 N 倍 拥有%100 发好牌的几率
|
||
// 赢的局数 是平均值的 2N 倍 拥有%100 发差牌的几率
|
||
|
||
// 计算最大输值的 除以赔率 换算成积分
|
||
// 当天输的超过 N 倍 x %30 每超过 %1 就增加 1的发好牌几率 封顶 %50
|
||
// 当天赢的超过 N 倍 x %50 每超过 %1 就增加 1的发差牌几率 封顶 %50
|
||
|
||
/// <summary>
|
||
/// 幸运玩家管理器
|
||
/// </summary>
|
||
public partial class LuckPlayerManager : SingleInstance<LuckPlayerManager>
|
||
{
|
||
/// <summary>
|
||
/// 玩法的战绩记录
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, GamePlayerScoreRecord> _wayGamePlayerScoreRecords =
|
||
new ConcurrentDictionary<string, GamePlayerScoreRecord>();
|
||
|
||
private readonly ConcurrentQueue<string> _wayGamePlayerWayIds = new ConcurrentQueue<string>();
|
||
|
||
private const string RecordPath = "LuckRecord/WayRecordDataV2.txt";
|
||
|
||
/// <summary>
|
||
/// 15天未玩游戏就过期
|
||
/// </summary>
|
||
private const long ExpireTime = 15L * 24 * 60 * 60 * 1000;
|
||
|
||
/// <summary>
|
||
/// 统计次数
|
||
/// </summary>
|
||
private const int StaticsCnt = 100;
|
||
|
||
/// <summary>
|
||
/// 输的平均值倍数
|
||
/// </summary>
|
||
private float _loseMultConfig = 3f;
|
||
|
||
private bool isEnable = false;
|
||
|
||
public event Action<GamePlayerScoreRecord, PlayerScoreRecord> PlayerScoreUpdate;
|
||
|
||
public event Action<GamePlayerScoreRecord> WayRecordUpdate;
|
||
|
||
/// <summary>
|
||
/// 加载数据
|
||
/// </summary>
|
||
public void LoadData(float loseMultConfig)
|
||
{
|
||
isEnable = loseMultConfig >= 1f;
|
||
|
||
this._loseMultConfig = loseMultConfig;
|
||
LoadRecordData();
|
||
LoadClubBalanceData();
|
||
Debug.Info($"是否启用:{isEnable} {loseMultConfig}");
|
||
}
|
||
|
||
private void LoadRecordData()
|
||
{
|
||
if (!isEnable)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (_wayGamePlayerScoreRecords.Count > 0)
|
||
{
|
||
Debug.Error("已加载过幸运玩家数据!");
|
||
return;
|
||
}
|
||
|
||
_wayGamePlayerScoreRecords.Clear();
|
||
|
||
try
|
||
{
|
||
if (File.Exists(RecordPath))
|
||
{
|
||
string jsonValue = File.ReadAllText(RecordPath);
|
||
FriendLuckRecord records = JsonConvert.DeserializeObject<FriendLuckRecord>(jsonValue);
|
||
foreach (var record in records.ScoreRecords)
|
||
{
|
||
//先进行数据初始化
|
||
record.PlayerScoreRecords = new ConcurrentDictionary<int, PlayerScoreRecord>();
|
||
foreach (var item in record.Records)
|
||
{
|
||
if (!record.PlayerScoreRecords.TryAdd(item.UserId, item))
|
||
{
|
||
Debug.Error($"怎么会有重复数据:{item.UserId}");
|
||
}
|
||
|
||
record.PlayerUserIds.Enqueue(item.UserId);
|
||
}
|
||
|
||
if (_wayGamePlayerScoreRecords.TryAdd(record.WayId, record))
|
||
{
|
||
_wayGamePlayerWayIds.Enqueue(record.WayId);
|
||
}
|
||
else
|
||
{
|
||
Debug.Error($"玩法怎么会有重复数据:{record.WayId}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error($"LoadRecordData error:{e.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存数据
|
||
/// </summary>
|
||
public void SaveData()
|
||
{
|
||
if (!isEnable)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
FriendLuckRecord records = new FriendLuckRecord();
|
||
foreach (var record in _wayGamePlayerScoreRecords.Values)
|
||
{
|
||
if (record.PlayerScoreRecords != null)
|
||
{
|
||
record.Records.Clear();
|
||
foreach (var item in record.PlayerScoreRecords.Values)
|
||
{
|
||
record.Records.Add(item);
|
||
}
|
||
}
|
||
|
||
records.ScoreRecords.Add(record);
|
||
}
|
||
|
||
string jsonValue = JsonConvert.SerializeObject(records);
|
||
FileInfo fileInfo = new FileInfo(RecordPath);
|
||
if (!fileInfo.Directory.Exists)
|
||
{
|
||
fileInfo.Directory.Create();
|
||
}
|
||
|
||
File.WriteAllText(RecordPath, jsonValue);
|
||
|
||
SaveClubBalanceData();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error($"SaveData error:{e.Message}");
|
||
}
|
||
}
|
||
|
||
private ConcurrentQueue<Random> _randoms = new ConcurrentQueue<Random>();
|
||
|
||
private Random GetRandom()
|
||
{
|
||
if (_randoms.TryDequeue(out Random random))
|
||
{
|
||
return random;
|
||
}
|
||
|
||
return new Random();
|
||
}
|
||
|
||
private void ReleaseRandom(Random random)
|
||
{
|
||
_randoms.Enqueue(random);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取幸运值索引
|
||
/// </summary>
|
||
/// <param name="wayId"></param>
|
||
/// <param name="userIds"></param>
|
||
/// <returns></returns>
|
||
public (int, int) GetLuckValueIndex(string wayId, List<int> userIds)
|
||
{
|
||
int luckIndex = -1;
|
||
int badLuckIndex = -1;
|
||
|
||
if (!isEnable)
|
||
{
|
||
return (luckIndex, badLuckIndex);
|
||
}
|
||
|
||
List<PlayerScoreRecord> scoreRecords = new List<PlayerScoreRecord>();
|
||
|
||
if (_wayGamePlayerScoreRecords.TryGetValue(wayId, out GamePlayerScoreRecord record))
|
||
{
|
||
for (int i = 0; i < userIds.Count; i++)
|
||
{
|
||
if (userIds[i] <= 0)
|
||
{
|
||
Debug.Warning("怎么会有Userid 小于0的情况!");
|
||
return (luckIndex, badLuckIndex);
|
||
}
|
||
|
||
if (record.PlayerScoreRecords.TryGetValue(userIds[i], out PlayerScoreRecord playerRecord))
|
||
{
|
||
scoreRecords.Add(playerRecord);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return (luckIndex, badLuckIndex);
|
||
}
|
||
|
||
Random random = GetRandom();
|
||
//先计算连输 连赢
|
||
for (int i = 0; i < scoreRecords.Count; i++)
|
||
{
|
||
//连续赢 增加发差牌概率
|
||
if (badLuckIndex < 0 && scoreRecords[i].ContinuousWinCnt > 4) //已经连赢4次以上
|
||
{
|
||
scoreRecords[i].ContinuousWin_BadWeight = 20 * (scoreRecords[i].ContinuousWinCnt - 4);
|
||
if (random.Next(0, 100) < scoreRecords[i].ContinuousWin_BadWeight)
|
||
{
|
||
badLuckIndex = i;
|
||
}
|
||
|
||
Debug.Info($"连续赢:{i} {badLuckIndex} 触发发差牌概率:{scoreRecords[i].ContinuousWin_BadWeight}");
|
||
}
|
||
|
||
//连续输 增加发好牌的概率
|
||
if (luckIndex < 0 && scoreRecords[i].ContinuousLoseCnt > 3) //已经连输3次以上
|
||
{
|
||
scoreRecords[i].ContinuosLose_LuckWeight = 30 * (scoreRecords[i].ContinuousLoseCnt - 3);
|
||
if (random.Next(0, 100) < scoreRecords[i].ContinuosLose_LuckWeight)
|
||
{
|
||
luckIndex = i;
|
||
}
|
||
|
||
Debug.Info($"连续输:{i} {luckIndex} 触发发好牌概率:{scoreRecords[i].ContinuosLose_LuckWeight}");
|
||
}
|
||
}
|
||
|
||
//计算新手保护
|
||
if (luckIndex < 0)
|
||
{
|
||
for (int i = scoreRecords.Count - 1; i >= 0; i--)
|
||
{
|
||
if (i == luckIndex || i == badLuckIndex)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (scoreRecords[i].NewPlayerCnt > 0)
|
||
{
|
||
scoreRecords[i].NewPlayerCnt--;
|
||
if (random.NextDouble() < 0.2f)
|
||
{
|
||
luckIndex = i;
|
||
Debug.Info($"新手保护发牌:{scoreRecords[i].UserId}");
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//计算俱乐部平衡
|
||
if (BalanceAllConfigs.Count > 0)
|
||
{
|
||
for (int i = 0; i < scoreRecords.Count; i++)
|
||
{
|
||
if (luckIndex >= 0 && badLuckIndex >= 0)
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (i == luckIndex || i == badLuckIndex)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
ClubPlayerBalanceType clubPlayerBalanceType = GetBalancePlayerType(record.BeiLv,record.WayFightCnt, scoreRecords[i].UserId);
|
||
|
||
// 不计算平衡
|
||
if (clubPlayerBalanceType < ClubPlayerBalanceType.Luck)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (luckIndex < 0 && clubPlayerBalanceType == ClubPlayerBalanceType.Luck)
|
||
{
|
||
luckIndex = i;
|
||
Debug.Info($"俱乐部平衡幸运:{scoreRecords[i].UserId}");
|
||
}
|
||
|
||
if (badLuckIndex < 0 && clubPlayerBalanceType == ClubPlayerBalanceType.BadLuck)
|
||
{
|
||
badLuckIndex = i;
|
||
Debug.Info($"俱乐部平衡倒霉:{scoreRecords[i].UserId}");
|
||
}
|
||
}
|
||
}
|
||
|
||
//计算这段时间的输赢平衡
|
||
if (record.AverageLoseMax < -1)
|
||
{
|
||
for (int i = scoreRecords.Count - 1; i >= 0; i--)
|
||
{
|
||
if (i == luckIndex || i == badLuckIndex)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (luckIndex < 0 && scoreRecords[i].NextFightLuck >= 100)
|
||
{
|
||
luckIndex = i;
|
||
scoreRecords[i].NextFightLuck = 0;
|
||
Debug.Info($"这个位置输的多,发好牌:{i}");
|
||
}
|
||
|
||
if (badLuckIndex < 0 && scoreRecords[i].NextFightBadLuck >= 100)
|
||
{
|
||
badLuckIndex = i;
|
||
scoreRecords[i].NextFightBadLuck = 0;
|
||
Debug.Info($"这个位置赢的多,发差牌:{i}");
|
||
}
|
||
}
|
||
}
|
||
|
||
//计算一天的输赢平衡
|
||
if (record.MaxLoseScore < -1)
|
||
{
|
||
for (int i = 0; i < scoreRecords.Count; i++)
|
||
{
|
||
if (i == luckIndex || i == badLuckIndex)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
float multValue = Math.Abs(scoreRecords[i].DayScore / record.MaxLoseScore);
|
||
|
||
if (multValue > _loseMultConfig)
|
||
{
|
||
//计算幸运
|
||
if (luckIndex < 0 && scoreRecords[i].DayScore < 0 && multValue > _loseMultConfig)
|
||
{
|
||
float luckProbability = (multValue / _loseMultConfig - 1f) - 0.3f;
|
||
if (luckProbability > 0 && random.NextDouble() < luckProbability)
|
||
{
|
||
luckIndex = i;
|
||
Debug.Info($"按天计算 幸运玩家概率:{i} {luckProbability} {multValue} {_loseMultConfig}");
|
||
}
|
||
}
|
||
|
||
if (badLuckIndex < 0 && scoreRecords[i].DayScore > 0 && multValue > _loseMultConfig)
|
||
{
|
||
float badLuckProbability = (multValue / _loseMultConfig - 1f) - 0.5f;
|
||
if (badLuckProbability > 0 && random.NextDouble() < badLuckProbability)
|
||
{
|
||
badLuckIndex = i;
|
||
Debug.Info($"按天计算 倒霉玩家概率:{i} {badLuckProbability} {multValue} {_loseMultConfig}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
ReleaseRandom(random);
|
||
|
||
if (luckIndex >= 0 || badLuckIndex >= 0)
|
||
{
|
||
FriendRoomStatistics.Instance.AddBalance(wayId, luckIndex < 0 ? -1 : scoreRecords[luckIndex].UserId,
|
||
badLuckIndex < 0 ? -1 : scoreRecords[badLuckIndex].UserId);
|
||
Debug.Info($"幸运玩家:{(luckIndex >= 0 ? scoreRecords[luckIndex].UserId : -1)} {(badLuckIndex >= 0 ? scoreRecords[badLuckIndex].UserId : -1)}");
|
||
}
|
||
|
||
return (luckIndex, badLuckIndex);
|
||
}
|
||
|
||
public void AddOnceFight(string wayId, int userid, int score)
|
||
{
|
||
if (!isEnable)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (!_wayGamePlayerScoreRecords.TryGetValue(wayId, out GamePlayerScoreRecord record))
|
||
{
|
||
return;
|
||
}
|
||
|
||
PlayerScoreRecord playerScoreRecord = record.PlayerScoreRecords.GetOrAdd(userid,
|
||
(key) =>
|
||
{
|
||
record.PlayerUserIds.Enqueue(key);
|
||
Debug.Info($"创建玩家x {userid}");
|
||
return new PlayerScoreRecord()
|
||
{
|
||
UserId = key,
|
||
LastEditorTime = TimeInfo.Instance.FrameTime
|
||
};
|
||
}
|
||
);
|
||
|
||
//连续输赢的统计 小赢小输不算连续
|
||
if (score > 5)
|
||
{
|
||
playerScoreRecord.ContinuousWinCnt++;
|
||
playerScoreRecord.ContinuousLoseCnt = 0;
|
||
}
|
||
|
||
if (score < -5)
|
||
{
|
||
playerScoreRecord.ContinuousLoseCnt++;
|
||
playerScoreRecord.ContinuousWinCnt = 0;
|
||
}
|
||
|
||
playerScoreRecord.DayScore += score;
|
||
if (score >= 0)
|
||
playerScoreRecord.WinFightCnt++;
|
||
|
||
if (score > 0 && playerScoreRecord.NewPlayerCnt > 0)
|
||
{
|
||
playerScoreRecord.NewPlayerCnt--;
|
||
}
|
||
|
||
playerScoreRecord.TotalFightCnt++;
|
||
|
||
//最大输值的平均有值,才开始记录
|
||
//记录值
|
||
playerScoreRecord.LastEditorTime = TimeInfo.Instance.FrameTime - 5000;
|
||
|
||
Debug.Info($"单局统计:{record.BeiLv} {record.WayFightCnt} {playerScoreRecord.ToString()}");
|
||
|
||
AddOnceFightScore(record.BeiLv,record.WayFightCnt, userid, score);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加积分到记录 所有局数都打完才记录 临时解散的不算
|
||
/// </summary>
|
||
/// <param name="wayId">玩法Id</param>
|
||
/// <param name="beiLv">倍率</param>
|
||
/// <param name="fightCnt"> fightCnt </param>
|
||
/// <param name="fightScore"> 分值 </param>
|
||
public void AddScoreRecord(string wayId, float beiLv, int fightCnt, FightScore[] fightScore)
|
||
{
|
||
if (!isEnable)
|
||
{
|
||
return;
|
||
}
|
||
|
||
GamePlayerScoreRecord record = _wayGamePlayerScoreRecords.GetOrAdd(wayId, (key) =>
|
||
{
|
||
_wayGamePlayerWayIds.Enqueue(wayId);
|
||
Debug.Info($"创建 GamePlayerScoreRecord:{wayId}");
|
||
return new GamePlayerScoreRecord()
|
||
{
|
||
WayId = wayId,
|
||
BeiLv = beiLv,
|
||
WayFightCnt = fightCnt,
|
||
PlayerScoreRecords = new ConcurrentDictionary<int, PlayerScoreRecord>(),
|
||
LastEditorTime = TimeInfo.Instance.FrameTime
|
||
};
|
||
});
|
||
|
||
Debug.Info($"_wayGamePlayerScoreRecords Count:{_wayGamePlayerScoreRecords.Count}");
|
||
|
||
int winMaxScore = 0;
|
||
int loseMaxScore = 0;
|
||
StringBuilder stringBuilder = new StringBuilder();
|
||
|
||
foreach (var score in fightScore)
|
||
{
|
||
if (score.Value > winMaxScore)
|
||
{
|
||
winMaxScore = (int)score.Value;
|
||
}
|
||
|
||
if (score.Value < loseMaxScore)
|
||
{
|
||
loseMaxScore = (int)score.Value;
|
||
}
|
||
}
|
||
|
||
//最大输值的平均有值,才开始记录
|
||
//记录值
|
||
foreach (var score in fightScore)
|
||
{
|
||
stringBuilder.Append($"userid:{score.UserId} value:{score.Value} ");
|
||
|
||
PlayerScoreRecord playerScoreRecord = record.PlayerScoreRecords.GetOrAdd(score.UserId,
|
||
(key) =>
|
||
{
|
||
record.PlayerUserIds.Enqueue(key);
|
||
Debug.Info($"创建玩家- {score.UserId}");
|
||
return new PlayerScoreRecord()
|
||
{
|
||
UserId = key,
|
||
NewPlayerCnt = 10, //前10局新手保护 概率是%20 所以相当于最多2次机会
|
||
LastEditorTime = TimeInfo.Instance.FrameTime
|
||
};
|
||
}
|
||
);
|
||
|
||
playerScoreRecord.PingHengFightCnt--;
|
||
if (playerScoreRecord.PingHengFightCnt <= 0)
|
||
{
|
||
Debug.Info($"平衡场次重算:{playerScoreRecord.UserId}");
|
||
Random random = GetRandom();
|
||
playerScoreRecord.PingHengFightCnt = random.Next(60, 100);
|
||
if (playerScoreRecord.DayScore < 0)
|
||
{
|
||
playerScoreRecord.DayScore /= 2;
|
||
}
|
||
else
|
||
{
|
||
playerScoreRecord.DayScore = 0;
|
||
}
|
||
|
||
ReleaseRandom(random);
|
||
}
|
||
|
||
playerScoreRecord.TotalScore += (int)score.Value;
|
||
Debug.Info($"添加:{playerScoreRecord.UserId} {score.Value} {playerScoreRecord.TotalScore}");
|
||
if (record.AverageLoseMax < -1)
|
||
{
|
||
//有了参考值才计算 幸运 或者倒霉玩家
|
||
playerScoreRecord.Score += (int)score.Value;
|
||
playerScoreRecord.NextFightLuck = 0;
|
||
playerScoreRecord.NextFightBadLuck = 0;
|
||
float multConfigValue = Math.Abs((float)playerScoreRecord.Score / record.AverageLoseMax);
|
||
if (playerScoreRecord.Score < 0 && multConfigValue > _loseMultConfig)
|
||
{
|
||
//给一个幸运的概率
|
||
playerScoreRecord.NextFightLuck = 100;
|
||
playerScoreRecord.Score = 0;
|
||
|
||
Debug.Info(
|
||
$"触发幸运玩家:{playerScoreRecord.UserId} {playerScoreRecord.Score} {multConfigValue}:{_loseMultConfig}");
|
||
}
|
||
|
||
if (playerScoreRecord.Score > 0 && multConfigValue > 2 * _loseMultConfig)
|
||
{
|
||
playerScoreRecord.NextFightBadLuck = 100;
|
||
playerScoreRecord.Score = 0;
|
||
Debug.Info(
|
||
$"触发倒霉玩家:{playerScoreRecord.UserId} {playerScoreRecord.Score} {multConfigValue}:{_loseMultConfig}");
|
||
}
|
||
}
|
||
|
||
PlayerScoreUpdate?.Invoke(record, playerScoreRecord);
|
||
|
||
AddSessionFightScore(beiLv,fightCnt,playerScoreRecord.UserId, (int)score.Value,Math.Abs(score.Value - winMaxScore) < 0.01f);
|
||
}
|
||
|
||
record.TotalLoseMax += loseMaxScore;
|
||
record.TotalWinMax += winMaxScore;
|
||
if (loseMaxScore < record.LoseMax)
|
||
{
|
||
record.LoseMax = loseMaxScore;
|
||
}
|
||
|
||
if (winMaxScore > record.WinMax)
|
||
{
|
||
record.WinMax = winMaxScore;
|
||
}
|
||
|
||
record.FightCnt++;
|
||
|
||
//第一次 只算一半的局数,先把值算出来
|
||
if ((record.AverageLoseMax > -1 && record.FightCnt >= StaticsCnt / 2) || record.FightCnt >= StaticsCnt)
|
||
{
|
||
record.AverageLoseMax = (int)(record.TotalLoseMax / record.FightCnt);
|
||
record.MaxLoseScore = (int)(record.AverageLoseMax / beiLv);
|
||
record.FightCnt = 0;
|
||
record.TotalLoseMax = 0;
|
||
record.TotalWinMax = 0;
|
||
}
|
||
|
||
record.LastEditorTime = TimeInfo.Instance.FrameTime;
|
||
WayRecordUpdate?.Invoke(record);
|
||
Debug.Info($"总局统计: {record.ToString()}");
|
||
}
|
||
|
||
public string GetPlayerInfo(string wayId, int userid)
|
||
{
|
||
if (_wayGamePlayerScoreRecords.TryGetValue(wayId, out GamePlayerScoreRecord record))
|
||
{
|
||
if (record.PlayerScoreRecords.TryGetValue(userid, out PlayerScoreRecord playerScoreRecord))
|
||
{
|
||
return playerScoreRecord.ToString();
|
||
}
|
||
}
|
||
|
||
return "none";
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
if (!isEnable)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 移除不使用的数据
|
||
if (_wayGamePlayerWayIds.Count > 0)
|
||
{
|
||
try
|
||
{
|
||
if (_wayGamePlayerWayIds.TryDequeue(out string wayid))
|
||
{
|
||
bool isRemove = true;
|
||
if (_wayGamePlayerScoreRecords.TryGetValue(wayid, out GamePlayerScoreRecord record))
|
||
{
|
||
if (TimeInfo.Instance.FrameTime - record.LastEditorTime > ExpireTime)
|
||
{
|
||
if (!_wayGamePlayerScoreRecords.TryRemove(wayid, out record))
|
||
{
|
||
isRemove = false;
|
||
}
|
||
|
||
Debug.Info($"移除 - {wayid}");
|
||
}
|
||
else
|
||
{
|
||
// 计算玩家许久未使用的值
|
||
if (record.PlayerUserIds.Count > 0)
|
||
{
|
||
if (record.PlayerUserIds.TryDequeue(out int userid))
|
||
{
|
||
bool isDel = true;
|
||
if (record.PlayerScoreRecords.TryGetValue(userid,
|
||
out PlayerScoreRecord playerScoreRecord))
|
||
{
|
||
if (TimeInfo.Instance.FrameTime - playerScoreRecord.LastEditorTime >
|
||
ExpireTime)
|
||
{
|
||
Debug.Info($"过期移除:{userid}");
|
||
if (!record.PlayerScoreRecords.TryRemove(userid, out playerScoreRecord))
|
||
{
|
||
isDel = false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
isDel = false;
|
||
}
|
||
}
|
||
|
||
if (!isDel)
|
||
{
|
||
record.PlayerUserIds.Enqueue(userid);
|
||
}
|
||
}
|
||
}
|
||
|
||
isRemove = false;
|
||
}
|
||
}
|
||
|
||
if (!isRemove)
|
||
{
|
||
_wayGamePlayerWayIds.Enqueue(wayid);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error($"LuckPlayerManager Update Error:{e.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 朋友房幸运玩家积分记录
|
||
/// </summary>
|
||
public class FriendLuckRecord
|
||
{
|
||
public List<GamePlayerScoreRecord> ScoreRecords = new List<GamePlayerScoreRecord>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 玩家积分记录
|
||
/// </summary>
|
||
public class GamePlayerScoreRecord
|
||
{
|
||
/// <summary>
|
||
/// 玩法ID
|
||
/// </summary>
|
||
public string WayId;
|
||
|
||
/// <summary>
|
||
/// 玩法局数
|
||
/// </summary>
|
||
public int WayFightCnt;
|
||
|
||
/// <summary>
|
||
/// 每局赢的最大值总和
|
||
/// </summary>
|
||
public long TotalWinMax;
|
||
|
||
/// <summary>
|
||
/// 记录赢的最大值
|
||
/// </summary>
|
||
public long WinMax;
|
||
|
||
/// <summary>
|
||
/// 每局输的最大值总和
|
||
/// </summary>
|
||
public long TotalLoseMax;
|
||
|
||
/// <summary>
|
||
/// 记录输的最大值
|
||
/// </summary>
|
||
public long LoseMax;
|
||
|
||
/// <summary>
|
||
/// 场次
|
||
/// </summary>
|
||
public int FightCnt;
|
||
|
||
/// <summary>
|
||
/// 最近一百次的输的平均
|
||
/// </summary>
|
||
public int AverageLoseMax;
|
||
|
||
/// <summary>
|
||
/// 倍率
|
||
/// </summary>
|
||
public float BeiLv;
|
||
|
||
/// <summary>
|
||
/// AverageLoseMax / BeiLv
|
||
/// </summary>
|
||
public int MaxLoseScore;
|
||
|
||
/// <summary>
|
||
/// 玩家积分记录 - 用来序列化
|
||
/// </summary>
|
||
public List<PlayerScoreRecord> Records = new List<PlayerScoreRecord>();
|
||
|
||
/// <summary>
|
||
/// 上次修改的时间
|
||
/// </summary>
|
||
public long LastEditorTime;
|
||
|
||
/// <summary>
|
||
/// 玩家的Userids
|
||
/// </summary>
|
||
[JsonIgnore] public ConcurrentQueue<int> PlayerUserIds = new ConcurrentQueue<int>();
|
||
|
||
/// <summary>
|
||
/// 玩家的积分记录 - 用来计算
|
||
/// </summary>
|
||
[JsonIgnore] public ConcurrentDictionary<int, PlayerScoreRecord> PlayerScoreRecords = null;
|
||
|
||
public override string ToString()
|
||
{
|
||
return
|
||
$"wayid:{WayId}, AverageLoseMax:{AverageLoseMax}, fightcnt:{FightCnt}, winmax:{WinMax}, losemax:{LoseMax}, totalwinmax:{TotalWinMax}, totallosemax:{TotalLoseMax}, lasteditortime:{LastEditorTime}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 玩家积分记录
|
||
/// </summary>
|
||
public class PlayerScoreRecord
|
||
{
|
||
/// <summary>
|
||
/// 玩家ID
|
||
/// </summary>
|
||
public int UserId;
|
||
|
||
/// <summary>
|
||
/// 距上次发牌累计的积分
|
||
/// </summary>
|
||
public int Score;
|
||
|
||
/// <summary>
|
||
/// 连续赢的次数
|
||
/// </summary>
|
||
public int ContinuousWinCnt;
|
||
|
||
/// <summary>
|
||
/// 连续输的次数
|
||
/// </summary>
|
||
public int ContinuousLoseCnt;
|
||
|
||
/// <summary>
|
||
/// 一段时间的分
|
||
/// </summary>
|
||
public int DayScore;
|
||
|
||
/// <summary>
|
||
/// 平衡 场次
|
||
/// </summary>
|
||
public int PingHengFightCnt;
|
||
|
||
/// <summary>
|
||
/// 获得的总分
|
||
/// </summary>
|
||
public int TotalScore;
|
||
|
||
/// <summary>
|
||
/// 赢的局数
|
||
/// </summary>
|
||
public int WinFightCnt;
|
||
|
||
/// <summary>
|
||
/// 总战斗次数
|
||
/// </summary>
|
||
public int TotalFightCnt;
|
||
|
||
/// <summary>
|
||
/// 上次修改的时间
|
||
/// </summary>
|
||
public long LastEditorTime;
|
||
|
||
/// <summary>
|
||
/// 新手保护的局数
|
||
/// </summary>
|
||
public int NewPlayerCnt;
|
||
|
||
/// <summary>
|
||
/// 下一个大局 有一个幸运的概率
|
||
/// </summary>
|
||
[JsonIgnore] public int NextFightLuck;
|
||
|
||
/// <summary>
|
||
/// 下一个大局 有一个倒霉的概率
|
||
/// </summary>
|
||
[JsonIgnore] public int NextFightBadLuck;
|
||
|
||
/// <summary>
|
||
/// 连续赢 输的权重
|
||
/// </summary>
|
||
[JsonIgnore] public int ContinuousWin_BadWeight;
|
||
|
||
/// <summary>
|
||
/// 连续输 赢的权重
|
||
/// </summary>
|
||
[JsonIgnore] public int ContinuosLose_LuckWeight;
|
||
|
||
public override string ToString()
|
||
{
|
||
return
|
||
$"userid:{UserId}, score:{Score}, TotalScore:{TotalScore}, ContinuousWinCnt:{ContinuousWinCnt},ContinuousLoseCnt:{ContinuousLoseCnt},LastEditorTime:{LastEditorTime},DayScore:{DayScore},WinFightCnt:{WinFightCnt},TotalFightCnt:{TotalFightCnt}";
|
||
}
|
||
}
|
||
|
||
public struct FightScore
|
||
{
|
||
/// <summary>
|
||
/// 玩家ID
|
||
/// </summary>
|
||
public int UserId;
|
||
|
||
/// <summary>
|
||
/// 玩家的分数
|
||
/// </summary>
|
||
public double Value;
|
||
}
|
||
}
|
||
} |