326 lines
11 KiB
C#
326 lines
11 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using ServerCore;
|
|
using MODULE_ID = System.UInt32;
|
|
using ServerMetricsHelper = ServerBase.ServerMetricsHelper;
|
|
|
|
namespace MatchServer;
|
|
|
|
public class MatchServerLogic : ServerLogicBase, IWithPacketNamespaceVerifier, IWithConfiguration,
|
|
IWithServerMetrics, IWithLogActor
|
|
{
|
|
const string PacketNamespace = "MatchServer.PacketHandler";
|
|
private readonly string _serverConfigPath = "./";
|
|
public Action? OnServerStart { get; set; }
|
|
|
|
public MatchServerLogic(ServerConfig config) : base(config)
|
|
{
|
|
}
|
|
|
|
public MatchServerLogic(ServerConfig config, string serverConfigPath) : base(config)
|
|
{
|
|
_serverConfigPath = serverConfigPath;
|
|
}
|
|
|
|
public Result mergeConfiguration(IConfiguration configuration)
|
|
{
|
|
var result = new Result();
|
|
var key_options = configuration;
|
|
|
|
var port = ushort.Parse(key_options["port"] ?? "0");
|
|
var config_file = key_options["config"];
|
|
|
|
var server_config = getServerConfig();
|
|
|
|
server_config.setAppParamPort(port);
|
|
server_config.setConfigFilePath($"{_serverConfigPath + ServerConfig.ConfigDirectory + "/" + config_file}");
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
protected override string onGetDumpFilename()
|
|
{
|
|
return getServerName() + "_" + getServerConfig().getAppParamPort();
|
|
}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var businesslog_refresh_date = MetaHelper.GameConfigMeta.BusinessLogRefreshTime;
|
|
DailyTimeEventManager.Instance.tryAddTask("MatchBusinessLogRefresh", businesslog_refresh_date, onBusinessLogRefresh);
|
|
|
|
result = await base.onInit();
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to onInit() !!! : {result.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// 비즈니스 로그가 일일 아카이빙 되도록 강제로 매일 로그를 남긴다.
|
|
private async Task onBusinessLogRefresh()
|
|
{
|
|
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("Match EmptyBusinessLog write");
|
|
}
|
|
|
|
protected override Result onCreateServerName()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var server_type_name = getServerType();
|
|
var server_type = server_type_name.toServerType();
|
|
if (false == server_type.isValidServerType())
|
|
{
|
|
err_msg = $"ServerType invalid !!! : {server_type.ToString()}";
|
|
result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg);
|
|
return result;
|
|
}
|
|
|
|
var server_config = getServerConfig();
|
|
var listen_port = server_config.toClientListenPort();
|
|
// if (listen_port <= 0)
|
|
// {
|
|
// err_msg = $"Client listen port invalid !!! : appParamPort:{listen_port}, configListenPort:{server_config.ClientListenPort} - {server_type.ToString()}";
|
|
// result.setFail(ServerErrorCode.ClientListenPortInvalid, err_msg);
|
|
// return result;
|
|
// }
|
|
//
|
|
base.setServerName(server_type.toServerName(server_config.toClientListenIP(), listen_port, 0, 0));
|
|
|
|
return result;
|
|
}
|
|
|
|
protected override Result onLoadMetaDatas()
|
|
{
|
|
return ServerCommon.ServerLogicHelper.loadMetaDatas(this);
|
|
}
|
|
|
|
protected override async Task<Result> onRegisterModuleAll()
|
|
{
|
|
var result = new Result();
|
|
|
|
var config = getServerConfig();
|
|
var load_config_info = config.getLoadedConfig();
|
|
NullReferenceCheckHelper.throwIfNull(load_config_info,
|
|
() => $"load_config_info is null !!! - {toBasicString()}");
|
|
|
|
{
|
|
result = await tryCreateAndRegisterModule(() =>
|
|
{
|
|
var config_param = new DynamoDbClient.ConfigParam();
|
|
result = config_param.tryReadFromJsonOrDefault(load_config_info);
|
|
if (result.isFail())
|
|
{
|
|
return (null, result);
|
|
}
|
|
|
|
var module_context = new ModuleContext((MODULE_ID)ModuleId.DynamoDbConnector
|
|
, 0, 0, config_param);
|
|
var created_module = new DynamoDbClient(module_context);
|
|
return (created_module, result);
|
|
});
|
|
}
|
|
{
|
|
result = await tryCreateAndRegisterModule(() =>
|
|
{
|
|
var config_param = new RedisConnector.ConfigParam();
|
|
result = config_param.tryReadFromJsonOrDefault(load_config_info);
|
|
if (result.isFail())
|
|
{
|
|
return (null, result);
|
|
}
|
|
|
|
var module_context = new ModuleContext((MODULE_ID)ModuleId.RedisConnector
|
|
, 0, 0, config_param);
|
|
var created_module = new RedisConnector(module_context);
|
|
return (created_module, result);
|
|
});
|
|
}
|
|
{
|
|
result = await tryCreateAndRegisterModule(() =>
|
|
{
|
|
var found_redis_connector = getModule<RedisConnector>((MODULE_ID)ModuleId.RedisConnector);
|
|
if (null == found_redis_connector)
|
|
{
|
|
return (
|
|
null
|
|
, new Result() { ErrorCode = ServerErrorCode.ModuleNotFound, ResultString = $"RedisConnector not found !!! : moduleId:{ModuleId.RedisConnector}" }
|
|
);
|
|
}
|
|
|
|
var config_param = new RedisWithLuaScriptExecutor.ConfigParam();
|
|
result = config_param.tryReadFromJsonOrDefault(load_config_info);
|
|
if (result.isFail())
|
|
{
|
|
return (null, result);
|
|
}
|
|
|
|
var module_context = new ModuleContext((MODULE_ID)ModuleId.RedisWithLuaScriptExecutor
|
|
, 0, 0, config_param);
|
|
var created_module = new RedisWithLuaScriptExecutor(found_redis_connector, module_context);
|
|
|
|
return (created_module, result);
|
|
});
|
|
}
|
|
{
|
|
result = await tryCreateAndRegisterModule(() =>
|
|
{
|
|
var config_param = new RabbitMqConnector.ConfigParam();
|
|
result = config_param.tryReadFromJsonOrDefault(load_config_info);
|
|
if (result.isFail())
|
|
{
|
|
return (null, result);
|
|
}
|
|
|
|
config_param.ServiceName = getServerName();
|
|
|
|
var module_context = new ModuleContext((MODULE_ID)ModuleId.RabbitMqConnector
|
|
, 0, 0, config_param);
|
|
var created_module = new RabbitMq4Match(module_context);
|
|
config_param.fnServerMessageRecvFromConsumer = created_module.onRecvProtocol;
|
|
|
|
return (created_module, result);
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public override async Task<Result> onCreateTickerAll()
|
|
{
|
|
var result = new Result();
|
|
|
|
result = await this.createTimeEventForMinuteTicker();
|
|
if (result.isFail())
|
|
{
|
|
Log.getLogger()
|
|
.error(
|
|
$"Failed to createTimeEventForMinuteTicker() !!! : {result.toBasicString()} - {toBasicString()}");
|
|
return result;
|
|
}
|
|
|
|
var world_id = 0;
|
|
result = await onInitServerKeyToCache(world_id);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public bool isValidPacketNamespace(string? toCheckNamespace, IPacketCommand packetCommand)
|
|
{
|
|
if (null != toCheckNamespace && true == toCheckNamespace.Contains(PacketNamespace))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Log.getLogger().error(
|
|
$"Invalid MatchServer PacketNamespace !!!, not included Namespace : {PacketNamespace} ⊆ {toCheckNamespace}, packetCommnad:{packetCommand.toBasicString()}");
|
|
return false;
|
|
}
|
|
|
|
public async Task<Result> setupServerMetrics()
|
|
{
|
|
var result =
|
|
await ServerMetricsHelper.setupDefaultServerMetrics<RedisConnector>(this,
|
|
(MODULE_ID)ModuleId.RedisConnector);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected override async Task<Result> onStartServer()
|
|
{
|
|
var result = await base.onStartServer();
|
|
OnServerStart?.Invoke();
|
|
return result;
|
|
}
|
|
|
|
public bool isSetupCompleted()
|
|
{
|
|
return ServerMetricsHelper.isSetupCompleted(this);
|
|
}
|
|
|
|
public ServerMetricsCacheRequest getServerMetricsCacheRequest()
|
|
{
|
|
return ServerBase.ServerMetricsHelper.getServerMetricsCacheRequest(this);
|
|
}
|
|
|
|
public override async Task onTaskServerInfoSyncTick()
|
|
{
|
|
var result = await syncServerInfoToCache();
|
|
if (result.isFail())
|
|
{
|
|
Log.getLogger()
|
|
.error($"Failed to syncServerInfoToCache() !!! : {result.toBasicString()} - {toBasicString()}");
|
|
}
|
|
}
|
|
|
|
public async Task<Result> syncServerInfoToCache()
|
|
{
|
|
var result = new Result();
|
|
var server_name = getServerName();
|
|
var server_config = getServerConfig();
|
|
var listen_ip = server_config.toClientListenIP();
|
|
var listen_port = server_config.toClientListenPort();
|
|
// TODO: 카운트 정보 처리
|
|
var user_count = 0;
|
|
var max_user_count = 0;
|
|
var reservation_count = 0;
|
|
var ugc_npc_count = 0;
|
|
var return_count = 0;
|
|
var aws_instance_id = getInstanceId();
|
|
|
|
result = await ServerBase.ServerMetricsHelper.syncServerInfoToCache(this
|
|
, server_name
|
|
, listen_ip, listen_port
|
|
, user_count, max_user_count
|
|
, reservation_count, return_count
|
|
, ugc_npc_count
|
|
, aws_instance_id);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public ILogActor toLogActor()
|
|
{
|
|
var log_info = new LogicActorLog();
|
|
log_info.initLogInfo(
|
|
this.getServerConfig().getRegionId()
|
|
, this.getServerConfig().getWorldId()
|
|
, this.getServerType().toServerType()
|
|
, this.getServerName()
|
|
);
|
|
return log_info;
|
|
}
|
|
|
|
public int getWorldId() => 0;
|
|
public int getChannelNo() => 0;
|
|
}
|