using Amazon.DynamoDBv2.Model; using GameServer.Contents.GameMode.Helper; using GameServer.Contents.GameMode.Manage.StateManage; using NeoSmart.AsyncLock; using ServerBase; using ServerCommon; using ServerCore; namespace GameServer.Contents.GameMode.Manage.PlayManage; public abstract class GameModeBase : EntityBase, IGameMode, IWithLogActor { protected bool m_is_init_completed = false; protected InstanceRoom m_instance_room; public readonly IHostMigrator m_host_migrator; protected EntityTicker? m_ticker; protected Int32 m_ticker_interval_msecs = GameModeConstants.GAME_MODE_DEFAULT_INTERVAL_MSECS; protected IGameModeState? m_current_game_mode_state; //kihoon todo: 이거 수정해야된다. IGameMode를 받으면 안될듯...아니면 받더래도 public GameModeBase(EntityType type, InstanceRoom instanceRoom) : base(type) { m_is_init_completed = false; m_instance_room = instanceRoom; ArgumentNullReferenceCheckHelper.throwIfNull(instanceRoom, () => $"GameModeBase constructor instanceRoom is null !!!"); m_host_migrator = HostMigrationFactory.createCommonHostMigrator(1, GameServerApp.getServerLogic()); //kihoon todo : gamemodeID를 넘겨야 한다; } public override async Task onInit() { var result = new Result(); //action 추가 addEntityActions(); //GameModeBase 쪽 로직 더 넣을것 있으면 여기에 result = await base.onInit(); if (result.isFail()) return result; //init이 다 되면 ticker 만든다. result = await createTask(); if (result.isFail()) return result; //타이머 생성후 초기해야될 것이 있으면 한다. await initAfterTimerCreate(); m_is_init_completed = true; return result; } public void addEntityActions() { } public string getRoomId() { return m_instance_room.getMap().m_room_id; } private async Task createTask() { var result = new Result(); m_ticker = createTaskTicker(); NullReferenceCheckHelper.throwIfNull(m_ticker, () => $"m_ticker is null !!! - id"); await m_ticker.onInit(); await Task.CompletedTask; return result; } public EntityTicker createTaskTicker() //나중에 모드별로 별도 정의 필요하면 그때 virtual로 { var ticker = new GameModeLifeCycleTicker(this, m_ticker_interval_msecs, gameModeTaskTick); return ticker; } private async Task gameModeTaskTick() { if (!m_is_init_completed) return; try { await taskUpdate(); } catch(Exception e) { Log.getLogger().error($"Exception !!!, new gameModeTaskTick() : exception:{e}, basicString : {toBasicString()}"); } } public abstract Task taskUpdate(); public abstract Task initAfterTimerCreate(); public override string toBasicString() { var basic_string = base.toBasicString() + $"GameModeBase.... room_id : {getRoomId()}"; return basic_string; } public bool isLoadCompleted() { return m_is_init_completed; } public IGameModeState getGameModeState() { NullReferenceCheckHelper.throwIfNull(m_current_game_mode_state, () => $"m_current_game_mode_state is null !!"); return m_current_game_mode_state; } public void setGameModeState(IGameModeState state) { m_current_game_mode_state = state; } public InstanceRoom getInstanceRoom() => m_instance_room; public EntityTicker? getEntityTicker() => m_ticker; public ILogActor toLogActor() { var server_logic = GameServerApp.getServerLogic(); var region_id = server_logic.getServerConfig().getRegionId(); var server_name = server_logic.getServerName(); var log_info = new BattleInstanceActorLog(region_id, server_name, getRoomId(), m_instance_room.getInstanceId()); return log_info; } }