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.
 
 
 
 
 
 

1870 lines
77 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Sog;
using ProtoCSStruct;
using System.Security.Cryptography;
using System.IO;
using System.Reflection;
using Sog.Log;
using Org.BouncyCastle.Bcpg;
namespace Rank
{
public static class RankSvc
{
private static long lastTickTime = 0;
private static readonly int HideRankTimeGap = 3 * 86400;
// 延迟发送排名奖励的时间
private static readonly int DelaySendRankRewardTime = 3600;
public static int GMRewardRankId = 0;
public static int GMRewardTime = 0;
public static void OnTick(long nowSecond)
{
TickLoadRankFromDb(nowSecond);
TickRefreshRank(nowSecond);
//更新排行榜里的玩家排名,有新的玩家数据的时候
TickUpdateRank(nowSecond);
// if (nowSecond >= lastTickTime + 60)
// {
// lastTickTime = nowSecond;
// TickActivityRank(nowSecond);
// }
TickSaveRankData(nowSecond);
TickClearActRankData(nowSecond);
}
public static void On10secondTick(long nowSecond)
{
TickSaveActRankData(nowSecond);
}
public static bool CheckCanStop()
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realIdItem in rankData.AllRank.Values)
{
if (!realIdItem.m_loadDbDataSuccess)
{
continue;
}
foreach (var rankItem in realIdItem.m_rankMap.Values)
{
if (rankItem.CurRecord != null)
{
if (rankItem.CurRecord.IsDirty() || rankItem.CurRecord.NeedUpdate)
{
TraceLog.Debug("RankSvc.CheckCanStop realm {0} rank {1} dirty {2}", rankItem.RealmId, rankItem.RankID, rankItem.CurRecord.NeedUpdate);
return false;
}
}
}
}
return true;
}
private static void TickRefreshRank(long nowSecond)
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realIdItem in rankData.AllRank.Values)
{
foreach (var rankItem in realIdItem.m_rankMap.Values)
{
if (rankItem.CurRecord != null)
{
TickRefreshCurRankRecord(nowSecond, rankItem);
}
}
}
}
private static void TickRefreshCurRankRecord(long nowSecond, RankDataOne rankDataOne)
{
RankDataRecord record = rankDataOne.CurRecord;
var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId);
if (rankDesc == null || rankDesc.refreshType == 0)
{
return;
}
long newBeginTime = 0;
//不刷新
switch ((RankFlushType)rankDesc.refreshType)
{
case RankFlushType.None:
return;
case RankFlushType.Seconds:
//if(nowSecond - record.BeginTime < rankDesc.refreshTypeNum)
//{
// return;
//}
//newBeginTime = nowSecond;
return;
case RankFlushType.Daily:
if (AppTime.IsSameDay(nowSecond, record.BeginTime))
{
return;
}
newBeginTime = AppTime.GetTodayStartTime(nowSecond);
break;
case RankFlushType.Weekly:
if (AppTime.IsSameWeek127(nowSecond, record.BeginTime))
{
return;
}
newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond);
break;
}
if (record.AwardTime != 0)
{
TraceLog.Error("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} already award at time {2}"
, record.RankId, record.BeginTime, record.AwardTime);
return;
}
TraceLog.Debug("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}"
, record.RankId, record.BeginTime, record.AwardTime);
//更新当前榜单
TickUpdateRank(rankDataOne);
//发放奖励
SendRankAwardMail(rankDataOne);
//重置榜单
ReplaceOnRefreshRankRecord(rankDataOne, newBeginTime);
}
//手动清空排行榜
public static void ClearRank(int rankID, int realmID)
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realIdItem in rankData.AllRank.Values)
{
foreach (var rankItem in realIdItem.m_rankMap.Values)
{
if (rankItem.RankID == rankID && rankItem.RealmId == realmID)
{
RankDataRecord record = rankItem.CurRecord;
var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId);
if (rankDesc == null)
{
return;
}
long nowSecond = RankServerUtils.GetApp().GetTimeSecond();
long newBeginTime = 0;
switch ((RankFlushType)rankDesc.refreshType)
{
case RankFlushType.Seconds:
newBeginTime = nowSecond;
break;
case RankFlushType.Daily:
newBeginTime = AppTime.GetTodayStartTime(nowSecond);
break;
case RankFlushType.Weekly:
newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond);
break;
}
TraceLog.Debug("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}"
, record.RankId, record.BeginTime, record.AwardTime);
//更新当前榜单
TickUpdateRank(rankItem);
ReplaceOnRefreshRankRecord(rankItem, newBeginTime);
}
}
}
}
//新老榜替换
public static void ReplaceOnRefreshRankRecord(RankDataOne rankDataOne, long newBeginTime)
{
rankDataOne.CurRecord.BeginTime = newBeginTime;
if (rankDataOne.FlushType == RankFlushType.Seconds)
{
return;
}
rankDataOne.CurRecord.lastRankAwardTime = 0;
rankDataOne.CurRecord.rewardGetUids.Clear();
rankDataOne.CurRecord.lastRankData.Clear();
rankDataOne.CurRecordLimitScore = 0;
//填充进旧榜,并回收
foreach (var it in rankDataOne.data.m_curRecordIDMap)
{
ref DBRankOnePlayerStruct one = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(it.Value);
if (one.data.Uid == it.Key)
{
rankDataOne.CurRecord.lastRankData.Add(one.data);
}
rankDataOne.data.m_cacheCurRecord.Free(it.Value);
}
if (rankDataOne.data.m_cacheCurRecord.GetUsedCount() > 1)
{
TraceLog.Error("RankSvc.ReplaceOnRefreshRankRecord rank {0} m_cacheCurRecord free error", rankDataOne.RankID);
}
//回收needRank
foreach (var it in rankDataOne.data.m_needRankIDMap)
{
rankDataOne.data.m_cacheNeedRankData.Free(it.Value);
}
if (rankDataOne.data.m_cacheNeedRankData.GetUsedCount() > 1)
{
TraceLog.Error("RankSvc.ReplaceOnRefreshRankRecord rank {0} m_cacheNeedRankData free error", rankDataOne.RankID);
}
rankDataOne.data.m_curRecordIDMap.Clear();
rankDataOne.data.m_needRankIDMap.Clear();
rankDataOne.CurRecord.AwardTime = 0;
rankDataOne.CurRecord.Data.Clear();
rankDataOne.CurRecord.NeedUpdate = true;
rankDataOne.CurRecord.MakeDirty();
NoticeRankChange(rankDataOne);
}
public static void SendRankAwardMail(RankDataOne rankOne)
{
int rankId = rankOne.RankID;
var record = rankOne.CurRecord;
var rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId);
if (rankDesc == null)
{
return;
}
TraceLog.Debug("RankSvc.SendRankAwardMail rankId {0}", record.RankId);
int count = 0;
int rank = 1;
while (true)
{
if (rank <= record.Data.Count)
{
long uid = record.Data[rank - 1];
TraceLog.Debug("RankSvc.SendRankAwardMail {0} - uid {1} rank", rank, uid);
SendAwardMailToRankPlayer(uid, rank, rankDesc);
++count;
if(rank <= 100 && rankDesc.rankId == 2)
{
ref DBRankOnePlayerStruct p = ref rankOne.data.m_cacheCurRecord.GetByIndex(rankOne.data.m_curRecordIDMap[uid]);
LogContinueBattleRank(uid, rank, (int)p.data.Score, 0, GetRankAward(rank, rankDesc));
}else if (rank <= 100 && rankDesc.rankId == 3)
{
ref DBRankOnePlayerStruct p = ref rankOne.data.m_cacheCurRecord.GetByIndex(rankOne.data.m_curRecordIDMap[uid]);
LogContinueBattleRank(uid, rank, 0, (int)p.data.Score, GetRankAward(rank, rankDesc));
}
}
else
{ //排行榜上的玩家发送完奖励
break;
}
++rank;
}
TraceLog.Debug("RankSvc.SendRankAwardMail succ, rankId {0} award count {1}", record.RankId, count);
}
public static void SendAwardMailToRankPlayer(long uid, int rankPos, RankConfigDesc rankDesc)
{
string reward = GetRankAward(rankPos, rankDesc);
TraceLog.Trace("RankSvc.SendAwardMailToRankPlayer uid {0} rankId {1} pos {2}, reward={3}", uid, rankDesc.rankId, rankPos, reward);
MailSender.SendNewMailToPlayer(uid, rankDesc.mail, reward, rankPos);
}
public static string GetRankAward(int rank, RankConfigDesc rankDesc)
{
List<TypeIDValue32> rewards = new List<TypeIDValue32>();
foreach (var item in RankAwardDescMgr.Instance.GetGroup(rankDesc.rankAward))
{
if (rank >= item.Value.minRank && rank <= item.Value.maxRank)
{
return item.Value.reward;
}
}
return "";
}
private static void TickUpdateRank(long nowSecond)
{
WorldRankData rankData = RankServerUtils.GetRankData();
//1分钟一次,停服时5s一次
int updateRankCd = 5;
if (RankServerUtils.GetApp().IsStopping)
{
updateRankCd = 5;
}
foreach (var realmIdItem in rankData.AllRank.Values)
{
if (realmIdItem.m_loadDbDataSuccess == false)
{
continue;
}
if (nowSecond < realmIdItem.m_lastUpdateRankTime + updateRankCd)
{
return;
}
realmIdItem.m_lastUpdateRankTime = nowSecond;
foreach (var rankItem in realmIdItem.m_rankMap.Values)
{
if (rankItem.CurRecord != null)
{
TickUpdateRank(rankItem);
}
}
}
foreach (var realmIdItem in rankData.GlobalRank.Values)
{
if (realmIdItem.m_loadDbDataSuccess == false)
{
continue;
}
if (nowSecond < realmIdItem.m_lastUpdateRankTime + updateRankCd)
{
return;
}
realmIdItem.m_lastUpdateRankTime = nowSecond;
var rankItem = realmIdItem.rankOne;
{
if (rankItem.CurRecord != null)
{
TickUpdateRank(rankItem);
}
}
}
}
public static void LoadRankDataFromDb(int realmId)
{
SSQueryRankDbReq req = new SSQueryRankDbReq();
TraceLog.Trace("RankSvc.LoadRankDataFromDb begin realmId num:{0}", realmId);
SortedList<int, RankConfigDesc> list = RankConfigDescMgr.Instance.ItemTable;
uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1);
req.RealmId = realmId;
req.GroupId = 0;
req.BeginTime = 0; //存取库Req.BeginTime全部统一用0
for (int i = 0; i < list.Values.Count; i++)
{
RankConfigDesc desc = list.Values[i];
if (desc.type != RankType.Single) continue;//跨服榜单独拉取
req.RankId = desc.rankId;
RankServerUtils.GetPacketSender().SendToServerByID(dbServerID,
(int)SSGameMsgID.QueryRankDbReq, ref req, 0);
}
}
public static void LoadGlobalRankFromDB(WorldRankData rankData, long nowSecond)
{
SSQueryRankDbReq req = new SSQueryRankDbReq();
SortedList<int, RankConfigDesc> list = RankConfigDescMgr.Instance.ItemTable;
uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1);
req.RealmId = 0;
req.GroupId = 0;
req.BeginTime = 0; //存取库Req.BeginTime全部统一用0
for (int i = 0; i < list.Values.Count; i++)
{
RankConfigDesc desc = list.Values[i];
if (desc.type != RankType.All) continue;//跨服榜单独拉取
if (!rankData.GlobalRank.TryGetValue(desc.rankId, out var rankone))
{
rankone = new GlobalRankInfo();
rankData.GlobalRank[desc.rankId] = rankone;
}
if (rankone.m_loadDbDataSuccess)
{
continue;
}
if (rankone.m_serverStartTime == 0)
{
rankone.m_serverStartTime = nowSecond;
}
if (nowSecond - rankone.m_serverStartTime > 5 && nowSecond - rankone.m_lastLoadDbReqTime > 30)
{
rankone.m_lastLoadDbReqTime = nowSecond;
req.RankId = desc.rankId;
RankServerUtils.GetPacketSender().SendToServerByID(dbServerID,
(int)SSGameMsgID.QueryRankDbReq, ref req, 0);
TraceLog.Trace("RankSvc.LoadGlobalRankFromDB begin {0}", req.RankId);
}
}
}
//5秒后开始加载数据库,如果失败30秒后再次尝试
public static void TickLoadRankFromDb(long nowSecond)
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realmItem in rankData.AllRank.Values)
{
if (realmItem.m_loadDbDataSuccess)
{
continue;
}
if (realmItem.m_serverStartTime == 0)
{
realmItem.m_serverStartTime = nowSecond;
}
if (nowSecond - realmItem.m_serverStartTime > 5 && nowSecond - realmItem.m_lastLoadDbReqTime > 30)
{
realmItem.m_lastLoadDbReqTime = nowSecond;
LoadRankDataFromDb(realmItem.m_realmId);
}
}
LoadGlobalRankFromDB(rankData, nowSecond);
}
public static void OnSaveRankDbRes(uint remoteAppID, StructPacket packet)
{
ref SSSaveRankDbRes res = ref packet.GetMessage<SSSaveRankDbRes>();
if (res.Ret == 0)
{
if (res.BeginTime == 0)
{
bool setSaveSeq = false;
WorldRankData rankData = RankServerUtils.GetRankData();
if (rankData.TryGetRankDataOne(out var rankOne, res.RealmId, res.RankId))
{
if (rankOne.CurRecord != null)
{
setSaveSeq = true;
rankOne.CurRecord.SavedSuccessSeq = res.DataSeq;
TraceLog.Trace("RankSvc.OnSaveRankDbRes CurRecord rankId {0} {1} {2}", res.RankId, res.RealmId, res.DataSeq);
}
}
if (!setSaveSeq)
{
TraceLog.Error("RankSvc.OnSaveRankDbRes CurRecord rankId {0} {1} not setSaveSeq", res.RankId, res.RealmId);
}
}
else
{
TraceLog.Trace("RankSvc.OnSaveRankDbRes rankId {0} {1} {2} save success", res.RankId, res.RealmId, res.BeginTime);
}
}
else
{
TraceLog.Error("RankSvc.OnSaveRankDbRes rankId {0} {1} {2} save fail", res.RankId, res.RealmId, res.BeginTime);
}
}
public static void OnQueryRankDbRes(uint remoteAppID, StructPacket packet)
{
ref SSQueryRankDbRes res = ref packet.GetMessage<SSQueryRankDbRes>();
RankDataOne oneRank = null;
var rankDesc = RankConfigDescMgr.Instance.GetConfig(res.RankId);
if(rankDesc.type == RankType.Single)
{
oneRank = RankUtils.GetCreateWorldRankDataOne(res.RealmId, res.RankId);
if (oneRank == null)
{
TraceLog.Error("RankSvc.OnQueryRankDbRes realm {0} rankid {1} not get RankDataOne", res.RealmId, res.RankId);
return;
}
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(res.RealmId);
if (realmRankInfo != null && realmRankInfo.m_loadDbDataSuccess)
{
TraceLog.Debug("RankSvc.OnQueryRankDbRes realm {0} rankId {1} already load, skip", res.RealmId, res.RankId);
return;
}
}
else
{
oneRank = RankUtils.GetCreateGlobalRank(res.RankId);
}
if (oneRank.CurRecord != null)
{
TraceLog.Error("RankSvc.OnQueryRankDbRes rankId {0} already load curRank from db, skip", res.RankId);
return;
}
if (res.BeginTime != 0)
{
TraceLog.Error("RankSvc.OnQueryRankDbRes rankId {0} only load beginTime zero data {1}", res.RankId, res.BeginTime);
return;
}
oneRank.CurRecord = new RankDataRecord(res.RankId);
InitRankData(oneRank, ref res.Data);
if (rankDesc.type == RankType.Single)
{
if (RankUtils.CheckLoadRankDataSuccess(res.RealmId))
{
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(res.RealmId);
realmRankInfo.m_loadDbDataSuccess = true;
}
}
else if (rankDesc.type == RankType.All)
{
WorldRankData rankData = RankServerUtils.GetRankData();
rankData.GlobalRank[res.RankId].m_loadDbDataSuccess = true;
}
TraceLog.Debug("RankSvc.OnQueryRankDbRes realmId {0} rank {1} load success", res.RealmId, res.RankId);
}
public static void InitRankData(RankDataOne rankData, ref DBRankData data)
{
rankData.closeRankTime = data.CloseRankTime;
rankData.hideRankTime = data.HideRankTime;
ref RankDataInfoCache cacheInfo = ref rankData.data;
if (rankData.CurRecord.Data.Count != 0)
{
TraceLog.Error("RankSvc.InitRankData had InitCurRankData");
return;
}
rankData.CurRecord.BeginTime = data.BeginTime;
rankData.CurRecord.AwardTime = data.AwardTime;
for (int i = 0; i < data.RankList.Count; i++)
{
ref DBRankOnePlayerStruct one = ref cacheInfo.m_cacheCurRecord.Malloc();
if (!one.IsNull())
{
int index = one.GetObjectID();
one.data.CopyFrom(ref data.RankList[i]);
cacheInfo.m_curRecordIDMap.Add(data.RankList[i].Uid, index); //Uid index map
rankData.CurRecord.Data.Add(data.RankList[i].Uid);
}
}
for (int i = 0; i < data.LastRankData.LastRankList.Count; ++i)
{
rankData.CurRecord.lastRankData.Add(data.LastRankData.LastRankList[i]);
}
for (int i = 0; i < data.LastRankData.RewardGetUids.Count; ++i)
{
rankData.CurRecord.rewardGetUids.Add(data.LastRankData.RewardGetUids[i]);
}
if (rankData.SaveObjMax > 0 && rankData.SaveObjMax <= data.RankList.Count)
{
rankData.CurRecordLimitScore = data.RankList[rankData.SaveObjMax - 1].Score;
}
else
{
rankData.CurRecordLimitScore = 0;
}
//把已上榜的放到待排序队列中
AddCur2Need(ref rankData);
}
public static void ForceUpdateAllRank(int realmId = 0, int rankId = 0, bool skipCheck = false)
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realmIdPair in rankData.AllRank)
{
if (realmId == 0 || realmIdPair.Key == realmId)
{
foreach (var rankPair in realmIdPair.Value.m_rankMap)
{
if (rankId == 0 || rankPair.Key == rankId)
{
if (rankPair.Value.CurRecord != null)
{
TickUpdateRank(rankPair.Value, skipCheck);
}
}
}
}
}
}
public static string GetRankActSaveDbFileName()
{
return "./RankActDb_" + RankServerUtils.GetApp().ServerID.ToString() + ".fdb";
}
public static void SaveRankData()
{
var allplayerInfo = RankServerUtils.GetAllplayerInfo();
var file = GetRankActSaveDbFileName();
int haveSave = 0;
TraceLog.Trace("RankSvc.SaveRankData save file {0} begin time {1}", file, RankServerUtils.GetTimeSecond());
try
{
FileStream fileStream = File.OpenWrite(file);
//清空文件
fileStream.SetLength(0);
BinaryWriter sw = new BinaryWriter(fileStream);
foreach (var one in allplayerInfo.Values)
{
int size = one.CalculateSize();
byte[] dataByte = new byte[size];
CodedOutputStream ouput = new CodedOutputStream(dataByte);
one.WriteTo(ouput);
sw.Write(size);
sw.Write(dataByte); //写入数据
sw.Flush();
++haveSave;
}
sw.Dispose();
fileStream.Dispose();
}
catch (Exception ex)
{
TraceLog.Error("RankSvc.SaveRankData write file failed! {0}", file);
TraceLog.Exception(ex);
return;
}
TraceLog.Trace("RankSvc.SaveRankData save file {0} end time {1}", file, RankServerUtils.GetTimeSecond());
}
public static bool LoadRankFromFile()
{
var allplayerInfo = RankServerUtils.GetAllplayerInfo();
var file = GetRankActSaveDbFileName();
TraceLog.Trace("RankSvc.LoadMatchFromFile save file {0} begin time {1}", file, RankServerUtils.GetTimeSecond());
if (File.Exists(file) == false)
{
TraceLog.Trace("RankSvc.LoadMatchFromFile file not exist {0}", file);
return true;
}
try
{
FileStream fileStream = File.OpenRead(file);
BinaryReader sw = new BinaryReader(fileStream);
long lenth = fileStream.Length;
long pos = 0;
while (pos < lenth)
{
int size = sw.ReadInt32();
byte[] data = sw.ReadBytes(size); //读数据
pos += sizeof(int) + size;
if (pos <= lenth)
{
CodedInputStream input = new CodedInputStream(data);
var one = new DBActRankTopPlayerInfo();
one.ReadFrom(input);
allplayerInfo.TryAdd(one.Uid, one);
}
}
sw.Dispose();
fileStream.Dispose();
}
catch (Exception ex)
{
TraceLog.Error("RankSvc.LoadMatchFromFile parse message failed! {0}", file);
TraceLog.Exception(ex);
return false;
}
TraceLog.Trace("RankSvc.LoadMatchFromFile file {0} success time {1}", file, RankServerUtils.GetTimeSecond());
return true;
}
public static bool CheckGetAward(int mainType)
{
//return mainType == (int)RankMainType.TimeRecord;
return false;
}
public static void DealNeedForceUpdate(RankDataOne rankOne)
{
//能领奖的榜有第一名就要更新,玩家需要在第一时间能领奖
if (CheckGetAward(0/*(int)rankOne.MainType*/) && rankOne.CurRecord.Data.Count < 10)
{
//if (rankOne.LinkRank > 0)
//{
// //先更新主榜
// var mainRankdata = RankUtils.GetRankDataOne(rankOne.RealmId, rankOne.LinkRank);
// if (mainRankdata != null)
// {
// TickUpdateRank(mainRankdata);
// }
//}
TickUpdateRank(rankOne);
AddCanAwardRank(rankOne);
}
}
private static void TickUpdateRank(RankDataOne rankOne, bool skipCheck = false)
{
if (rankOne.CurRecord == null)
{
return;
}
if (rankOne.CurRecord.NeedUpdate || skipCheck)
{
rankOne.CurRecord.NeedUpdate = false;
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;
}
SortNeedRank(ref rankOne, rankDesc);
if (rankDesc.refreshType != (int)RankFlushType.Seconds)
{//按照秒刷新的排行榜不推送通知
NoticeRankChange(rankOne);
}
TraceLog.Trace("RankSvc.TickUpdateRank realmId:{0} rankId:{1}", rankOne.RealmId, rankOne.RankID);
}
}
private static void TickSaveRankData(long nowSecond)
{
long nowMs = RankServerUtils.GetTimeMs();
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realmIdItem in rankData.AllRank.Values)
{
if (realmIdItem.m_loadDbDataSuccess == false)
{
continue;
}
foreach (var rankItem in realmIdItem.m_rankMap.Values)
{
if (rankItem.CurRecord != null)
{
if (rankItem.CurRecord.CanDoSaveReqNow(nowMs))
{
SaveRankCurRecord(rankItem);
rankItem.CurRecord.OnSaveReq(nowMs);
}
}
}
}
foreach (var rankItem in rankData.GlobalRank.Values)
{
if (rankItem.rankOne == null) continue;
if (rankItem.rankOne.CurRecord != null)
{
if (rankItem.rankOne.CurRecord.CanDoSaveReqNow(nowMs))
{
SaveRankCurRecord(rankItem.rankOne);
rankItem.rankOne.CurRecord.OnSaveReq(nowMs);
}
}
}
}
private static void TickSaveActRankData(long nowSecond)
{
long nowMs = RankServerUtils.GetTimeMs();
var rankData = RankServerUtils.GetActRankData();
uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1);
foreach (var realmRank in rankData.Values)
{
foreach (var rankOne in realmRank.m_AcRank.Values)
{
if (!rankOne.IsDirty()) continue;
if (!rankOne.CanDoSaveReqNow(nowMs)) continue;
// save req
var req = new SSSaveActRankDataReq();
req.ActRankId = rankOne.ActRankID;
req.RealmId = rankOne.RealmId;
req.BeginTime = rankOne.BeginTime;
req.EndTime = rankOne.EndTime;
req.EndClear = rankOne.endClear ? 1 : 0;
req.RankData.RankId = rankOne.ActRankID;
foreach (var one in rankOne.m_rankRank)
{
if (req.RankData.RankList.Count >= req.RankData.RankList.GetMaxCount()) break;
req.RankData.RankList.Add(one.Uid);
}
req.DataSeq = rankOne.DataSeq;
rankOne.OnSaveReq(nowMs);
RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveActRankDataReq, ref req, 0);
TraceLog.Trace("RankSvc.TickSaveActRankData rankId {0} rem:{1} dataSeq {2}", rankOne.ActRankID, rankOne.RealmId, rankOne.DataSeq);
}
}
}
private static void TickClearActRankData(long nowSecond)
{
long nowMs = RankServerUtils.GetTimeMs();
var rankData = RankServerUtils.GetActRankData();
uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1);
foreach (var realmRank in rankData.Values)
{
foreach (var rankOne in realmRank.m_AcRank.Values)
{
if (rankOne.endClear) continue;
if (rankOne.EndTime > nowSecond) continue;
//结算
EndClearRank(rankOne);
}
}
}
public static void EndClearRank(ActRankOne rankOne)
{
var desc = ActivityDescMgr.Instance.GetConfig(rankOne.ActRankID);
if (desc == null)
{
TraceLog.Error("RankSvc.EndClearRank get PandoraActivity is null! id:{0}", rankOne.ActRankID);
return;
}
for (var i = 0; i < rankOne.m_rankRank.Count; i++)
{
var rank = i + 1;
SendActRankAwardMailPlayer(rankOne.m_rankRank[i].Uid, rank, rankOne.ActRankID, rankOne.RealmId, desc);
}
TraceLog.Trace("RankSvc.EndClearRank rank actRank:{0} rem:{1}", rankOne.ActRankID, rankOne.RealmId);
rankOne.endClear = true;
rankOne.MakeDirty();
}
public static void SendActRankAwardMailPlayer(long uid, int rankPos, int ActRankID, int rem, ActivityDesc desc)
{
;
var descMail=MailDescMgr.Instance.GetConfig(desc.mailId);
DBMail mail = new DBMail();
mail.Uid = uid;
mail.MailConfId = desc.mailId;
mail.MailType = (int)MailType.ActRank;
//mail.Title.SetString(descMail.title);
//mail.Content.SetString(descMail.content);
//mail.SenderName.SetString(descMail.name);
mail.Param1 = rankPos;
var rankReward = GetActRankReward(rankPos);
for (int i = 0; i < rankReward.Count; i++)
{
mail.AddGoods.Add(rankReward[i]);
}
TraceLog.TraceDetail("RankSvc.SendAwardMailToRankPlayer uid {0} rankId {1} rem:{2}: mailInfo:{3}", uid, ActRankID, rem, mail);
MailSender.SendNewMailToPlayer(mail.Uid, ref mail);
}
private static List<TypeIDValueString> GetActRankReward(int rank)
{
var list = new List<TypeIDValueString>();
NewSeverRankAwardDesc rankDesc = null;
foreach (var desc in NewSeverRankAwardDescMgr.Instance.ItemTable.Values)
{
if (desc.minRank <= rank && desc.maxRank >= rank)
{
rankDesc = desc;
break;
}
}
if (rankDesc == null) return list;
for (var i = 0; i < rankDesc.rewards.Length; i++)
{
if (!string.IsNullOrEmpty(rankDesc.rewards[i].id) ) continue;
list.Add(new TypeIDValueString()
{
Type = rankDesc.rewards[i].type,
Id = new FixedStructString64(rankDesc.rewards[i].id),
Value = rankDesc.rewards[i].value,
});
}
return list;
}
private static void SaveRankCurRecord(RankDataOne rankOne)
{
RankDataRecord record = rankOne.CurRecord;
TraceLog.Trace("RankSvc.SaveRankRecord rankId {0} beginTime {1} dataSeq {2}", record.RankId, record.BeginTime, record.DataSeq);
SSSaveRankDbReq req = new SSSaveRankDbReq();
req.RankId = record.RankId;
req.RealmId = rankOne.RealmId;
req.BeginTime = 0; //存取库Req.BeginTime全部统一用0
req.GroupId = 0;
req.Data.RankId = record.RankId;
req.Data.AwardTime = record.AwardTime;
req.Data.HideRankTime = rankOne.hideRankTime;
req.Data.CloseRankTime = rankOne.closeRankTime;
req.Data.BeginTime = record.BeginTime;
req.DataSeq = record.DataSeq;
foreach (var uid in record.Data)
{
long index;
if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out index))
{
if (req.Data.RankList.GetCount() < req.Data.RankList.GetMaxCount()
&& req.Data.RankList.GetCount() < rankOne.SaveObjMax)
{
ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index);
req.Data.RankList.Add(ref one.data);
}
}
}
int dataCount = rankOne.CurRecord.lastRankData.Count;
if (dataCount > req.Data.LastRankData.LastRankList.GetMaxCount())
{
TraceLog.Error("RankSvc.SaveRankRecord rankId {0} LastRankList error count {1}", rankOne.RankID, dataCount);
dataCount = req.Data.LastRankData.LastRankList.GetMaxCount();
}
req.Data.LastRankData.AwardTime = rankOne.CurRecord.lastRankAwardTime;
for (int i = 0; i < dataCount; ++i)
{
req.Data.LastRankData.LastRankList.Add(rankOne.CurRecord.lastRankData[i]);
}
dataCount = rankOne.CurRecord.rewardGetUids.Count;
if (dataCount > req.Data.LastRankData.RewardGetUids.GetMaxCount())
{
TraceLog.Error("RankSvc.SaveRankRecord rankId {0} RewardGetUids error count {1}", rankOne.RankID, dataCount);
dataCount = req.Data.LastRankData.RewardGetUids.GetMaxCount();
}
for (int i = 0; i < dataCount; ++i)
{
req.Data.LastRankData.RewardGetUids.Add(rankOne.CurRecord.rewardGetUids[i]);
}
uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1);
RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveRankDbReq, ref req, 0);
}
public static void AddCur2Need(ref RankDataOne rankOne)
{
long index;
foreach (var uid in rankOne.CurRecord.Data)
{
if (rankOne.data.m_needRankIDMap.ContainsKey(uid) == false)
{
if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out index))
{
ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index);
if (one.data.Uid == uid)
{
ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.Malloc();
if (need.IsNull())
{
TraceLog.Error("RankSvc.AddCur2Need !!!!!!!! cache isfull");
return;
}
need.data.CopyFrom(ref one.data);
rankOne.data.m_needRankIDMap.Add(uid, need.GetObjectID());
}
else
{
TraceLog.Error("RankSvc.AddCur2Need item_Value:{0} != one_data_Uid:{1}", uid, one.data.Uid);
}
}
}
}
}
public static void SortNeedRank(ref RankDataOne rankOne, RankConfigDesc rankDesc)
{
WorldRankData rankData = RankServerUtils.GetRankData();
List<RankBriefDataOne> rankSortList = new List<RankBriefDataOne>();
bool sortByLess = rankDesc.sortByLess == 1;
bool sortByLess2 = rankDesc.sortByLess1 == 1;
foreach (var item in rankOne.data.m_needRankIDMap)
{
if (rankData.m_forbitUidMap.ContainsKey(item.Key))
{
continue;
}
ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.GetByIndex(item.Value);
var dataOne = new RankBriefDataOne(need.data.Uid, need.data.Rank, need.data.Rank, need.data.Score,need.data.Param, need.data.Time);
rankSortList.Add(dataOne);
}
//默认小值在前,非小值在前的话乘-1
rankSortList.Sort((a, b) => a.CompareTo(b, sortByLess, sortByLess2));
// 清空cur
foreach (long uid in rankOne.CurRecord.Data)
{
if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out long index))
{
ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index);
rankOne.data.m_cacheCurRecord.Free(ref one);
}
}
rankOne.data.m_curRecordIDMap.Clear();
rankOne.CurRecord.MakeDirty();
rankOne.CurRecordLimitScore = 0; //限制分数设为0
rankOne.CurRecord.Data.Clear();
Dictionary<long, long> newNeedRankIDMap = new Dictionary<long, long>();
// 填充cur
for (int i = 0; i < rankSortList.Count; ++i)
{
var oneData = rankSortList[i];
long uid = oneData.Uid;
int rank = rankOne.CurRecord.Data.Count + 1;
if (rankOne.data.m_needRankIDMap.TryGetValue(uid, out long index))
{
ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.GetByIndex(index);
ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.Malloc();
if (one.IsNull() || need.IsNull())
{
TraceLog.Error("RankSvc.SortNeedRank can not Malloc rankOne.data.m_cacheCurRecord {0}", rankOne.RankID);
return;
}
rankOne.data.m_curRecordIDMap.Add(uid, one.GetObjectID());
newNeedRankIDMap.Add(uid, index); //新的needRankMap
need.data.Rank = rank;
one.data.CopyFrom(ref need.data);
rankOne.CurRecord.Data.Add(need.data.Uid);
if (rank == rankOne.SaveObjMax)
{
rankOne.CurRecordLimitScore = oneData.Score;
break;
}
}
}
rankOne.CurRecord.MakeDirty();
//将不在新排行榜上的数据从needrank中清除
foreach (var item in rankOne.data.m_needRankIDMap)
{
if (newNeedRankIDMap.ContainsKey(item.Key) == false)
{
rankOne.data.m_cacheNeedRankData.Free(item.Value);
}
}
rankOne.data.m_needRankIDMap = newNeedRankIDMap;
}
public static void NoticeRankChange(RankDataOne rankOne)
{
CSNoticeRankChange notice = new CSNoticeRankChange();
notice.RealmId = rankOne.RealmId;
notice.RankId = rankOne.RankID;
//广播给所有game
RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)CSGameMsgID.NoticeRankChange, ref notice, 0, 0);
}
//添加能领奖的榜
public static void AddCanAwardRank(RankDataOne rankDataOne)
{
RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankDataOne.RankID);
//记录榜才能领奖
if (rankDesc == null)
{
return;
}
//有第一名
if (rankDataOne.CurRecord != null && rankDataOne.CurRecord.Data.Count > 0)
{
SSUpdateAwardRank notice = new SSUpdateAwardRank();
notice.RealmId = rankDataOne.RealmId;
notice.RankList.Add(rankDataOne.RankID);
//广播给所有game
RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0);
TraceLog.Trace("RankSvc.AddCanAwardRank realmId:{0} rankId:{1}", rankDataOne.RealmId, rankDataOne.RankID);
}
}
//更新能领奖的榜单
public static void UpdateCanAwardRank()
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realmIdPair in rankData.AllRank)
{
SSUpdateAwardRank notice = new SSUpdateAwardRank();
notice.RealmId = realmIdPair.Key;
notice.CleanCache = 1; //清楚缓存
foreach (var rankPair in realmIdPair.Value.m_rankMap)
{
var oneInfo = rankPair.Value;
if (oneInfo.CurRecord != null && oneInfo.CurRecord.Data.Count > 0)
{
var rankDesc = RankConfigDescMgr.Instance.GetConfig(oneInfo.RankID);
//记录榜才能领奖
if (rankDesc != null)
{
notice.RankList.Add(oneInfo.RankID);
if (notice.RankList.Count >= notice.RankList.GetMaxCount())
{
RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0);
notice.RankList.Clear();
notice.CleanCache = 0;
}
}
}
}
if (notice.RankList.Count > 0)
{
RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0);
}
}
}
public static void OnRankRealmlistRanklistRes(uint remoteAppID, StructPacket packet)
{
ref SSRankRealmlistRes res = ref packet.GetMessage<SSRankRealmlistRes>();
RankServerData serverData = RankServerUtils.GetRankServerData();
var addRank = false;
for (int i = 0; i < res.Realms.Count; i++)
{
var realm = new RealmBriefInfo(ref res.Realms[i]);
serverData.m_configRealm[realm.realmId] = realm;
if (serverData.m_RankData.AllRank.ContainsKey(realm.realmId) == false)
{
serverData.m_RankData.AllRank.Add(realm.realmId, new RealmRankInfo(realm.realmId));
addRank = true;
}
if (realm.bigRealmId > 0 && serverData.m_RankData.AllRank.ContainsKey(realm.bigRealmId) == false)
{
serverData.m_RankData.AllRank.Add(realm.bigRealmId, new RealmRankInfo(realm.bigRealmId));
addRank = true;
}
}
// ActRank.LoadActRank();
TraceLog.Trace("OnRankRealmlistRanklistRes realm count {0}", serverData.m_configRealm.Count);
}
//判断能不能上榜
public static bool CheckRankLimit(RankConfigDesc rankDesc, long values, long limitScore)
{
if (limitScore == 0)
{
return true;
}
//顺序榜小于限制值
if (rankDesc.sortByLess == 1 && values < limitScore)
{
return true;
}
//逆序榜大于限制值
else if (rankDesc.sortByLess == 0 && values > limitScore)
{
return true;
}
return false;
}
public static void OnSynRoleRankData(uint remoteAppID, StructPacket packet)
{
ref SSSynRoleRankData synData = ref packet.GetMessage<SSSynRoleRankData>();
SSAddRankDataReq addReq = new SSAddRankDataReq()
{
Uid = synData.Uid,
RealmId = synData.RealmId,
GroupId = synData.GroupId,
Level = synData.Level,
Gender = synData.Gender,
IconFrameId = synData.IconFrameId,
};
addReq.Nick.CopyFrom(ref synData.Nick);
addReq.Icon.CopyFrom(ref synData.Icon);
SSAddRankDataRes res = new SSAddRankDataRes()
{
Uid = synData.Uid,
RealmId = synData.RealmId,
GroupId = synData.GroupId,
};
for (int i = 0; i < synData.List.Count; ++i)
{
ref var oneData = ref synData.List[i];
addReq.RankId = oneData.RankID;
addReq.Score = oneData.RankScore;
res.RankId = oneData.RankID;
res.Score = oneData.RankScore;
res.Ret = (int)OnAddRankData(remoteAppID, ref addReq, ref res);
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.AddRankDataRes, ref res, packet.ObjectID);
}
}
public static void OnAddRankDataReq(uint remoteAppID, StructPacket packet)
{
ref SSAddRankDataReq req = ref packet.GetMessage<SSAddRankDataReq>();
SSAddRankDataRes res = new SSAddRankDataRes()
{
Uid = req.Uid,
RankId = req.RankId,
RealmId = req.RealmId,
GroupId = req.GroupId,
Score = req.Score,
};
res.Ret = (int)OnAddRankData(remoteAppID, ref req, ref res);
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.AddRankDataRes, ref res, packet.ObjectID);
}
public static void OnSendRankRewardReq(uint remoteAppID, StructPacket packet)
{
//ref var req = ref packet.GetMessage<SSSendRankRewardReq>();
////获取榜单
//var serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
//if (!serverData.m_RankData.TryGetRankDataOne(out RankDataOne rank, req.RealmId, req.RankId))
//{
// TraceLog.Error("RankSvc.OnSendRankRewardReq realm {0} rank {1} not exist"
// , req.RankId, req.RealmId);
// return;
//}
//rank.hideRankTime = req.HideRankTime;
//if (req.CloseRank == 1 && rank.closeRankTime == 0)
//{
// rank.closeRankTime = (int)RankServerUtils.GetTimeSecond();
//}
//if (rank.CurRecord != null && rank.CurRecord.AwardTime == 0)
//{
// // todo 这里有个风险, 如果rankData存DB失败, 同时服务器core了, 那么重启后可能会重复发奖励
// rank.CurRecord.AwardTime = RankServerUtils.GetTimeSecond();
// rank.CurRecord.NeedSave = true;
// SendRankAwardMail(rank.RankID, rank.CurRecord);
//}
}
public static CSErrCode OnAddRankData(uint remoteAppID, ref SSAddRankDataReq req, ref SSAddRankDataRes res)
{
RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(req.RankId);
//分数0,不上榜
if (rankDesc == null || req.Score == 0)
{
TraceLog.Error("RankSvc.OnAddRankData fail RankId:{0} score:{1}", req.RankId, req.Score);
return CSErrCode.SysFailure;
}
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
//排行榜黑名单
if (serverData.m_RankData.m_forbitUidMap.ContainsKey(req.Uid))
{
TraceLog.Trace("RankSvc.OnAddRankData fail forbitUid:{0} RankId:{1} score:{2}",
req.Uid, req.RankId, req.Score);
return CSErrCode.SysFailure;
}
RankDataOne rankDataOne = null;
if (rankDesc.type == RankType.Single)
{
RealmRankInfo relamInfo = RankUtils.GetRealmRankInfo(req.RealmId);
if (relamInfo == null || relamInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.OnAddRankData realmid {0} not all loaded", req.RealmId);
return CSErrCode.SysFailure;
}
if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, req.RealmId, req.RankId))
{
TraceLog.Error("RankSvc.OnAddRankData get RankData fail RankId:{0} RealmId:{1}", req.RankId, req.RealmId);
return CSErrCode.SysFailure;
}
}
else
{
rankDataOne = RankUtils.GetGlobalRank(req.RankId);
if (rankDataOne == null)
{
TraceLog.Error("RankSvc.OnAddRankData rankid {0} null", req.RankId);
return CSErrCode.SysFailure;
}
}
if (rankDataOne.CurRecord == null)
{
TraceLog.Error("RankSvc.OnAddRankData RankData currecord null RankId:{0} RealmId:{1}", req.RankId, req.RealmId);
return CSErrCode.SysFailure;
}
// 排行榜关闭或隐藏, 不更新
if (rankDataOne.closeRankTime > 0
|| (rankDataOne.hideRankTime > 0 && RankServerUtils.GetTimeSecond() >= rankDataOne.hideRankTime))
{
TraceLog.Trace("RankSvc.OnAddRankData RankId:{0} RealmId:{1} close or hide", req.RankId, req.RealmId);
return CSErrCode.RankStopUpdate;
}
//太拉跨了不能上榜
if (!CheckRankLimit(rankDesc, req.Score, rankDataOne.CurRecordLimitScore))
{
res.LimintScore = rankDataOne.CurRecordLimitScore;
return CSErrCode.RankScoreLimit;
}
long top;
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(req.Uid, out top))
{
//可能只是切换了称号
ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(top);
need.data.Param = req.Param;
}
long index;
//有需要上榜的缓存数据
if (rankDataOne.data.m_needRankIDMap.TryGetValue(req.Uid, out index))
{
ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.GetByIndex(index);
//需不需要更新数据
if (CheckRankLimit(rankDesc, req.Score, need.data.Score))
{
TraceLog.Trace("RankSvc.OnAddRankData rank {0} realm {1} uid {2} score {3}"
, req.RankId, req.RealmId, req.Uid, req.Score);
need.data.Time = RankServerUtils.GetTimeSecond();
need.data.Icon.CopyFrom(ref req.Icon);
need.data.Nick.CopyFrom(ref req.Nick);
need.data.Gender = req.Gender;
need.data.Level = req.Level;
need.data.Score = req.Score;
need.data.IconFrameId = req.IconFrameId;
need.data.Param = req.Param;
need.data.Skin = req.Skin;
need.data.Weapon1 = req.Weapon1;
need.data.Power = req.Power;
need.data.WingrefitId = req.WingrefitId;
need.data.WingskinId = req.WingskinId;
need.data.WingwearId = req.WingwearId;
rankDataOne.CurRecord.NeedUpdate = true;
return CSErrCode.None;
}
//可能是切换称号
need.data.Param = req.Param;
return CSErrCode.RankScoreLimit;
}
if (AddNeedRankData(rankDataOne, ref req) >= 0)
{
return CSErrCode.None;
}
return CSErrCode.SysFailure;
}
public static int AddNeedRankData(RankDataOne rankDataOne, ref SSAddRankDataReq req)
{
ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.Malloc();
if (need.IsNull())
{
TraceLog.Error("RankSvc.AddNeedRankData malloc cache fail RankId:{0} uid:{1} score:{2}", req.RankId, req.Uid, req.Score);
return -1;
}
rankDataOne.data.m_needRankIDMap.Add(req.Uid, need.GetObjectID());
rankDataOne.CurRecord.NeedUpdate = true;
TraceLog.Trace("RankSvc.AddNeedRankData rank {0} realm {1} uid {2} score {3}"
, req.RankId, req.RealmId, req.Uid, req.Score);
need.data.Clear();
need.data.Uid = req.Uid;
need.data.Rank = rankDataOne.data.m_cacheCurRecord.GetTotalCount() + 1; //排序依据 同分数的话排名会低于之前就在榜上的
need.data.Time = RankServerUtils.GetTimeSecond();
need.data.Icon.CopyFrom(ref req.Icon);
need.data.Nick.CopyFrom(ref req.Nick);
need.data.Gender = req.Gender;
need.data.Level = req.Level;
need.data.Score = req.Score;
need.data.IconFrameId = req.IconFrameId;
need.data.Param = req.Param;
need.data.Skin = req.Skin;
need.data.Weapon1 = req.Weapon1;
need.data.Power = req.Power;
need.data.WingrefitId = req.WingrefitId;
need.data.WingskinId = req.WingskinId;
need.data.WingwearId = req.WingwearId;
RankSvc.DealNeedForceUpdate(rankDataOne);
//没空间了直接排一次
if (rankDataOne.data.m_cacheNeedRankData.GetFreeCount() <= 0)
{
TickUpdateRank(rankDataOne);
}
return 0;
}
public static void OnQueryRankListReq(uint remoteAppID, StructPacket packet)
{
ref CSQueryRankListReq req = ref packet.GetMessage<CSQueryRankListReq>();
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
var desc = RankConfigDescMgr.Instance.GetConfig(req.RankId);
RankDataOne rankDataOne = null;
if (desc.type == RankType.Single)
{
int realmId = req.RealmId;
if (CheckIsKfRank(req.RankId))
{
realmId = req.BigRealmId;
}
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId);
if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.OnQueryRankListReq get realmRankInfo fail RealmId:{0}", realmId);
return;
}
if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, req.RankId))
{
TraceLog.Error("RankSvc.OnQueryRankListReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId);
return;
}
}
else if(desc.type == RankType.All)
{
rankDataOne = RankUtils.GetGlobalRank(req.RankId);
}
// 隐藏排行榜
if (rankDataOne.hideRankTime > 0
&& RankServerUtils.GetTimeSecond() >= rankDataOne.hideRankTime)
{
TraceLog.Trace("RankSvc.OnQueryRankListReq realmId {0} rankId {1} hide at {2}"
, req.RankId, req.RankId, rankDataOne.hideRankTime);
return;
}
CSQueryRankListRes res = new CSQueryRankListRes
{
Ret = (int)CSErrCode.None,
RankId = req.RankId,
HideRankTime = rankDataOne.hideRankTime,
//NextUpdateRankTime = (int)realmRankInfo.m_lastUpdateRankTime + 60
};
long selfUid = packet.ObjectID;
for (int rank = req.StartPos; rank <= req.EndPos; ++rank)
{
if (rank <= rankDataOne.CurRecord.Data.Count && rank > 0)
{
long Uid = rankDataOne.CurRecord.Data[rank - 1];
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(Uid, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
res.RankList.Add(ref data.data);
if (res.RankList.Count >= res.RankList.GetMaxCount())
{
break;
}
}
}
}
res.GetLastReward = true;
if (rankDataOne.CurRecord != null)
{
for (int i = 0; i < rankDataOne.CurRecord.lastRankData.Count; ++i)
{
if (rankDataOne.CurRecord.lastRankData[i].Uid == selfUid)
{
res.LastRank = rankDataOne.CurRecord.lastRankData[i].Rank;
if (!rankDataOne.CurRecord.rewardGetUids.Contains(selfUid))
{
res.GetLastReward = false;
}
break;
}
}
}
//从第一名开始请求的时候需要回自己的排名
res.SelfRank = 0;
if (req.StartPos == 1)
{
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(selfUid, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
if (data.data.Uid == selfUid)
{
res.SelfRank = data.data.Rank;
res.SelfScore = data.data.Score;
res.SelfParam = data.data.Param;
}
}
}
res.PlayerCount = res.RankList.Count;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)CSGameMsgID.QueryRankListRes, ref res, packet.ObjectID);
}
public static void OnQueryRankSelfReq(uint remoteAppID, StructPacket packet)
{
ref CSQueryRankSelfReq req = ref packet.GetMessage<CSQueryRankSelfReq>();
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
int realmId = req.RealmId;
if (CheckIsKfRank(req.RankId))
{
realmId = req.BigRealmId;
}
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId);
if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.OnQueryRankListReq get realmRankInfo fail RealmId:{0}", realmId);
return;
}
if (!serverData.m_RankData.TryGetRankDataOne(out RankDataOne rankDataOne, realmId, req.RankId))
{
TraceLog.Error("RankSvc.OnQueryRankListReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId);
return;
}
if (rankDataOne == null || rankDataOne.CurRecord == null)
{
return;
}
if (rankDataOne.CurRecord.rewardGetUids.Contains(packet.ObjectID))
{
return;
}
CSQueryRankSelfRes res = new CSQueryRankSelfRes();
res.Ret = (int)CSErrCode.None;
res.RankId = req.RankId;
for (int rank = 0; rank < rankDataOne.CurRecord.Data.Count; ++rank)
{
if (rankDataOne.CurRecord.Data[rank] == packet.ObjectID &&
rankDataOne.data.m_curRecordIDMap.TryGetValue(packet.ObjectID, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
res.SelfInfo = data.data;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)CSGameMsgID.QueryRankSelfRes, ref res, packet.ObjectID);
return;
}
}
//未上榜的也需要返回一下数据
res.SelfInfo = new DBRankPlayerInfo() { Rank = 0 };
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)CSGameMsgID.QueryRankSelfRes, ref res, packet.ObjectID);
}
//根据类型获取排行榜list
public static List<int> GetRankListByType(int mainType, int subType)
{
List<int> rankList = new List<int>();
SortedList<int, RankConfigDesc> list = RankConfigDescMgr.Instance.ItemTable;
for (int i = 0; i < list.Values.Count; i++)
{
RankConfigDesc desc = list.Values[i];
}
return rankList;
}
public static void OnQueryRankTopReq(uint remoteAppID, StructPacket packet)
{
ref CSQueryRankTopReq req = ref packet.GetMessage<CSQueryRankTopReq>();
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
CSQueryRankTopRes res = new CSQueryRankTopRes
{
Ret = (int)CSErrCode.None,
MainType = req.MainType,
SubType = req.SubType,
};
List<int> rankList = GetRankListByType(req.MainType, req.SubType);
if (rankList.Count == 0)
{
res.Ret = (int)CSErrCode.RankTypeError;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankTopRes, ref res, packet.ObjectID);
TraceLog.Error("RankSvc.OnQueryRankTopReq type error {0}-{1}", req.MainType, req.SubType);
return;
}
foreach (var rankId in rankList)
{
int realmId = req.RealmId;
if (CheckIsKfRank(rankId))
{
realmId = req.BigRealmId;
}
if (serverData.m_RankData.TryGetRankDataOne(out RankDataOne rankDataOne, realmId, rankId))
{
RankTopPlayerInfo onePlayer = new RankTopPlayerInfo
{
Uid = 0,
RankId = rankId,
};
if (rankDataOne.CurRecord.Data.Count > 0)
{
long Uid = rankDataOne.CurRecord.Data[0];
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(Uid, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
onePlayer.Uid = data.data.Uid;
onePlayer.Gender = data.data.Gender;
onePlayer.Level = data.data.Level;
onePlayer.Score = data.data.Score;
onePlayer.Nick.CopyFrom(ref data.data.Nick);
onePlayer.Icon.CopyFrom(ref data.data.Icon);
onePlayer.Time = data.data.Time;
onePlayer.IconFrameId = data.data.IconFrameId;
}
}
res.TopInfo.Add(ref onePlayer);
if (res.TopInfo.Count >= res.TopInfo.GetMaxCount())
{
TraceLog.Error("RankSvc.OnQueryRankTopReq top count is full {0}", res.TopInfo.Count);
break;
}
}
}
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)CSGameMsgID.QueryRankTopRes, ref res, packet.ObjectID);
}
public static void OnPlayerShowInfoUpdate(uint remoteAppID, StructPacket packet)
{
ref SSPlayerShowInfoUpdate req = ref packet.GetMessage<SSPlayerShowInfoUpdate>();
RealmRankInfo realmInfo = RankUtils.GetRealmRankInfo(req.RealmId);
if (realmInfo == null || realmInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.OnPlayerShowInfoUpdate RealmId:{0} no load success", req.RealmId);
return;
}
foreach (var item in realmInfo.m_rankMap)
{
var rankDataOne = item.Value;
//在榜上
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(req.Uid, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
if (data.data.Uid == req.Uid)
{
data.data.Level = req.Level;
data.data.Gender = req.Gender;
data.data.Icon.CopyFrom(ref req.Icon);
data.data.Nick.CopyFrom(ref req.Nick);
data.data.IconFrameId = req.IconFrameId;
data.data.Power = req.Power;
data.data.Skin = req.Skin;
data.data.WingskinId = req.WingskinId;
data.data.WingrefitId = req.WingrefitId;
data.data.WingwearId = req.WingwearId;
rankDataOne.CurRecord.MakeDirty();
}
}
//在即将上榜的缓存中
if (rankDataOne.data.m_needRankIDMap.TryGetValue(req.Uid, out index))
{
ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.GetByIndex(index);
if (need.data.Uid == req.Uid)
{
need.data.Gender = req.Gender;
need.data.Level = req.Level;
need.data.Icon.CopyFrom(ref req.Icon);
need.data.Nick.CopyFrom(ref req.Nick);
need.data.IconFrameId = req.IconFrameId;
need.data.Power = req.Power;
need.data.Skin = req.Skin;
need.data.WingskinId = req.WingskinId;
need.data.WingrefitId = req.WingrefitId;
need.data.WingwearId = req.WingwearId;
rankDataOne.CurRecord.NeedUpdate = true;
}
}
}
}
//添加禁止上榜名单
public static bool AddForbitRankUid(long uid)
{
WorldRankData rankData = RankServerUtils.GetRankData();
return rankData.m_forbitUidMap.TryAdd(uid, true);
}
public static bool CheckIsKfRank(int rankId)
{
var desc = RankConfigDescMgr.Instance.GetConfig(rankId);
if (desc != null && desc.reasonType == (int)RankReasonType.ArenaStarRank)
{
return true;
}
return false;
}
public static void QueryRankOneReq(uint remoteAppID, StructPacket packet)
{
ref SSQueryRankOneReq req = ref packet.GetMessage<SSQueryRankOneReq>();
var res = new SSQueryRankOneRes();
res.Uid = req.Uid; ;
res.RealmId = req.RealmId;
res.RankId = req.RankId;
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
var desc = RankConfigDescMgr.Instance.GetConfig(req.RankId);
RankDataOne rankDataOne = null;
if (desc.type == RankType.Single)
{
int realmId = req.RealmId;
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId);
if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.QueryRankOneReq get realmRankInfo fail RealmId:{0}", realmId);
return;
}
if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, req.RankId))
{
TraceLog.Error("RankSvc.QueryRankOneReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId);
//没有记录
res.Ret = 1;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID);
return;
}
if(rankDataOne.data.m_curRecordIDMap.TryGetValue(req.RankId, out var cidx))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(cidx);
if (data.data.Uid == req.Uid)
{
res.Rank.CopyFrom(ref data.data);
res.Ret = 0;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID);
return;
}
}
//没有记录
res.Ret = 1;
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID);
}
}
public static void TALogRank(long nowSecond)
{
WorldRankData rankData = RankServerUtils.GetRankData();
foreach (var realIdItem in rankData.AllRank.Values)
{
foreach (var rankItem in realIdItem.m_rankMap.Values)
{
if (rankItem.CurRecord != null)
{
if(rankItem.RankID == 1)
{
for (int i = 0; i < rankItem.CurRecord.Data.Count; i++)
{
long uid = rankItem.CurRecord.Data[i];
if (rankItem.data.m_curRecordIDMap.TryGetValue(uid, out long index))
{
ref var d = ref rankItem.data.m_cacheCurRecord.GetByIndex(index);
LogChapterRank(uid, i + 1, (int)d.data.Score, d.data.Param);
}
}
}
}
}
}
}
public static void LogChapterRank(long uid, int rank, int mainland_id, int fight_time)
{
var ta = new TALogHelper(TALOG_TYPE.TRACE, uid + "", "", TALogEventName.RANK_FLOW);
ta.Add("rank", rank);
ta.Add("mainland_id", mainland_id);
ta.Add("fight_time", fight_time);
ta.PutLog();
}
public static void LogContinueBattleRank(long uid, int rank, int stage_max, int score, string rewardid)
{
var ta = new TALogHelper(TALOG_TYPE.TRACE, uid + "", "", TALogEventName.continue_battle_rank);
ta.Add("rank", rank);
ta.Add("stage_max", stage_max);
ta.Add("score", score);
ta.Add("rewards_id", rewardid);
ta.PutLog();
}
public static void RankPlayerBylevelReq(uint remoteAppID, StructPacket packet)
{
ref CSRankPlayerByLevelReq req = ref packet.GetMessage<CSRankPlayerByLevelReq>();
var res = new CSRankPlayerByLevelRes();
res.Uid = req.Uid; ;
res.RealmId = req.RealmId;
//获取榜单
RankServerData serverData = ServerDataObjMgr.GetDataObj<RankServerData>(RankDataObjType.RankServerData);
var desc = RankConfigDescMgr.Instance.GetConfig(1);
RankDataOne rankDataOne = null;
if (desc.type == RankType.Single)
{
int realmId = req.RealmId;
RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId);
if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false)
{
TraceLog.Error("RankSvc.RankPlayerBylevelReq get realmRankInfo fail RealmId:{0}", realmId);
return;
}
if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, desc.rankId))
{
TraceLog.Error("RankSvc.RankPlayerBylevelReq get RankData fail RealmId:{0} RankId:{1}", realmId, desc.rankId);
//没有记录
return;
}
List<long> idlist = new List<long>();
for (int i = 0; i < rankDataOne.CurRecord.Data.Count; i++)
{
long uid = rankDataOne.CurRecord.Data[i];
if (rankDataOne.data.m_curRecordIDMap.TryGetValue(uid, out long index))
{
ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index);
if (data.data.Level <= req.LvMax && data.data.Level >= req.LvMin)
{
idlist.Add(uid);
if (idlist.Count == 10) break;
}
}
}
if (idlist.Count > 0)
{
GenericUtils.Shuffle(RankServerUtils.GetRankServerData().m_app.Rand, idlist);
res.Uids.Add(idlist[0]);
}
RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID,
(int)CSGameMsgID.RankPlayerBylevelRes, ref res, packet.ObjectID);
}
}
}
}