using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
namespace vnxbqy.UI
|
{
|
|
public class RankModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk
|
{
|
//后续不再使用,旧逻辑依然有在用不要删除 C1001_tagCWatchBillboard, H1001_tagBillboard接收排行榜信息
|
//改用 HA9A2_tagPYBillboardData 和 HC007_tagGCCrossBillboardInfo; 参考m_RankPageDatas
|
public Dictionary<int, List<RankData>> m_RankDatas = new Dictionary<int, List<RankData>>();
|
|
public Dictionary<int, List<int>> displaySubRanks = new Dictionary<int, List<int>>();
|
public Dictionary<int, bool> subRankSpreads = new Dictionary<int, bool>();
|
public List<int> displayRanks = new List<int>();
|
|
int m_SelectRankId = 0;
|
public int selectRankId
|
{
|
get { return m_SelectRankId; }
|
|
set
|
{
|
if (m_SelectRankId != value)
|
{
|
m_SelectSubRankId = 0;
|
m_SelectRankId = value;
|
if (selectRankIdRefresh != null)
|
{
|
selectRankIdRefresh();
|
}
|
}
|
}
|
}
|
|
int m_SelectSubRankId = 0;
|
public int selectSubRankId
|
{
|
get { return m_SelectSubRankId; }
|
set
|
{
|
if (m_SelectSubRankId != value)
|
{
|
m_SelectSubRankId = value;
|
if (selectSubRankIdRefresh != null)
|
{
|
selectSubRankIdRefresh();
|
}
|
}
|
}
|
}
|
|
public int selectRankType
|
{
|
get
|
{
|
if (displaySubRanks.ContainsKey(selectRankId))
|
{
|
var config = RankListConfig.Get(selectSubRankId);
|
return config == null ? 0 : config.type;
|
}
|
else
|
{
|
var config = RankListConfig.Get(selectRankId);
|
return config == null ? 0 : config.type;
|
}
|
}
|
}
|
|
public int displayRankCount { get; private set; }
|
public int jumpRankType { get; set; }
|
|
public readonly ObjectPool<RankData> m_RankDataPool = new ObjectPool<RankData>(OnGetRankData, OnReleaseRankData);
|
|
public event Action selectRankIdRefresh;
|
public event Action selectSubRankIdRefresh;
|
public event Action<int> onRankRefresh;
|
public event Action<int> onMyRankRefresh;
|
|
public override void Init()
|
{
|
jumpRankType = -1;
|
ParseConfig();
|
}
|
|
public void OnBeforePlayerDataInitialize()
|
{
|
foreach (var rankDatas in m_RankDatas.Values)
|
{
|
foreach (var item in rankDatas)
|
{
|
m_RankDataPool.Release(item);
|
}
|
}
|
m_RankDatas.Clear();
|
|
m_RankPageDatas.Clear();
|
m_RankIDToIndex.Clear();
|
queryRankCD.Clear();
|
}
|
|
public void OnPlayerLoginOk()
|
{
|
//SendBegRank(RankType.JadeDynastyTower);
|
}
|
|
public override void UnInit()
|
{
|
}
|
|
void ParseConfig()
|
{
|
{
|
var config = FuncConfigConfig.Get("RankListCnt");
|
displayRankCount = int.Parse(config.Numerical1);
|
}
|
|
{
|
var configs = RankListConfig.GetValues();
|
foreach (var config in configs)
|
{
|
if (config.ID >= 100)
|
{
|
var rankId = config.ID / 100;
|
List<int> subRanks = null;
|
if (!displaySubRanks.TryGetValue(rankId, out subRanks))
|
{
|
subRanks = new List<int>();
|
displaySubRanks.Add(rankId, subRanks);
|
}
|
subRanks.Add(config.ID);
|
}
|
else
|
{
|
displayRanks.Add(config.ID);
|
}
|
}
|
}
|
}
|
|
public bool TryGetRanks(int type, out List<RankData> ranks)
|
{
|
return m_RankDatas.TryGetValue(type, out ranks);
|
}
|
|
public bool TryGetMyRank(int type, out int rank)
|
{
|
rank = 0;
|
var playerId = PlayerDatas.Instance.baseData.PlayerID;
|
List<RankData> rankDatas = null;
|
if (TryGetRanks(type, out rankDatas))
|
{
|
for (int i = 0; i < rankDatas.Count; i++)
|
{
|
if (rankDatas[i].id == playerId)
|
{
|
rank = i + 1;
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
public bool TryGetMyRankByID(int type, int queryID, out int rank)
|
{
|
rank = 0;
|
List<RankData> rankDatas = null;
|
if (TryGetRanks(type, out rankDatas))
|
{
|
for (int i = 0; i < rankDatas.Count; i++)
|
{
|
if (rankDatas[i].id == queryID)
|
{
|
rank = i + 1;
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
|
public void SendBegRank(RankType rankType)
|
{
|
C1001_tagCWatchBillboard rankPack = new C1001_tagCWatchBillboard();
|
rankPack.Type = (byte)rankType;
|
GameNetSystem.Instance.SendInfo(rankPack);
|
}
|
|
|
public void ReceivePackage(H1001_tagBillboard package)
|
{
|
List<RankData> rankDatas = null;
|
if (!m_RankDatas.TryGetValue(package.Type, out rankDatas))
|
{
|
rankDatas = new List<RankData>();
|
m_RankDatas.Add(package.Type, rankDatas);
|
}
|
for (int i = 0; i < package.BillboardCount; i++)
|
{
|
if (i < rankDatas.Count)
|
{
|
rankDatas[i].type = package.Type;
|
ReSetRankData(rankDatas[i], package.Billboard[i]);
|
}
|
else
|
{
|
var rankData = m_RankDataPool.inactivedCount > 0 ?
|
m_RankDataPool.Get() : new RankData();
|
rankData.type = package.Type;
|
ReSetRankData(rankData, package.Billboard[i]);
|
rankDatas.Add(rankData);
|
}
|
}
|
var start = package.BillboardCount;
|
var end = rankDatas.Count;
|
for (int i = end - 1; i >= start; i--)
|
{
|
RankData data = rankDatas[i];
|
rankDatas.RemoveAt(i);
|
m_RankDataPool.Release(data);
|
}
|
if (onRankRefresh != null)
|
{
|
onRankRefresh(package.Type);
|
}
|
}
|
|
void ReSetRankData(RankData data, H1001_tagBillboard.tagBillboardList serverData)
|
{
|
data.id = serverData.ID;
|
data.name1 = serverData.Name1.Trim().Replace("\0", "");
|
data.name2 = serverData.Name2.Trim().Replace("\0", "");
|
data.subType = serverData.Type2;
|
data.value1 = serverData.Value1;
|
data.value2 = serverData.Value2;
|
data.value3 = serverData.Value3;
|
data.value4 = serverData.Value4;
|
data.value5 = serverData.Value5;
|
data.value6 = serverData.Value6;
|
data.value7 = serverData.Value7;
|
data.value8 = serverData.Value8;
|
data.cmpValue = serverData.CmpValue;
|
data.cmpValue2 = serverData.CmpValue2;
|
data.cmpValue3 = serverData.CmpValue3;
|
data.userData = serverData.UserData;
|
}
|
|
void ReSetRankDataEx(RankData data, HA9A2_tagPYBillboardData.tagPYBillboardInfo serverData, int type)
|
{
|
data.id = serverData.ID;
|
data.id2 = (int)serverData.ID2;
|
data.name1 = serverData.Name1.Trim().Replace("\0", "");
|
data.name2 = serverData.Name2.Trim().Replace("\0", "");
|
data.subType = serverData.Type2;
|
data.value1 = serverData.Value1;
|
data.value2 = serverData.Value2;
|
data.value3 = serverData.Value3;
|
data.value4 = serverData.Value4;
|
data.value5 = serverData.Value5;
|
data.value6 = serverData.Value6;
|
data.value7 = serverData.Value7;
|
data.value8 = serverData.Value8;
|
data.cmpValue = serverData.CmpValue;
|
data.cmpValue2 = serverData.CmpValue2;
|
data.cmpValue3 = serverData.CmpValue3;
|
data.userData = serverData.UserData;
|
data.index = (int)serverData.OrderIndex;
|
data.type = type;
|
}
|
|
static void OnGetRankData(RankData data)
|
{
|
|
}
|
|
static void OnReleaseRankData(RankData data)
|
{
|
|
}
|
|
#region 分页查询
|
Dictionary<int, int> queryRankCD = new Dictionary<int, int>(); //查询CD
|
Dictionary<int, Dictionary<int, RankData>> m_RankPageDatas = new Dictionary<int, Dictionary<int, RankData>>(); //分页查询 排名索引按字段存储 0代表第一名
|
//类型:ID -排名索引,通过ID进行排重删除 不同名次 同ID的数据
|
Dictionary<int, Dictionary<int, int>> m_RankIDToIndex = new Dictionary<int, Dictionary<int, int>>();
|
|
|
//本服分页查询使用说明
|
//1. QueryRankByPage:先查询第一页,startIndex = 0, count = 30, 在第一页查询前可以选择初始化ResetQueryParam
|
//2. ListenRankPage:一般在滚动条OnRefreshCell监听排行榜显示名次,用于分页查询
|
// WatchID; //查看指定ID名次前后,其他参数无效
|
public void QueryRankByPage(int type, int startIndex = 0, int count = 30, int watchID = 0, bool forceQuery = false)
|
{
|
if (queryRankCD.ContainsKey(type) && !forceQuery)
|
{
|
if (Time.time - queryRankCD[type] < 2f)
|
{
|
return;
|
}
|
}
|
|
var pak = new CA9A2_tagCPYWatchBillboard();
|
pak.Type = (byte)type;
|
pak.StartIndex = (uint)startIndex; //排名从0开始
|
pak.WatchCnt = (byte)count;
|
pak.WatchID = (uint)watchID;
|
|
GameNetSystem.Instance.SendInfo(pak);
|
queryRankCD[type] = (int)Time.time;
|
}
|
|
//监听排行榜显示名次,用于分页查询,第一页查询由外部触发
|
//使用场景 如界面排行榜滚动的时候每次查询30个排名名额,在显示大于m*30 +20名时,监听下一页,查询m+1页
|
int pageCnt = 30; //每页查询条数
|
int queryPointNum = 20; //查询点
|
int queryPageCD = 60; //查询点CD 避免不断上下滑动的时候过于频繁查询,外部使用重新打开的时候可以重置CD
|
Dictionary<int, float> queryPageTimes = new Dictionary<int, float>(); //查询页CD
|
public void ListenRankPage(int type, int index)
|
{
|
int page = index / pageCnt;
|
if (index > page * pageCnt + queryPointNum)
|
{
|
if (queryPageTimes.ContainsKey(page) && Time.realtimeSinceStartup - queryPageTimes[page] < queryPageCD)
|
return;
|
Debug.LogFormat("分页查询:{0} - {1}", index, page);
|
QueryRankByPage(type, pageCnt * (page + 1), pageCnt, forceQuery:true);
|
queryPageTimes[page] = Time.realtimeSinceStartup;
|
}
|
}
|
|
public void ResetQueryParam()
|
{
|
pageCnt = 30;
|
queryPointNum = 20;
|
queryPageCD = 60;
|
queryPageTimes.Clear();
|
}
|
|
public void SetQueryParm(int pageCnt, int queryPointNum, int queryPageCD)
|
{
|
this.pageCnt = pageCnt;
|
this.queryPointNum = queryPointNum;
|
this.queryPageCD = queryPageCD;
|
queryPageTimes.Clear();
|
}
|
|
|
//分页查询使用说明
|
//1. QueryCrossRank:先查询第一页,startIndex = 0, count = 30, 在第一页查询前可以选择初始化ResetQueryParam
|
//2. ListenCrossRankPage:一般在滚动条OnRefreshCell监听排行榜显示名次,用于分页查询
|
// WatchID; //查看指定ID名次前后,其他参数无效
|
//查询跨服排行榜,排行榜类型可能因跨服功能不同 由分组分赛季等情况组合
|
/// <param name="count"> 查看条数,服务端默认20,最大不超过100 </param>
|
public void QueryCrossRank(int type, int groupID, int startIndex = 0, int count = 30, int watchID = 0, int cd = 2, bool forceQuery = false, int groupValue2 = 0)
|
{
|
if (queryRankCD.ContainsKey(type) && !forceQuery)
|
{
|
if (Time.time - queryRankCD[type] < cd)
|
{
|
return;
|
}
|
}
|
|
var pak = new CC004_tagCGViewCrossBillboard();
|
pak.Type = (byte)type;
|
pak.GroupValue1 = (byte)groupID;
|
pak.GroupValue2 = (uint)groupValue2;
|
pak.StartIndex = (uint)startIndex;
|
pak.WatchCnt = (byte)count;
|
pak.WatchID = (uint)watchID;
|
GameNetSystem.Instance.SendInfo(pak);
|
|
queryRankCD[type] = (int)Time.time;
|
}
|
|
//groupVaule2 用于分组分赛季等情况
|
public void ListenCrossRankPage(int type, int groupID, int index, int groupVaule2 = 0)
|
{
|
int page = index / pageCnt;
|
if (index > page * pageCnt + queryPointNum)
|
{
|
if (queryPageTimes.ContainsKey(page) && Time.realtimeSinceStartup - queryPageTimes[page] < queryPageCD)
|
return;
|
Debug.LogFormat("跨服分页查询:{0} - {1}", index, page);
|
QueryCrossRank(type, groupID, pageCnt * (page + 1), pageCnt, forceQuery: true, groupValue2: groupVaule2);
|
queryPageTimes[page] = Time.realtimeSinceStartup;
|
}
|
}
|
|
|
//跨服排行榜信息
|
public void UpdateCSBillboardInfo(HC007_tagGCCrossBillboardInfo package)
|
{
|
if (package.Type == 150)
|
{
|
//已在 CSRechargeModel 处理,此处过滤
|
return;
|
}
|
|
ReceivePackageCross(package);
|
|
}
|
|
//跨服排行榜信息
|
public void ReceivePackageCross(HC007_tagGCCrossBillboardInfo package)
|
{
|
int rankType = package.Type;
|
//部分跨服排行榜同一个榜存在分组分区的情况 //赛区3位+赛季3位+排行榜类型3位
|
if (rankType == CrossServerOneVsOneRewardModel.rankType)
|
{
|
rankType = (int)package.GroupValue1 * 1000000 + (int)package.GroupValue2 * 1000 + rankType;
|
}
|
if (!m_RankPageDatas.ContainsKey(rankType))
|
{
|
m_RankPageDatas.Add(rankType, new Dictionary<int, RankData>());
|
}
|
|
//同ID排重删除
|
if (!m_RankIDToIndex.ContainsKey(rankType))
|
{
|
m_RankIDToIndex.Add(rankType, new Dictionary<int, int>());
|
}
|
|
for (int i = 0; i < package.BillboardCount; i++)
|
{
|
int id = (int)package.CrossBillboardDataList[i].ID;
|
int orderIndex = (int)package.CrossBillboardDataList[i].OrderIndex;
|
if (!m_RankIDToIndex[rankType].ContainsKey(id))
|
{
|
m_RankIDToIndex[rankType][id] = orderIndex;
|
}
|
else if (m_RankIDToIndex[rankType][id] != orderIndex)
|
{
|
m_RankPageDatas[rankType].Remove(m_RankIDToIndex[rankType][id]);
|
m_RankIDToIndex[rankType][id] = orderIndex;
|
}
|
}
|
|
|
for (int i = 0; i < package.BillboardCount; i++)
|
{
|
int orderIndex = (int)package.CrossBillboardDataList[i].OrderIndex;
|
if (!m_RankPageDatas[rankType].ContainsKey(orderIndex))
|
{
|
m_RankPageDatas[rankType][orderIndex] = new RankData();
|
}
|
ReSetRankData(m_RankPageDatas[rankType][orderIndex], package.CrossBillboardDataList[i], package.Type);
|
}
|
|
if (package.WatchID != 0)
|
{
|
onMyRankRefresh?.Invoke(rankType);
|
}
|
else
|
{
|
onRankRefresh?.Invoke(rankType);
|
}
|
}
|
|
//跨服排行榜信息
|
void ReSetRankData(RankData data, HC007_tagGCCrossBillboardInfo.tagGCCrossBillboardData serverData, int type)
|
{
|
data.id = serverData.ID;
|
data.id2 = (int)serverData.ID2;
|
data.name1 = serverData.Name1.Replace("\0", "");
|
data.name2 = serverData.Name2.Replace("\0", "");
|
data.subType = serverData.Type2;
|
data.value1 = serverData.Value1;
|
data.value2 = serverData.Value2;
|
data.value3 = serverData.Value3;
|
data.value4 = serverData.Value4;
|
data.value5 = serverData.Value5;
|
data.value6 = serverData.Value6;
|
data.value7 = serverData.Value7;
|
data.value8 = serverData.Value8;
|
data.cmpValue = serverData.CmpValue;
|
data.cmpValue2 = serverData.CmpValue2;
|
data.cmpValue3 = serverData.CmpValue3;
|
data.userData = serverData.UserData;
|
data.index = serverData.OrderIndex;
|
data.type = type; //与服务端一致的跨服排行榜类型,外部自行处理不同分组分赛季等情况
|
}
|
|
//查询本服排行榜
|
public void ReceiveRankPagePackage(HA9A2_tagPYBillboardData package)
|
{
|
if (package.Type == 28)
|
//本服竞技场排行榜,已在 ArenaRankModel 处理,此处过滤
|
return;
|
|
|
if (!m_RankPageDatas.ContainsKey(package.Type))
|
{
|
m_RankPageDatas.Add(package.Type, new Dictionary<int, RankData>());
|
}
|
|
//同ID排重删除
|
if (!m_RankIDToIndex.ContainsKey(package.Type))
|
{
|
m_RankIDToIndex.Add(package.Type, new Dictionary<int, int>());
|
}
|
|
for (int i = 0; i < package.BillboardCount; i++)
|
{
|
int id = (int)package.Billboard[i].ID;
|
int orderIndex = (int)package.Billboard[i].OrderIndex;
|
if (!m_RankIDToIndex[package.Type].ContainsKey(id))
|
{
|
m_RankIDToIndex[package.Type][id] = orderIndex;
|
}
|
else if (m_RankIDToIndex[package.Type][id] != orderIndex)
|
{
|
m_RankPageDatas[package.Type].Remove(m_RankIDToIndex[package.Type][id]);
|
m_RankIDToIndex[package.Type][id] = orderIndex;
|
}
|
}
|
|
|
|
for (int i = 0; i < package.BillboardCount; i++)
|
{
|
int orderIndex = (int)package.Billboard[i].OrderIndex;
|
if (!m_RankPageDatas[package.Type].ContainsKey(orderIndex))
|
{
|
m_RankPageDatas[package.Type][orderIndex] = new RankData();
|
}
|
ReSetRankDataEx(m_RankPageDatas[package.Type][orderIndex], package.Billboard[i], package.Type);
|
}
|
|
if (package.WatchID != 0)
|
{
|
onMyRankRefresh?.Invoke(package.Type);
|
}
|
else
|
{
|
onRankRefresh?.Invoke(package.Type);
|
}
|
}
|
|
//排名从0 开始
|
//如果是跨服排行榜 类型可能因跨服功能不同 由分组分赛季等情况组合
|
public Dictionary<int, RankData> GetRankPageDatas(int type)
|
{
|
Dictionary<int, RankData> datas = null;
|
if (m_RankPageDatas.TryGetValue(type, out datas))
|
{
|
return datas;
|
}
|
return null;
|
}
|
|
|
////如果是跨服排行榜 类型可能因跨服功能不同 由分组分赛季等情况组合
|
public RankData GetMyRank(int type)
|
{
|
var playerId = PlayerDatas.Instance.baseData.PlayerID;
|
Dictionary<int, RankData> rankDatas = null;
|
if (m_RankPageDatas.TryGetValue(type, out rankDatas))
|
{
|
foreach (var item in rankDatas.Values)
|
{
|
if (item.id == playerId)
|
{
|
return item;
|
}
|
}
|
}
|
return null;
|
}
|
|
public RankData GetMyRankByID(int type, int queryID)
|
{
|
Dictionary<int, RankData> rankDatas = null;
|
if (m_RankPageDatas.TryGetValue(type, out rankDatas))
|
{
|
foreach (var item in rankDatas.Values)
|
{
|
if (item.id == queryID)
|
{
|
return item;
|
}
|
}
|
}
|
return null;
|
}
|
#endregion
|
}
|
|
public class RankData
|
{
|
public int type; //排行榜类型
|
public int subType;
|
public uint id;
|
public int id2;
|
public string name1;
|
public string name2;
|
public uint value1;
|
public uint value2;
|
public uint value3;
|
public uint value4;
|
public uint value5;
|
public uint value6;
|
public uint value7;
|
public uint value8;
|
public uint cmpValue;
|
public uint cmpValue2;
|
public uint cmpValue3;
|
public string userData;
|
public int index; //分页查询会用到 排名
|
}
|
}
|
|