초기커밋
This commit is contained in:
239
GameServer/Contents/GameMode/Helper/HostMigrationFactory.cs
Normal file
239
GameServer/Contents/GameMode/Helper/HostMigrationFactory.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
using Nettention.Proud;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
|
||||
public class HostMigrationFactory
|
||||
{
|
||||
public static IHostMigrator createCommonHostMigrator(int battleModeId, GameServerLogic gameServerLogic)
|
||||
{
|
||||
// battleModeId <- 게임 모드 ID 테이블 참조용
|
||||
// TODO: battleModeId를 사용하여 HostMigrationPolicy 생성하는 것으로 변경 예정
|
||||
int game_mode_option_data_id = 1;
|
||||
var host_migration_policy = createHostMigrationPolicyByMeta(game_mode_option_data_id);
|
||||
|
||||
var net_server = gameServerLogic.getProudNetListener().getNetServer();
|
||||
NullReferenceCheckHelper.throwIfNull(net_server, () => $"net_server is null !!!!");
|
||||
var host_migration_system = new HostMigrationSystem(net_server, host_migration_policy);
|
||||
var host_migrator = new CommonHostMigrator(host_migration_system, gameServerLogic);
|
||||
return host_migrator;
|
||||
}
|
||||
|
||||
private static HostMigrationPolicy createHostMigrationPolicyByMeta(int gameModeOptionDataId)
|
||||
{
|
||||
var meta = getMeta(gameModeOptionDataId);
|
||||
return new HostMigrationPolicy
|
||||
{
|
||||
HostKickFpsThreshold = meta.HostKickFpsThreshold,
|
||||
HostKickFpsDuration = TimeSpan.FromSeconds(meta.HostKickFpsDuration),
|
||||
HostKickPingThreshold = meta.HostKickPingThreshold,
|
||||
HostKickPingDuration = TimeSpan.FromSeconds(meta.HostKickPingDuration),
|
||||
};
|
||||
|
||||
GameModeOptionMetaData getMeta(int gameModeOptionDataId)
|
||||
{
|
||||
var game_mode_option_meta_table = MetaData.Instance.Meta.GameModeOptionMetaTable;
|
||||
game_mode_option_meta_table.GameModeOptionDataListbyGameModeOptionId.TryGetValue(gameModeOptionDataId,
|
||||
out var game_mode_option_meta);
|
||||
NullReferenceCheckHelper.throwIfNull(game_mode_option_meta, () => $"game_mode_option_meta is null !!!!");
|
||||
return game_mode_option_meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CommonHostMigrator : IHostMigrator
|
||||
{
|
||||
private readonly HostMigrationSystem m_host_migration_system;
|
||||
private string m_host_user_guid = string.Empty;
|
||||
private readonly GameServerLogic m_game_server_logic;
|
||||
private DateTime m_last_loop_time = DateTime.MinValue;
|
||||
private readonly TimeSpan m_loop_interval = TimeSpan.FromSeconds(1);
|
||||
|
||||
public HostID SuperPeerHostId => m_host_migration_system.SuperPeerHostId;
|
||||
public HostMigrationSystem HostMigrationSystem => m_host_migration_system;
|
||||
|
||||
public CommonHostMigrator(HostMigrationSystem hostMigrationSystem, GameServerLogic gameServerLogic)
|
||||
{
|
||||
m_host_migration_system = hostMigrationSystem;
|
||||
m_game_server_logic = gameServerLogic;
|
||||
}
|
||||
|
||||
public (Result, bool) migrateCheck(bool ignoreInterval = false)
|
||||
{
|
||||
if (!ignoreInterval && isOnMigrationLoopInterval())
|
||||
{
|
||||
return (new Result(), false);
|
||||
}
|
||||
|
||||
var (is_migrated, new_super_peer_id) = m_host_migration_system.migrateCheck();
|
||||
if (is_migrated)
|
||||
{
|
||||
var (result, user_guid) = getUserGuidByHostId(new_super_peer_id);
|
||||
if (result.isFail())
|
||||
{
|
||||
return (result, is_migrated);
|
||||
}
|
||||
|
||||
var host_change_success = m_host_migration_system.changeSuperPeerHostId(new_super_peer_id);
|
||||
if (!host_change_success)
|
||||
{
|
||||
return (new Result
|
||||
{
|
||||
ErrorCode = ServerErrorCode.NotFoundUser, ResultString = "Failed to change super peer."
|
||||
}, is_migrated);
|
||||
}
|
||||
m_host_user_guid = user_guid;
|
||||
return (result, is_migrated);
|
||||
}
|
||||
return (new Result(), false);
|
||||
}
|
||||
|
||||
public void setGroupHostId(HostID groupId)
|
||||
{
|
||||
m_host_migration_system.setGroupHostId(groupId);
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
// 삭제 예정
|
||||
//=================================================================
|
||||
public Result defineHost(HostID p2pGroupId = HostID.HostID_None, SuperPeerSelectionPolicy policy = null!, HostID[] excludes = null!)
|
||||
{
|
||||
// m_host_migration_system.setGroupHostId(p2pGroupId);
|
||||
//
|
||||
// var (is_migrated, new_super_peer_id) = m_host_migration_system.migrateCheck();
|
||||
//
|
||||
// if (is_migrated)
|
||||
// {
|
||||
// var (result, user_guid) = getUserGuidByHostId(new_super_peer_id);
|
||||
// if (result.isFail())
|
||||
// {
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// var host_change_success = m_host_migration_system.changeSuperPeerHostId(new_super_peer_id);
|
||||
// if (!host_change_success)
|
||||
// {
|
||||
// return new Result
|
||||
// {
|
||||
// ErrorCode = ServerErrorCode.NotFoundUser, ResultString = "Failed to change super peer."
|
||||
// };
|
||||
// }
|
||||
// m_host_user_guid = user_guid;
|
||||
// return result;
|
||||
// }
|
||||
return new Result();
|
||||
}
|
||||
|
||||
public Result modifyHost(string userGuid)
|
||||
{
|
||||
var (result, host_id) = getHostIdByUserGuid(userGuid);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (m_host_migration_system.changeSuperPeerHostId(host_id))
|
||||
{
|
||||
m_host_user_guid = userGuid;
|
||||
return result;
|
||||
}
|
||||
|
||||
return new Result { ErrorCode = ServerErrorCode.NotFoundUser, ResultString = "Failed to change super peer." };
|
||||
}
|
||||
|
||||
public Result removeHost()
|
||||
{
|
||||
m_host_migration_system.changeSuperPeerHostId(HostID.HostID_None);
|
||||
m_host_user_guid = string.Empty;
|
||||
return new Result();
|
||||
}
|
||||
|
||||
public string getHostUserGuid()
|
||||
{
|
||||
return m_host_user_guid;
|
||||
}
|
||||
|
||||
private (Result, string) getUserGuidByHostId(HostID hostId)
|
||||
{
|
||||
string err_msg;
|
||||
var result = new Result();
|
||||
if (hostId == HostID.HostID_None)
|
||||
{
|
||||
err_msg = $"there is not suitable super peer !!!! host_id : {hostId}";
|
||||
result.setFail(ServerErrorCode.NotFoundUser, err_msg);
|
||||
return (result, string.Empty);
|
||||
}
|
||||
|
||||
var session = m_game_server_logic.getProudNetListener().onLookupEntityWithSession((int)hostId);
|
||||
if (session is null)
|
||||
{
|
||||
err_msg = $"session is null!!!! host_id : {hostId}";
|
||||
result.setFail(ServerErrorCode.NotFoundUser, err_msg);
|
||||
return (result, string.Empty);
|
||||
}
|
||||
|
||||
var player = session as Player;
|
||||
if (player is null)
|
||||
{
|
||||
err_msg = $"player is null!!!! host_id : {hostId}";
|
||||
result.setFail(ServerErrorCode.NotFoundUser, err_msg);
|
||||
return (result, string.Empty);
|
||||
}
|
||||
|
||||
return (result, player.getUserGuid());
|
||||
}
|
||||
|
||||
private (Result, HostID) getHostIdByUserGuid(string userGuid)
|
||||
{
|
||||
string err_msg;
|
||||
var result = new Result();
|
||||
// todo: 임시 다른 방법 모색 - 비용이 비쌀 수 있음
|
||||
var session_pair = m_game_server_logic.getProudNetListener()
|
||||
.getEntityWithSessions()
|
||||
.FirstOrDefault(x => x.Value.getUserGuid() == userGuid);
|
||||
var session = session_pair.Value;
|
||||
if (session is null)
|
||||
{
|
||||
err_msg = $"session is null!!!! user_guid : {userGuid}";
|
||||
result.setFail(ServerErrorCode.NotFoundUser, err_msg);
|
||||
return (result, HostID.HostID_None);
|
||||
}
|
||||
|
||||
if (session is not Player player)
|
||||
{
|
||||
err_msg = $"player is null!!!! user_guid : {userGuid}";
|
||||
result.setFail(ServerErrorCode.NotFoundUser, err_msg);
|
||||
return (result, HostID.HostID_None);
|
||||
}
|
||||
|
||||
return (result, player.getHostId());
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
// 호스트 마이그레이션 루프 인터벌 중인지 여부
|
||||
//=================================================================
|
||||
private bool isOnMigrationLoopInterval()
|
||||
{
|
||||
if (m_last_loop_time == DateTime.MinValue)
|
||||
{
|
||||
m_last_loop_time = DateTime.UtcNow;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_last_loop_time.Add(m_loop_interval) < DateTime.UtcNow)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m_last_loop_time = DateTime.UtcNow;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user