You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
17 KiB
503 lines
17 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
using Sog;
|
|
using ProtoCSStruct;
|
|
|
|
namespace World
|
|
{
|
|
public static class RankSvc
|
|
{
|
|
private static long m_serverStartTime;
|
|
private static long m_lastLoadDbReqTime;
|
|
private static long m_lastSaveDbTime;
|
|
private static long m_lastUpdateRankTime;// 更新排行榜里的玩家数据,5秒一次
|
|
|
|
//5秒后开始加载数据库,如果失败30秒后再次尝试
|
|
private static void TickLoadFromDb(long nowSecond)
|
|
{
|
|
if (RankUtils.IsLoadRankDataFromDbSuccess())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_serverStartTime == 0)
|
|
{
|
|
m_serverStartTime = nowSecond;
|
|
}
|
|
|
|
if (nowSecond - m_serverStartTime > 5 && nowSecond - m_lastLoadDbReqTime > 30)
|
|
{
|
|
m_lastLoadDbReqTime = nowSecond;
|
|
|
|
}
|
|
}
|
|
|
|
//private static void SaveRankRecord(WorldRankDataRecord record)
|
|
//{
|
|
// if (record.NeedSave() == false)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// TraceLog.Trace("SaveRankRecord rankId {0} beginTime {1} dataSeq {2}", record.RankId, record.BeginTime, record.DataSeq);
|
|
|
|
// ref SSSaveRankDbReq req = ref CSStructPool<SSSaveRankDbReq>.Instance.GetObjRef();
|
|
// req.RankId = record.RankId;
|
|
// req.BeginTime = record.BeginTime;
|
|
// req.Data = record.Data;
|
|
|
|
// req.DataSeq = record.DataSeq;
|
|
|
|
// long nowMs = WorldServerUtils.GetTimeSecond() * 1000;
|
|
|
|
// record.OnSaveReq(nowMs);
|
|
|
|
// uint dbServerID = DBServerIDUtils.GetGameDBServerID(0);
|
|
// WorldServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveRankDbReq, ref req, 0);
|
|
|
|
//}
|
|
|
|
private static void TickSaveRankData(long nowSecond)
|
|
{
|
|
//平时300秒保存一次,停服的时候5秒
|
|
long saveIntervalSecond = 300;
|
|
|
|
if (WorldServerUtils.GetApp().CurrStopStage == ServerStopStage.stopping)
|
|
{
|
|
saveIntervalSecond = 5;
|
|
}
|
|
|
|
if (nowSecond - m_lastSaveDbTime <= saveIntervalSecond)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_lastSaveDbTime = nowSecond;
|
|
|
|
WorldRankData rankData = WorldServerUtils.GetWorldRankData();
|
|
|
|
foreach (var rankItem in rankData.AllRank.Values)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
public static void OnTick(long nowSecond)
|
|
{
|
|
TickLoadFromDb(nowSecond);
|
|
|
|
if (!RankUtils.IsLoadRankDataFromDbSuccess())
|
|
{
|
|
return;
|
|
}
|
|
|
|
TickRefreshRank(nowSecond);
|
|
|
|
//更新排行榜里的玩家排名,有新的玩家数据的时候
|
|
TickUpdateRank(nowSecond);
|
|
|
|
TickSaveRankData(nowSecond);
|
|
|
|
}
|
|
|
|
private static void TickRefreshRank(long nowSecond)
|
|
{
|
|
WorldRankData rankData = WorldServerUtils.GetWorldRankData();
|
|
|
|
foreach (var rankItem in rankData.AllRank.Values)
|
|
{
|
|
if (rankItem.CurRecord != null)
|
|
{
|
|
//TickRefreshCurRankRecord(nowSecond, rankItem.CurRecord, rankItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
//private static void TickRefreshCurRankRecord(long nowSecond, WorldRankDataRecord record, WorldRankDataOne rankDataOne)
|
|
//{
|
|
// var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId);
|
|
// if (rankDesc == null)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// long newBeginTime = 0;
|
|
|
|
// // 周榜
|
|
// if (rankDesc.refreshType == 1)
|
|
// {
|
|
// if (AppTime.IsSameWeek127(nowSecond, record.BeginTime))
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond);
|
|
// }
|
|
|
|
// if (rankDesc.refreshType == 2)
|
|
// {
|
|
// if (AppTime.IsSameDay(nowSecond, record.BeginTime))
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// newBeginTime = AppTime.GetTodayStartTime(nowSecond);
|
|
// }
|
|
|
|
// if (record.Data.AwardTime != 0)
|
|
// {
|
|
// TraceLog.Error("TickRefreshRankRecord rankId {0} beginTime {1} already award at time {2}"
|
|
// , record.RankId, record.BeginTime, record.Data.AwardTime);
|
|
// return;
|
|
// }
|
|
|
|
// //刷新
|
|
// record.Data.AwardTime = nowSecond;
|
|
|
|
// TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}"
|
|
// , record.RankId, record.BeginTime, record.Data.AwardTime);
|
|
|
|
// //替换老榜
|
|
// rankDataOne.LastRecord = record;
|
|
// //rankDataOne.LastRecord.RankDict.Clear();
|
|
|
|
// rankDataOne.CurRecordMinScore = 0; //设置成0
|
|
// rankDataOne.NeedRankPlayers.Clear();
|
|
|
|
|
|
// //new 新榜
|
|
// rankDataOne.CurRecord = new WorldRankDataRecord();
|
|
// rankDataOne.CurRecord.RankId = rankDesc.rankId;
|
|
// rankDataOne.CurRecord.BeginTime = newBeginTime;
|
|
// rankDataOne.CurRecord.Data = new DBRankData();
|
|
// rankDataOne.CurRecord.Data.RankId = rankDesc.rankId;
|
|
// //不清空老榜,直接复制数据,todo 加上清理的规则
|
|
// if (rankDesc.clearWhenRefresh == 0)
|
|
// {
|
|
// TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} clearWhenRefresh is 0, so copy old rank list"
|
|
// , record.RankId, record.BeginTime);
|
|
// for (int i = 0; i < record.Data.RankList.Count; i++)
|
|
// {
|
|
// rankDataOne.CurRecord.Data.RankList.Add(record.Data.RankList[i]);
|
|
|
|
// }
|
|
|
|
// for(int i =0;i< rankDataOne.CurRecord.Data.RankList.Count;i++)
|
|
// {
|
|
// rankDataOne.CurRecord.RankDict.Add(rankDataOne.CurRecord.Data.RankList[i].Uid, rankDataOne.CurRecord.Data.RankList[i]);
|
|
// }
|
|
// }
|
|
|
|
|
|
// rankDataOne.CurRecord.MakeDirty();
|
|
|
|
// //发奖
|
|
// var awardDesc = RankAwardDescMgr.Instance.GetGroup(rankDesc.rankId);
|
|
// if (awardDesc == null)
|
|
// {
|
|
// TraceLog.Trace("TickRefreshRankRecord rankId {0} no award config", record.RankId);
|
|
// return;
|
|
// }
|
|
|
|
// int awardPlayerCount = 0;
|
|
|
|
// foreach (var oneAward in awardDesc)
|
|
// {
|
|
// //遍历发邮件
|
|
// for (int i = oneAward.rankPosMin; i <= oneAward.rankPosMax; i++)
|
|
// {
|
|
// if (record.Data.RankList.Count < i || i <= 0)
|
|
// {
|
|
// continue;
|
|
// }
|
|
|
|
// DBRankPlayerInfo playerInfo = record.Data.RankList[i - 1];
|
|
|
|
// SendAwardMailToRankPlayer(playerInfo, oneAward, i);
|
|
|
|
// awardPlayerCount++;
|
|
// }
|
|
// }
|
|
|
|
// TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} send award success, award player count {2}"
|
|
// , record.RankId, record.BeginTime, awardPlayerCount);
|
|
|
|
//}
|
|
|
|
private static void AddOneItemToMail(DBMail mail, string itemid, int count)
|
|
{
|
|
TypeIDValueString item = new TypeIDValueString();
|
|
item.Type = (int) GoodsType.Items;
|
|
item.Id = new FixedStructString64(itemid);
|
|
item.Value = count;
|
|
|
|
mail.AddGoods.Add(item);
|
|
}
|
|
/*
|
|
private static void SendAwardMailToRankPlayer(DBRankPlayerInfo playerInfo, RankAwardDesc oneAward, int rankPos)
|
|
{
|
|
//给玩家发邮件,就是发奖品
|
|
DBMail mail = new DBMail();
|
|
mail.MailType = (int)MailType.Rank;
|
|
mail.Uid = playerInfo.Uid;
|
|
|
|
//var currency = new IDValue64() { Id = (long)CurrencyType.Chip, Value = oneAward.chip };
|
|
//mail.AddCurrency.Add(ref currency);
|
|
//currency = new IDValue64() { Id = (long)CurrencyType.Diamond, Value = oneAward.diamond };
|
|
//mail.AddCurrency.Add(ref currency);
|
|
|
|
//if (oneAward.itemid > 0 && oneAward.itemcount > 0)
|
|
// {
|
|
// AddOneItemToMail(mail, (uint)oneAward.itemid, oneAward.itemcount);
|
|
// }
|
|
// if (oneAward.itemid2 > 0 && oneAward.itemcount2 > 0)
|
|
// {
|
|
// AddOneItemToMail(mail, (uint)oneAward.itemid2, oneAward.itemcount2);
|
|
// }
|
|
|
|
//时间提前设置上,客户端可根据时间显示内容
|
|
mail.SendTime = WorldServerUtils.GetTimeSecond();
|
|
mail.Param1 = oneAward.rankId;//排行榜id
|
|
mail.Param2 = rankPos;//第几名
|
|
|
|
MailSvc.SendMail(mail);
|
|
|
|
TraceLog.Debug("RankSvc.SendAwardMailToRankPlayer send award mail to uid {0} rankId {1} rankPos {2}"
|
|
, playerInfo.Uid, oneAward.rankId, rankPos);
|
|
}*/
|
|
|
|
private static void TickUpdateRank(long nowSecond)
|
|
{
|
|
//1分钟一次
|
|
if (nowSecond - m_lastUpdateRankTime < 300)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_lastUpdateRankTime = nowSecond;
|
|
|
|
|
|
WorldRankData rankData = WorldServerUtils.GetWorldRankData();
|
|
|
|
foreach (var rankItem in rankData.AllRank.Values)
|
|
{
|
|
if (rankItem.CurRecord != null)
|
|
{
|
|
TickUpdateRank(rankItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void TickUpdateRank(WorldRankDataOne rankOne)
|
|
{
|
|
if (rankOne.CurRecord == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (rankOne.NeedRankPlayers.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int rankId = rankOne.CurRecord.RankId;
|
|
RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId);
|
|
if (rankDesc == null)
|
|
{
|
|
TraceLog.Error("RankSvc.TickUpdateRank rankId {0} not config desc", rankId);
|
|
return;
|
|
}
|
|
|
|
//for (int i = 0; i < rankOne.CurRecord.Data.RankList.Count; i++)
|
|
//{
|
|
// if (rankOne.NeedRankPlayers.ContainsKey(rankOne.CurRecord.Data.RankList[i].Uid) == false)
|
|
// {
|
|
// rankOne.NeedRankPlayers.Add(rankOne.CurRecord.Data.RankList[i].Uid, rankOne.CurRecord.Data.RankList[i]);
|
|
// }
|
|
//}
|
|
|
|
//降序排序
|
|
IEnumerable<DBRankPlayerInfo> query = from items in rankOne.NeedRankPlayers.Values orderby items.Score descending select items;
|
|
|
|
//清空老数据
|
|
//rankOne.CurRecord.Data.RankList.Clear();
|
|
rankOne.CurRecord.RankDict.Clear();
|
|
|
|
int iCount = 0;
|
|
long minScore = 0;
|
|
foreach (var player in query)
|
|
{
|
|
//分数为0不排
|
|
if (player.Score > 0)
|
|
{
|
|
//rankOne.CurRecord.Data.RankList.Add(player);
|
|
rankOne.CurRecord.RankDict.Add(player.Uid, player);
|
|
|
|
iCount++;
|
|
|
|
minScore = player.Score;
|
|
}
|
|
}
|
|
//清空
|
|
rankOne.NeedRankPlayers.Clear();
|
|
|
|
|
|
rankOne.CurRecordMinScore = minScore;
|
|
|
|
rankOne.CurRecord.MakeDirty();
|
|
|
|
rankOne.CurRecord.RankDataVersion++;
|
|
|
|
TraceLog.Debug("RankSvc.TickUpdateRank sort new rank list rankId {0} count {1} minScore {2}"
|
|
, rankId, iCount, minScore);
|
|
}
|
|
|
|
//玩家数据保存的时候更新排行榜
|
|
public static void OnPlayerDataSaveReq(DBRoleBase roleBase, DBRoleData roleData)
|
|
{
|
|
/*//数据没加载成功不处理
|
|
if (RankUtils.IsLoadRankDataFromDbSuccess() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
WorldRankData rankData = WorldServerUtils.GetWorldRankData();
|
|
|
|
foreach (var rankItem in rankData.AllRank.Values)
|
|
{
|
|
if (rankItem.CurRecord != null)
|
|
{
|
|
int rankId = rankItem.CurRecord.RankId;
|
|
RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId);
|
|
if (rankDesc == null)
|
|
{
|
|
TraceLog.Error("RankSvc.OnPlayerDataSaveReq rankId {0} not config desc", rankId);
|
|
continue;
|
|
}
|
|
|
|
long playerScore = 0;
|
|
//赢取筹码
|
|
if (rankDesc.rankScoreType == 1)
|
|
{
|
|
playerScore = roleData.StatData.Weekly.WinChip;
|
|
}
|
|
else if (rankDesc.rankScoreType == 2)
|
|
{
|
|
//playerScore = roleData.StatData.Weekly.MatchArch;
|
|
}
|
|
else if (rankDesc.rankScoreType == 3)
|
|
{
|
|
playerScore = roleBase.Chip;
|
|
}
|
|
else if (rankDesc.rankScoreType == 4)
|
|
{
|
|
playerScore = roleData.StatData.Weekly.ReceiveFriendGift;
|
|
}
|
|
|
|
//先更新已经在排行榜里的玩家信息
|
|
//财富榜强制更新,因为分数会变小
|
|
if (playerScore >= rankItem.CurRecordMinScore || rankDesc.rankScoreType == 3)
|
|
{
|
|
//UpdateRolebaseInRankList(rankItem.CurRecord, roleBase, playerScore);
|
|
}
|
|
|
|
//有可能新进排行榜的,重复了也不管,直接加
|
|
//分数大于最低或者排行榜未满的时候有分
|
|
//不管如何,都排一下序算了,金钱榜的金钱会减少,不这么做有点问题
|
|
//if (playerScore > rankItem.CurRecordMinScore
|
|
// || (playerScore > 0 && rankItem.CurRecord.Data.RankList.Count < rankDesc.listCount)
|
|
// || (playerScore > 0 && rankDesc.rankScoreType == 3))
|
|
{
|
|
AddPlayerToNeedRank(rankItem, roleBase, roleData, playerScore);
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
|
|
|
|
private static void AddPlayerToNeedRank(WorldRankDataOne oneRank, DBRoleBase roleBase, DBRoleData roleData, long score)
|
|
{
|
|
TraceLog.Trace("RankSvc.AddPlayerToNeedRank uid {0} rankId {1} score {2}", roleBase.Uid, oneRank.CurRecord.RankId, score);
|
|
|
|
/*DBRankPlayerInfo rankPlayer;
|
|
|
|
if (oneRank.NeedRankPlayers.ContainsKey(roleBase.Uid))
|
|
{
|
|
rankPlayer = oneRank.NeedRankPlayers[roleBase.Uid];
|
|
}
|
|
else
|
|
{
|
|
rankPlayer = new DBRankPlayerInfo();
|
|
oneRank.NeedRankPlayers.Add(roleBase.Uid, rankPlayer);
|
|
}
|
|
|
|
|
|
//更新数据
|
|
rankPlayer.Uid = roleBase.Uid;
|
|
rankPlayer.Score = score;
|
|
rankPlayer.Nick = roleBase.Nick;
|
|
rankPlayer.Icon = roleBase.Icon;
|
|
rankPlayer.Level = roleBase.Level;
|
|
rankPlayer.Chip = roleBase.Chip;
|
|
rankPlayer.Diamond = (int)roleBase.Diamond;
|
|
|
|
rankPlayer.VipLevel = roleBase.VipLevel;
|
|
rankPlayer.Gender = roleBase.Gender;
|
|
rankPlayer.GameRound = (int)RankUtils.GetRoleTotalStatData(roleData, (int)CSRoleStatisticsID.TotalRound);
|
|
rankPlayer.WinRound = (int)RankUtils.GetRoleTotalStatData(roleData, (int)CSRoleStatisticsID.TotalWin);*/
|
|
|
|
|
|
|
|
}
|
|
|
|
//更新昵称和头像等信息
|
|
public static void UpdateRolebaseInAllRankList(DBRoleBase roleBase)
|
|
{
|
|
//数据没加载成功不处理
|
|
if (RankUtils.IsLoadRankDataFromDbSuccess() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
WorldRankData rankData = WorldServerUtils.GetWorldRankData();
|
|
|
|
foreach (var rankItem in rankData.AllRank.Values)
|
|
{
|
|
if (rankItem.CurRecord != null)
|
|
{
|
|
if (rankItem.CurRecord.RankDict.ContainsKey(roleBase.Uid))
|
|
{
|
|
DBRankPlayerInfo rankPlayer = rankItem.CurRecord.RankDict[roleBase.Uid];
|
|
|
|
|
|
rankPlayer.Level = roleBase.Level;
|
|
rankPlayer.Nick = roleBase.Nick;
|
|
rankPlayer.Icon = roleBase.Icon;
|
|
|
|
TraceLog.Trace("UpdateRolebaseInRankList uid {0}", roleBase.Uid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//更新昵称和头像等信息
|
|
public static void UpdateRolebaseInRankList(WorldRankDataRecord record, DBRoleBase roleBase, long score)
|
|
{
|
|
if (record != null && record.RankDict.ContainsKey(roleBase.Uid))
|
|
{
|
|
DBRankPlayerInfo rankPlayer = record.RankDict[roleBase.Uid];
|
|
|
|
|
|
rankPlayer.Level = roleBase.Level;
|
|
rankPlayer.Nick = roleBase.Nick;
|
|
rankPlayer.Icon = roleBase.Icon;
|
|
rankPlayer.Score = score;
|
|
|
|
TraceLog.Trace("UpdateRolebaseInRankList uid {0}", roleBase.Uid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|