초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View 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()}");
}
}
}

View 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();
}
}