231 lines
9.4 KiB
C#
231 lines
9.4 KiB
C#
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();
|
|
}
|
|
} |