초기커밋
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcCommunicationRankAction : EntityActionBase
|
||||
{
|
||||
private Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks { get; } = new();
|
||||
|
||||
public UgcNpcCommunicationRankAction(UgcNpcRankEntity owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
|
||||
{
|
||||
if (!m_ranks.TryGetValue(state, out var ranks))
|
||||
{
|
||||
ranks = await loadRank(state);
|
||||
}
|
||||
|
||||
return (new Result(), ranks);
|
||||
}
|
||||
|
||||
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
|
||||
{
|
||||
Result result;
|
||||
AIChatRanking? chat_ranks;
|
||||
List<UgcNpcRank>? list;
|
||||
|
||||
var ugc_npc_guids = new List<(string, long)>();
|
||||
|
||||
// 누적 랭킹 조회
|
||||
if (state == UgcNpcRankState.Total)
|
||||
{
|
||||
(result, chat_ranks) = await AIChatServerConnector.getAllRanking(LanguageType.Ko, UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail() || chat_ranks == null) return null;
|
||||
}
|
||||
// 트랜드 랭킹 조회
|
||||
else
|
||||
{
|
||||
(result, chat_ranks) = await AIChatServerConnector.getTodayRanking(LanguageType.Ko, UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail() || chat_ranks == null) return null;
|
||||
}
|
||||
|
||||
foreach (var rank in chat_ranks.items)
|
||||
{
|
||||
ugc_npc_guids.Add((UgcNpcRankHelper.makeRankKey(rank.owner_guid, rank.char_guid), rank.total_chat_count));
|
||||
}
|
||||
|
||||
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(ugc_npc_guids);
|
||||
|
||||
Log.getLogger().info($"update ugc npc communication rank data : rank state[{state}] / rank count[{list.Count}]");
|
||||
m_ranks[state] = list;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
93
GameServer/Entity/Ranking/Action/UgcNpcLikeRankAction.cs
Normal file
93
GameServer/Entity/Ranking/Action/UgcNpcLikeRankAction.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcLikeRankAction : EntityActionBase
|
||||
{
|
||||
private readonly Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks;
|
||||
|
||||
public UgcNpcLikeRankAction(UgcNpcRankEntity owner) : base(owner)
|
||||
{
|
||||
m_ranks = new();
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
|
||||
{
|
||||
if (!m_ranks.TryGetValue(state, out var ranks))
|
||||
{
|
||||
ranks = await loadRank(state);
|
||||
}
|
||||
|
||||
return (new Result(), ranks);
|
||||
}
|
||||
|
||||
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
|
||||
{
|
||||
Result result;
|
||||
List<UgcNpcRank>? list;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var redis_client = server_logic.getRedisConnector();
|
||||
|
||||
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
|
||||
|
||||
// 누적 랭킹 조회
|
||||
if (state == UgcNpcRankState.Total)
|
||||
{
|
||||
var total_cache_request = new UgcNpcTotalRankCacheRequest(UgcNpcRankType.Like, rank_date, redis_client);
|
||||
|
||||
result = await total_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail()) return null;
|
||||
|
||||
var total_cache = total_cache_request.getTotalCache();
|
||||
NullReferenceCheckHelper.throwIfNull(total_cache, () => $"total_cache is null !!!");
|
||||
|
||||
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(total_cache.Ranks);
|
||||
}
|
||||
// 트랜드 랭킹 조회
|
||||
else
|
||||
{
|
||||
var trend_cache_request = new UgcNpcTrendRankCacheRequest(UgcNpcRankType.Like, rank_date, redis_client);
|
||||
result = await trend_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail()) return null;
|
||||
|
||||
var trend_rank_cache = trend_cache_request.getTrendRankCache();
|
||||
NullReferenceCheckHelper.throwIfNull(trend_rank_cache, () => $"trend_rank_cache is null !!!");
|
||||
|
||||
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(trend_rank_cache.Ranks);
|
||||
}
|
||||
|
||||
Log.getLogger().info($"update ugc npc like rank data : rank state[{state}] / rank count[{list.Count}]");
|
||||
m_ranks[state] = list;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<Result> setRankScore(string ownerGuid, string targetUserGuid, string ugcNpcMetaGuid, bool isAdd)
|
||||
{
|
||||
var key = UgcNpcRankHelper.makeRankKey(targetUserGuid, ugcNpcMetaGuid);
|
||||
var delta = isAdd ? 1 : -1;
|
||||
|
||||
var result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Like, key, delta, null);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Like, key, delta, UgcNpcRankHelper.makeCurrentOrganizationDate());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
93
GameServer/Entity/Ranking/Action/UgcNpcQuestRankAction.cs
Normal file
93
GameServer/Entity/Ranking/Action/UgcNpcQuestRankAction.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcQuestRankAction : EntityActionBase
|
||||
{
|
||||
private readonly Dictionary<UgcNpcRankState, List<UgcNpcRank>> m_ranks;
|
||||
|
||||
public UgcNpcQuestRankAction(UgcNpcRankEntity owner) : base(owner)
|
||||
{
|
||||
m_ranks = new();
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<(Result result, List<UgcNpcRank>? list)> getRanks(UgcNpcRankState state)
|
||||
{
|
||||
if (!m_ranks.TryGetValue(state, out var ranks))
|
||||
{
|
||||
ranks = await loadRank(state);
|
||||
}
|
||||
|
||||
return (new Result(), ranks);
|
||||
}
|
||||
|
||||
public async Task<List<UgcNpcRank>?> loadRank(UgcNpcRankState state)
|
||||
{
|
||||
Result result;
|
||||
List<UgcNpcRank>? list;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var redis_client = server_logic.getRedisConnector();
|
||||
|
||||
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
|
||||
|
||||
// 누적 랭킹 조회
|
||||
if (state == UgcNpcRankState.Total)
|
||||
{
|
||||
var total_cache_request = new UgcNpcTotalRankCacheRequest(UgcNpcRankType.Quest, rank_date, redis_client);
|
||||
|
||||
result = await total_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail()) return null;
|
||||
|
||||
var total_cache = total_cache_request.getTotalCache();
|
||||
NullReferenceCheckHelper.throwIfNull(total_cache, () => $"total_cache is null !!!");
|
||||
|
||||
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(total_cache.Ranks);
|
||||
}
|
||||
// 트랜드 랭킹 조회
|
||||
else
|
||||
{
|
||||
var trend_cache_request = new UgcNpcTrendRankCacheRequest(UgcNpcRankType.Quest, rank_date, redis_client);
|
||||
result = await trend_cache_request.getRanks(UgcNpcRankEntity.DefaultPageNum, UgcNpcRankEntity.DefaultPageSize);
|
||||
if (result.isFail()) return null;
|
||||
|
||||
var trend_rank_cache = trend_cache_request.getTrendRankCache();
|
||||
NullReferenceCheckHelper.throwIfNull(trend_rank_cache, () => $"trend_rank_cache is null !!!");
|
||||
|
||||
list = await UgcNpcRankHelper.getUgcNpcSummaryFromMetaGuid(trend_rank_cache.Ranks);
|
||||
}
|
||||
|
||||
Log.getLogger().info($"update ugc npc quest rank data : rank state[{state}] / rank count[{list.Count}]");
|
||||
m_ranks[state] = list;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<Result> setRankScore(string ownerGuid, string targetUserGuid, string ugcNpcMetaGuid, bool isAdd)
|
||||
{
|
||||
var key = UgcNpcRankHelper.makeRankKey(targetUserGuid, ugcNpcMetaGuid);
|
||||
var delta = isAdd ? 1 : -1;
|
||||
|
||||
var result = await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Quest, key, delta, null);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
await UgcNpcRankHelper.updateUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest, key, delta, UgcNpcRankHelper.makeCurrentOrganizationDate());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
433
GameServer/Entity/Ranking/Action/UgcNpcRankManageAction.cs
Normal file
433
GameServer/Entity/Ranking/Action/UgcNpcRankManageAction.cs
Normal file
@@ -0,0 +1,433 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcRankManageAction : EntityActionBase
|
||||
{
|
||||
private UgcNpcRankManageCacheRequest m_rank_manage_cache_request { get; set; }
|
||||
|
||||
public UgcNpcRankManageAction(UgcNpcRankEntity owner) : base(owner)
|
||||
{
|
||||
// DailyTimeEventManager 등록
|
||||
var date = MetaHelper.GameConfigMeta.NpcRankingCalculateTime;
|
||||
DailyTimeEventManager.Instance.tryAddTask("UgcNpcRankManage", date, onOrganizationUgcNpcRanking);
|
||||
|
||||
var businesslog_refresh_date = MetaHelper.GameConfigMeta.BusinessLogRefreshTime;
|
||||
DailyTimeEventManager.Instance.tryAddTask("BusinessLogRefresh", businesslog_refresh_date, onBusunessLogRefresh);
|
||||
|
||||
m_rank_manage_cache_request =
|
||||
new UgcNpcRankManageCacheRequest(GameServerApp.getServerLogic().getRedisConnector());
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
public override void onClear() {}
|
||||
|
||||
public async Task<Result> initRank()
|
||||
{
|
||||
// 1. 기본 정보 체크
|
||||
var result = await checkBaseUgcNpcRank();
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. Ranking 데이터 로딩
|
||||
await reloadAllUgcNpcRanks();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task reloadAllUgcNpcRanks()
|
||||
{
|
||||
try
|
||||
{
|
||||
var ranking_types = System.Enum.GetValues(typeof(UgcNpcRankType)).Cast<UgcNpcRankType>().ToList();
|
||||
var tasks = new List<Task>(ranking_types.Count * 2);
|
||||
|
||||
foreach (var type in ranking_types)
|
||||
{
|
||||
tasks.Add(getUgcNpcRankingData(type, UgcNpcRankState.Total));
|
||||
tasks.Add(getUgcNpcRankingData(type, UgcNpcRankState.Trend));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.getLogger().error($"fail to reload ugc npc rank : {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Result> notifyClientUgcNpcRankRefresh(bool includeAnotherServer)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. Client 전송
|
||||
var client_message = new ClientToGame();
|
||||
client_message.Message = new ClientToGameMessage();
|
||||
client_message.Message.NtfUgcNpcRankRefresh = new();
|
||||
|
||||
result = await UgcNpcRankHelper.BroadcastToAllClients(client_message);
|
||||
|
||||
// 2. Server Noti
|
||||
if (!includeAnotherServer) return result;
|
||||
|
||||
var server_message = new ServerMessage();
|
||||
server_message.NtfUgcNpcRankRefresh = new();
|
||||
|
||||
result = await UgcNpcRankHelper.BroadcastToAllServers(server_message, true);
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
private async Task<Result> checkBaseUgcNpcRank()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. total / like
|
||||
result = await checkBaseUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. total / quest
|
||||
result = await checkBaseUgcNpcRank(UgcNpcRankState.Total, UgcNpcRankType.Quest);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 3. trend / like
|
||||
result = await checkBaseUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 4. trend / quest
|
||||
result = await checkBaseUgcNpcRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> checkBaseUgcNpcRank(UgcNpcRankState state, UgcNpcRankType type)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
|
||||
var organization_time = UgcNpcRankHelper.makeCurrentOrganizationDate();
|
||||
var rank_date = organization_time.ToString("yyyy-MM-dd");
|
||||
|
||||
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{state.ToString()}";
|
||||
var second_key = state == UgcNpcRankState.Trend ? $"{type.ToString()}#{rank_date}" : type.ToString();
|
||||
|
||||
// 1. data 조회
|
||||
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
|
||||
var (result, rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
|
||||
if (result.isSuccess() && null != rank_doc) return result;
|
||||
|
||||
// 2. 빈 데이터 생성
|
||||
rank_doc = state == UgcNpcRankState.Trend
|
||||
? new UgcNpcRankDoc(state, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds())
|
||||
: new UgcNpcRankDoc(state, type, null);
|
||||
|
||||
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(rank_doc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task onOrganizationUgcNpcRanking()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. 시작 설정
|
||||
var is_set_start = await m_rank_manage_cache_request.setStartUgcNpcRankManage();
|
||||
if (!is_set_start) return;
|
||||
|
||||
// 2. 시작 조건 체크
|
||||
var is_start = await checkStartCondition();
|
||||
if (false == is_start) return;
|
||||
|
||||
// 3. total rank 데이터 처리
|
||||
result = await copyToOrganization();
|
||||
if (result.isFail()) return;
|
||||
|
||||
// 4. rank 데이터 등록
|
||||
result = await registrationOrganizationRank();
|
||||
if (result.isFail())
|
||||
{
|
||||
var err_msg = $"fail to organize ugc npc rank!! [{result.toBasicString()}]";
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
|
||||
// 5. reload data
|
||||
await reloadAllUgcNpcRanks();
|
||||
|
||||
// 6. Client 노티
|
||||
_ = await notifyClientUgcNpcRankRefresh(true);
|
||||
}
|
||||
|
||||
private async Task<bool> checkStartCondition()
|
||||
{
|
||||
var key = "";
|
||||
var rank_date = UgcNpcRankHelper.getCurrentRankDate();
|
||||
var sub_key = rank_date.ToString("yyyy-MM-dd");
|
||||
|
||||
// 1. total key 존재 여부 체크
|
||||
key = $"total:{UgcNpcRankType.Like.ToString()}:{sub_key}";
|
||||
var is_exist = await m_rank_manage_cache_request.isExistKey(key);
|
||||
if (is_exist == false) return true;
|
||||
|
||||
key = $"total:{UgcNpcRankType.Quest.ToString()}:{sub_key}";
|
||||
is_exist = await m_rank_manage_cache_request.isExistKey(key);
|
||||
if (is_exist == false) return true;
|
||||
|
||||
// 2. trend key 존재 여부 체크
|
||||
key = $"trend:{UgcNpcRankType.Like.ToString()}:{sub_key}";
|
||||
is_exist = await m_rank_manage_cache_request.isExistKey(key);
|
||||
if (is_exist == false) return true;
|
||||
|
||||
key = $"trend:{UgcNpcRankType.Quest.ToString()}:{sub_key}";
|
||||
is_exist = await m_rank_manage_cache_request.isExistKey(key);
|
||||
if (is_exist == false) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<Result> copyToOrganization()
|
||||
{
|
||||
// 1. total like 정보 복사
|
||||
var result = await copyTotalToOrganization(UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. total Quest 정보 복사
|
||||
result = await copyTotalToOrganization(UgcNpcRankType.Quest);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 3. trend like doc 생성
|
||||
result = await createTodayTrendRankDoc(UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 4. trend quest doc 생성
|
||||
result = await createTodayTrendRankDoc(UgcNpcRankType.Quest);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> copyTotalToOrganization(UgcNpcRankType type)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
|
||||
var delete_rank_keys = new List<string>();
|
||||
var rank_date = UgcNpcRankHelper.getCurrentRankDate().ToString("yyyy-MM-dd");
|
||||
|
||||
// 1. 기존 정보가 있다면 ?? 패스
|
||||
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{UgcNpcRankState.Total.ToString()}";
|
||||
var second_key = $"{type.ToString()}#{rank_date}";
|
||||
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
|
||||
var (result, origin_total_rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
|
||||
if (null != origin_total_rank_doc) return result;
|
||||
|
||||
// 2. Total 정보 조회
|
||||
query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, type.ToString());
|
||||
(result, var total_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(total_doc, () => $"total_doc is null !!! - {getOwner()}");
|
||||
|
||||
var total_attrib = total_doc.getAttrib<UgcNpcRankAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(total_attrib, () => $"total_attrib is null !!! - {getOwner()}");
|
||||
|
||||
// 3. 랭킹 정보 생성
|
||||
var total_rank_doc = new UgcNpcRankDoc(UgcNpcRankState.Total, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds());
|
||||
var total_rank_attrib = total_rank_doc.getAttrib<UgcNpcRankAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(total_rank_attrib, () => $"total_rank_attrib is null !!! - {getOwner()}");
|
||||
|
||||
var ranks = new Dictionary<string, long>(total_attrib.ranks.Count);
|
||||
foreach (var rank in total_attrib.ranks)
|
||||
{
|
||||
if (rank.Value <= 0)
|
||||
{
|
||||
delete_rank_keys.Add(rank.Key);
|
||||
continue;
|
||||
}
|
||||
ranks.Add(rank.Key, rank.Value);
|
||||
}
|
||||
|
||||
// 4. 데이터 정렬
|
||||
total_rank_attrib.ranks = sortRanks(ranks, UgcNpcRankEntity.DefaultPageSize);
|
||||
|
||||
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(total_rank_doc);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 5. score:0 랭킹 정보 정리
|
||||
foreach (var delete_key in delete_rank_keys)
|
||||
{
|
||||
total_attrib.ranks.Remove(delete_key);
|
||||
}
|
||||
result = await dynamoDb_client.simpleUpdateDocumentWithDocType<UgcNpcRankDoc>(total_doc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> createTodayTrendRankDoc(UgcNpcRankType type)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
|
||||
var rank_date = UgcNpcRankHelper.makeCurrentOrganizationDate().ToString("yyyy-MM-dd");
|
||||
var rank_doc = new UgcNpcRankDoc(UgcNpcRankState.Trend, type, rank_date, UgcNpcRankHelper.getUgcNpcRankDocTtlSeconds());
|
||||
|
||||
result = await dynamoDb_client.simpleInsertDocumentWithDocType<UgcNpcRankDoc>(rank_doc);
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> registrationOrganizationRank()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// 1. total / like
|
||||
result = await registrationOrganizationRank(UgcNpcRankState.Total, UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. total / quest
|
||||
result = await registrationOrganizationRank(UgcNpcRankState.Total, UgcNpcRankType.Quest);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 3. trend / like
|
||||
result = await registrationOrganizationRank(UgcNpcRankState.Trend, UgcNpcRankType.Like);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 4. trend / quest
|
||||
result = await registrationOrganizationRank(UgcNpcRankState.Trend, UgcNpcRankType.Quest);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> registrationOrganizationRank(UgcNpcRankState state, UgcNpcRankType type)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
|
||||
var rank_date = UgcNpcRankHelper.getCurrentRankDate().ToString("yyyy-MM-dd");
|
||||
|
||||
var result = new Result();
|
||||
|
||||
// 1. dynamoDb Data 가져오기
|
||||
var primary_key = $"{UgcNpcRankDoc.getPrefixOfPK()}{state.ToString()}";
|
||||
var second_key = $"{type.ToString()}#{rank_date}";
|
||||
var query_config = dynamoDb_client.makeQueryConfigForReadByPKSK(primary_key, second_key);
|
||||
(result, var origin_rank_doc) = await dynamoDb_client.simpleQueryDocTypeWithQueryOperationConfig<UgcNpcRankDoc>(query_config);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(origin_rank_doc, () => $"origin_rank_doc is null !!! - {getOwner()}");
|
||||
|
||||
var rank_attrib = origin_rank_doc.getAttrib<UgcNpcRankAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(rank_attrib, () => $"rank_attrib is null !!! - {getOwner()}");
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case UgcNpcRankState.Total:
|
||||
result = await registrationOrganizationRankForTotalToRedis(rank_attrib, type);
|
||||
break;
|
||||
|
||||
case UgcNpcRankState.Trend:
|
||||
result = await registrationOrganizationRankForTrendToRedis(rank_attrib, type);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> registrationOrganizationRankForTotalToRedis(UgcNpcRankAttrib rankAttrib, UgcNpcRankType type)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var redis_client = server_logic.getRedisConnector();
|
||||
|
||||
var rank_request = new UgcNpcTotalRankCacheRequest(type, UgcNpcRankHelper.getCurrentRankDate(), redis_client);
|
||||
|
||||
// 1. rank 설정
|
||||
var result = await rank_request.initRankScore(rankAttrib.ranks);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. ttl 설정
|
||||
result = await rank_request.setTtl();
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<Result> registrationOrganizationRankForTrendToRedis(UgcNpcRankAttrib rankAttrib, UgcNpcRankType type)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var redis_client = server_logic.getRedisConnector();
|
||||
|
||||
var rank_request = new UgcNpcTrendRankCacheRequest(type, UgcNpcRankHelper.getCurrentRankDate(), redis_client);
|
||||
|
||||
// 1. rank 설정
|
||||
var result = await rank_request.initRankScore(rankAttrib.ranks);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
// 2. ttl 설정
|
||||
result = await rank_request.setTtl();
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task getUgcNpcRankingData(UgcNpcRankType type, UgcNpcRankState state)
|
||||
{
|
||||
var entity = getOwner() as UgcNpcRankEntity;
|
||||
NullReferenceCheckHelper.throwIfNull(entity, () => $"entity is null !!!");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case UgcNpcRankType.Like:
|
||||
var like_action = entity.getEntityAction<UgcNpcLikeRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(like_action, () => $"like_action is null !!!");
|
||||
|
||||
await like_action.loadRank(state);
|
||||
break;
|
||||
|
||||
case UgcNpcRankType.Quest:
|
||||
var quest_action = entity.getEntityAction<UgcNpcQuestRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!!");
|
||||
|
||||
await quest_action.loadRank(state);
|
||||
break;
|
||||
|
||||
case UgcNpcRankType.Communication:
|
||||
var communication_action = entity.getEntityAction<UgcNpcCommunicationRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(communication_action, () => $"communication_action is null !!!");
|
||||
|
||||
await communication_action.loadRank(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, long> sortRanks(Dictionary<string, long> ranks, int length)
|
||||
{
|
||||
var list = new Dictionary<string, long>(length);
|
||||
var sorted_ranks = ranks.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
var count = 0;
|
||||
foreach (var rank in sorted_ranks)
|
||||
{
|
||||
if (count >= length) break;
|
||||
list.Add(rank.Key, rank.Value);
|
||||
count++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private async Task onBusunessLogRefresh()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var log_invokers = new List<ILogInvoker>(1);
|
||||
var empty_business_refresh_with_log_actor = new EmptyBusinessWithLogActor();
|
||||
DailyRefreshBusinessLog log = new();
|
||||
log_invokers.Add(log);
|
||||
BusinessLogger.collectLogs(new LogActionEx(LogActionType.TestBusinessLog), empty_business_refresh_with_log_actor, log_invokers);
|
||||
Log.getLogger().info("EmptyBusinessLog write");
|
||||
}
|
||||
}
|
||||
31
GameServer/Entity/Ranking/Helper/UgcNpcRankCheat.cs
Normal file
31
GameServer/Entity/Ranking/Helper/UgcNpcRankCheat.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using ServerCommon;
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
[ChatCommandAttribute("ugcnpcrank", typeof(ChatCommandGetUgcNpcRank), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
|
||||
public class ChatCommandGetUgcNpcRank : ChatCommandBase
|
||||
{
|
||||
public override async Task invoke(Player player, string token, string[] args)
|
||||
{
|
||||
Log.getLogger().info($"ChatCommandGetUgcNpcRank");
|
||||
|
||||
if (args.Length < 2) return;
|
||||
|
||||
var message = new ClientToGame();
|
||||
message.Request = new ClientToGameReq();
|
||||
message.Request.ReqUgcNpcRank = new();
|
||||
|
||||
if(! EnumHelper.tryParse<UgcNpcRankType>(args[0], out var type)) return;
|
||||
if (!EnumHelper.tryParse<UgcNpcRankState>(args[1], out var state)) return;
|
||||
|
||||
message.Request.ReqUgcNpcRank.Type = type;
|
||||
message.Request.ReqUgcNpcRank.State = state;
|
||||
|
||||
var result = await GameServerApp.getServerLogic().onCallProtocolHandler(player, message);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"fail to run ChatCommandGetUgcNpcRank!! : {result.toBasicString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
231
GameServer/Entity/Ranking/Helper/UgcNpcRankHelper.cs
Normal file
231
GameServer/Entity/Ranking/Helper/UgcNpcRankHelper.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
using Nettention.Proud;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
using DYNAMO_DB_TABLE_FULL_NAME = System.String;
|
||||
using Guid = System.Guid;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcRankHelper
|
||||
{
|
||||
public const string RankKeySplit = "_";
|
||||
|
||||
public static string makeRankKey(string ownerGuid, string ugcNpcMetaGuid) => $"{ownerGuid}{RankKeySplit}{ugcNpcMetaGuid}";
|
||||
|
||||
public static DateTime getCurrentRankDate()
|
||||
{
|
||||
return makeCurrentOrganizationDate().AddDays(-1);
|
||||
}
|
||||
|
||||
public static DateTime makeCurrentOrganizationDate()
|
||||
{
|
||||
var current_time = DateTimeHelper.Current;
|
||||
var compare_current = Convert.ToDateTime(current_time.ToString("HH:mm:ss"));
|
||||
var organizationTime = MetaHelper.GameConfigMeta.NpcRankingCalculateTime;
|
||||
|
||||
var check_time = compare_current < organizationTime ? current_time.AddDays(-1) : current_time;
|
||||
|
||||
var organization = new DateTime(check_time.Year, check_time.Month, check_time.Day, organizationTime.Hour,
|
||||
organizationTime.Minute, organizationTime.Second, DateTimeKind.Utc);
|
||||
|
||||
return organization;
|
||||
}
|
||||
|
||||
public static Int64 getUgcNpcRankDocTtlSeconds(DateTime? startDate = null)
|
||||
{
|
||||
var current = DateTimeHelper.Current;
|
||||
var delta_period = 0;
|
||||
|
||||
if (null != startDate)
|
||||
{
|
||||
if (startDate > current) startDate = current;
|
||||
|
||||
var current_time = new DateTime(current.Year, current.Month, current.Day);
|
||||
var delta = current_time - startDate;
|
||||
|
||||
delta_period = (int)delta.Value.TotalSeconds;
|
||||
}
|
||||
|
||||
// retention period 는 Hour 단위임
|
||||
var retention_period = MetaHelper.GameConfigMeta.NpcRankingRetentionPeriod;
|
||||
return retention_period * 60 * 60 - delta_period;
|
||||
}
|
||||
|
||||
public static (string ownerGuid, string ugcNpcMetaGuid) getDetailRankKey(string key)
|
||||
{
|
||||
var split = key.Split(RankKeySplit);
|
||||
if (split.Length < 2) return (string.Empty, string.Empty);
|
||||
|
||||
return (split[0], split[1]);
|
||||
}
|
||||
|
||||
public static async Task<List<UgcNpcRank>> getUgcNpcSummaryFromMetaGuid(List<(string guid, long score)> ranks)
|
||||
{
|
||||
var list = new List<UgcNpcRank>(ranks.Count);
|
||||
|
||||
var ranking = 1;
|
||||
|
||||
foreach (var rank in ranks)
|
||||
{
|
||||
var guids = UgcNpcRankHelper.getDetailRankKey(rank.guid);
|
||||
var ugc_npc_attrib = await getUgcNpcFromMetaGuid(guids.ownerGuid, guids.ugcNpcMetaGuid);
|
||||
if (ugc_npc_attrib == null) continue;
|
||||
|
||||
list.Add(await makeUgcNpcAttribToUgcNpcRank(ugc_npc_attrib, ranking, rank.score));
|
||||
ranking++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static async Task<Result> BroadcastToAllClients(ClientToGame message)
|
||||
{
|
||||
var target_clients = new List<HostID>();
|
||||
var users = GameServerApp.getServerLogic().getPlayerManager().getUsers();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
target_clients.Add(user.Value.getHostId());
|
||||
}
|
||||
|
||||
GameServerApp.getServerLogic().onSendPacketToHosts(target_clients.ToArray(), RmiContext.ReliableSend, message);
|
||||
|
||||
return await Task.FromResult(new Result());
|
||||
}
|
||||
|
||||
public static async Task<Result> BroadcastToAllServers(ServerMessage message, bool except_me)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var rabbit_mq = server_logic.getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
|
||||
(var result, var server_infos) = await server_logic.getServerInfoAll();
|
||||
foreach (var server in server_infos)
|
||||
{
|
||||
if (except_me && server.Name == server_logic.getServerName()) continue;
|
||||
rabbit_mq.SendMessage(server.Name, message);
|
||||
}
|
||||
|
||||
return await Task.FromResult(new Result());
|
||||
}
|
||||
|
||||
private static async Task<UgcNpcAttrib?> getUgcNpcFromMetaGuid(string ownerGuid, string ugcNpcMetaGuid)
|
||||
{
|
||||
var dynamo_db_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
||||
|
||||
// ugcNpcMeta 정보 획득
|
||||
var ugc_npc_doc = new UgcNpcDoc(OwnerEntityType.User, ownerGuid, ugcNpcMetaGuid);
|
||||
var ugc_npc_query_config = dynamo_db_client.makeQueryConfigForReadByPKSK(ugc_npc_doc.getPK(), ugc_npc_doc.getSK());
|
||||
var (result, docs) = await dynamo_db_client.simpleQueryDocTypesWithQueryOperationConfig<UgcNpcDoc>(ugc_npc_query_config);
|
||||
if (result.isFail() || docs.Count <= 0)
|
||||
{
|
||||
var err_msg = $"Failed to find UgcNpc. OwnerGuid: {ownerGuid} / NpcGuid : {ugcNpcMetaGuid}";
|
||||
result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return docs[0].getAttrib<UgcNpcAttrib>();
|
||||
}
|
||||
|
||||
private static async Task<UgcNpcRank> makeUgcNpcAttribToUgcNpcRank(UgcNpcAttrib docAttrib, int ranking, long score)
|
||||
{
|
||||
var rank = new UgcNpcRank();
|
||||
|
||||
rank.Rank = ranking;
|
||||
rank.Score = (int)score;
|
||||
rank.Title = docAttrib.Title;
|
||||
rank.NpcNickname = docAttrib.Nickname;
|
||||
rank.UgcNpcMetaGuid = docAttrib.UgcNpcMetaGuid;
|
||||
rank.OwnerUserGuid = docAttrib.OwnerGuid;
|
||||
rank.BodyItemMetaId = (int)docAttrib.BodyItemMetaId;
|
||||
|
||||
var (result, nickname_doc_attrib) = await NicknameDoc.findNicknameFromGuid(rank.OwnerUserGuid);
|
||||
if (result.isFail() || nickname_doc_attrib == null) rank.OwnerUserNickname = string.Empty;
|
||||
else rank.OwnerUserNickname = nickname_doc_attrib.Nickname;
|
||||
|
||||
return rank;
|
||||
}
|
||||
|
||||
public static async Task<Result> updateUgcNpcRank(UgcNpcRankState state, UgcNpcRankType type, string guid, int delta, DateTime? rankDate)
|
||||
{
|
||||
var dynamo_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
||||
|
||||
var rank_date = rankDate?.ToString("yyyy-MM-dd");
|
||||
var doc = new UgcNpcRankDoc(state, type, rank_date);
|
||||
var primary_key = doc.getPrimaryKey();
|
||||
primary_key.fillUpPrimaryKey(doc.getPK(), doc.getSK());
|
||||
|
||||
// data 변경
|
||||
var update = makeUpdateItemRequestForUgcNpcRank( dynamo_client
|
||||
, primary_key.toKeyWithAttributeValue(), nameof(UgcNpcRankAttrib.ranks), guid, delta);
|
||||
NullReferenceCheckHelper.throwIfNull(update, () => $"update is null !!!");
|
||||
var request = update.Item2;
|
||||
NullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!!");
|
||||
|
||||
var (result, _) = await dynamo_client.simpleQueryDocTypesWithUpdateItemRequest<UgcNpcRankDoc>(request, Guid.NewGuid().ToString("N"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static (Result, UpdateItemRequest?) makeUpdateItemRequestForUgcNpcRank( DynamoDbClient dbClient
|
||||
, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
|
||||
, string targetAttribName
|
||||
, string guid
|
||||
, double deltaCount )
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var table = dbClient.getTableByName(ServerBase.DynamoDbDefine.TableNames.Main);
|
||||
|
||||
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(table.TableName);
|
||||
query_builder.withKeys(attributeValueWithPrimaryKey);
|
||||
|
||||
var target_doc = new UgcNpcRankDoc();
|
||||
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
|
||||
var target_key = JsonHelper.getJsonPropertyName<UgcNpcRankAttrib>(targetAttribName);
|
||||
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
|
||||
|
||||
if (false == is_success)
|
||||
{
|
||||
var err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var attributeNames = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key);
|
||||
attributeNames.Add($"#{guid}", guid);
|
||||
query_builder.withExpressionAttributeNames(attributeNames);
|
||||
|
||||
attribute_expression += $".#{guid}";
|
||||
var update_expression = (deltaCount >= 0)
|
||||
? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
|
||||
: $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
|
||||
|
||||
query_builder.withUpdateExpression(update_expression);
|
||||
|
||||
var expression_attribute_values = new Dictionary<string, AttributeValue>
|
||||
{
|
||||
{ ":changeValue", new AttributeValue { N = Math.Abs(deltaCount).ToString() } },
|
||||
{ ":start", new AttributeValue { N = "0" } }
|
||||
};
|
||||
query_builder.withExpressionAttributeValues(expression_attribute_values);
|
||||
|
||||
query_builder.withReturnValues(ReturnValue.ALL_NEW);
|
||||
|
||||
return query_builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler;
|
||||
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_UGC_NPC_RANK), typeof(GetUgcNpcRankPacketHandler), typeof(GameLoginListener))]
|
||||
public class GetUgcNpcRankPacketHandler : PacketRecvHandler
|
||||
{
|
||||
public static bool send_GS2C_ACK_UGC_NPC_RANK(Player owner, Result result, UgcNpcRankType rankType, UgcNpcRankState rankState, List<UgcNpcRank>? ranking)
|
||||
{
|
||||
var ack_packet = new ClientToGame();
|
||||
ack_packet.Response = new ClientToGameRes();
|
||||
|
||||
ack_packet.Response.ErrorCode = result.ErrorCode;
|
||||
ack_packet.Response.AckUgcNpcRank = new();
|
||||
|
||||
|
||||
if (result.isSuccess())
|
||||
{
|
||||
ack_packet.Response.AckUgcNpcRank.Type = rankType;
|
||||
ack_packet.Response.AckUgcNpcRank.State = rankState;
|
||||
|
||||
ranking ??= new List<UgcNpcRank>();
|
||||
ack_packet.Response.AckUgcNpcRank.UgcNpcRank.AddRange(ranking);
|
||||
}
|
||||
|
||||
if (false == GameServerApp.getServerLogic().onSendPacket(owner, ack_packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
var player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
// 1. 기본 정보 체크
|
||||
var request = (recvMessage as ClientToGame)?.Request.ReqUgcNpcRank;
|
||||
if (null == request)
|
||||
{
|
||||
err_msg = $"Failed to get Request !!! : {nameof(ClientToGame.Request.ReqUgcNpcRank)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_GS2C_ACK_UGC_NPC_RANK(player,result, UgcNpcRankType.None, UgcNpcRankState.None, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
var ranking_entity = server_logic.findGlobalEntity<UgcNpcRankEntity>();
|
||||
if (null == ranking_entity)
|
||||
{
|
||||
err_msg = $"Failed to get Request !!! : {nameof(ClientToGame.Request.ReqUgcNpcRank)}";
|
||||
result.setFail(ServerErrorCode.UgcNpcRankEntityIsNotFound, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_GS2C_ACK_UGC_NPC_RANK(player,result, request.Type, request.State, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. request validation 체크
|
||||
if (false == checkRequestValidation(request))
|
||||
{
|
||||
err_msg = $"Failed to get Request !!! : {nameof(ClientToGame.Request.ReqUgcNpcRank)}";
|
||||
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
send_GS2C_ACK_UGC_NPC_RANK(player,result, request.Type, request.State, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. ranking data 조회
|
||||
(Result result, List<UgcNpcRank>? ranks) res_rank = new();
|
||||
res_rank.result = result;
|
||||
|
||||
switch (request.Type)
|
||||
{
|
||||
case UgcNpcRankType.Like:
|
||||
var like_action = ranking_entity.getEntityAction<UgcNpcLikeRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(like_action, () => $"UgcNpcLikeRankAction is null !!! - player:{player.toBasicString()}");
|
||||
|
||||
res_rank = await like_action.getRanks(request.State);
|
||||
break;
|
||||
case UgcNpcRankType.Communication:
|
||||
var communication_action = ranking_entity.getEntityAction<UgcNpcCommunicationRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(communication_action, () => $"UgcNpcCommunicationRankAction is null !!! - player:{player.toBasicString()}");
|
||||
|
||||
res_rank = await communication_action.getRanks(request.State);
|
||||
break;
|
||||
case UgcNpcRankType.Quest:
|
||||
var quest_action = ranking_entity.getEntityAction<UgcNpcQuestRankAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(quest_action, () => $"UgcNpcQuestRankAction is null !!! - player:{player.toBasicString()}");
|
||||
|
||||
res_rank = await quest_action.getRanks(request.State);
|
||||
break;
|
||||
}
|
||||
|
||||
send_GS2C_ACK_UGC_NPC_RANK(player, res_rank.result, request.Type, request.State, res_rank.ranks);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool checkRequestValidation(ClientToGameReq.Types.C2GS_REQ_UGC_NPC_RANK request)
|
||||
{
|
||||
// 1. state 체크
|
||||
if (request.State == UgcNpcRankState.None) return false;
|
||||
|
||||
// 2. type 체크
|
||||
if (request.Type == UgcNpcRankType.None) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class NotifyUgcNpcRankRefreshHandler
|
||||
{
|
||||
public async Task recvUgcNpcRankRefresh(ServerMessage.Types.GS2GS_NTF_UGC_NPC_RANK_REFRESH notify)
|
||||
{
|
||||
var ugc_npc_rank_entity = GameServerApp.getServerLogic().findGlobalEntity<UgcNpcRankEntity>();
|
||||
NullReferenceCheckHelper.throwIfNull(ugc_npc_rank_entity, () => $"ugc_npc_rank_entity is null !!!");
|
||||
var action = ugc_npc_rank_entity.getEntityAction<UgcNpcRankManageAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(ugc_npc_rank_entity, () => $"ugc_npc_rank_entity is null !!!");
|
||||
NullReferenceCheckHelper.throwIfNull(action, () => $"action is null !!!");
|
||||
|
||||
// reload data
|
||||
await action.reloadAllUgcNpcRanks();
|
||||
|
||||
// notify to client
|
||||
await action.notifyClientUgcNpcRankRefresh(false);
|
||||
}
|
||||
}
|
||||
49
GameServer/Entity/Ranking/UgcNpcRankEntity.cs
Normal file
49
GameServer/Entity/Ranking/UgcNpcRankEntity.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class UgcNpcRankEntity : EntityBase
|
||||
{
|
||||
public const int DefaultPageNum = 0;
|
||||
public const int DefaultPageSize = 100;
|
||||
|
||||
public UgcNpcRankEntity() : base(EntityType.UgcNpcRank)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
// attribute
|
||||
addEntityAttribute(new UgcNpcLikeRankAttribute(this));
|
||||
addEntityAttribute(new UgcNpcCommunicationRankAttribute(this));
|
||||
addEntityAttribute(new UgcNpcQuestRankAttribute(this));
|
||||
|
||||
// action
|
||||
addEntityAction(new UgcNpcLikeRankAction(this));
|
||||
addEntityAction(new UgcNpcCommunicationRankAction(this));
|
||||
addEntityAction(new UgcNpcQuestRankAction(this));
|
||||
addEntityAction(new UgcNpcRankManageAction(this));
|
||||
|
||||
return await Task.FromResult(new Result());
|
||||
}
|
||||
|
||||
public override string toBasicString()
|
||||
{
|
||||
return $"{this.getTypeName()}";
|
||||
}
|
||||
|
||||
public override string toSummaryString()
|
||||
{
|
||||
return $"{this.getTypeName()}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user