Files
caliverse_server/GameServer/Room/InstanceRoom.cs
2025-05-01 07:23:28 +09:00

846 lines
33 KiB
C#

using System.Collections.Concurrent;
using Google.Protobuf.WellKnownTypes;
using Nettention.Proud;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using USER_GUID = System.String;
namespace GameServer;
public partial class InstanceRoom
{
CancellationTokenSource _cts = new CancellationTokenSource();
ConcurrentDictionary<string, Player> m_players = new();
//object memberLock = new object();
readonly string _roomId;
readonly int _instanceId;
Map _map = new();
EPlaceType _placeType;
ContentsType _contentsType;
bool _isFullMemberStart = false;
bool _concertStart = false;
bool _concertEnd = false;
DateTime _concertStartTime;
DateTime _concertEndTime;
int _concertLength;
int _startBuffID = 0;
int _concertEnterItemId = 0;
int _concertEnterItemCount = 0;
bool _isPartyInstance = false;
string _partyGuid = string.Empty;
int _screenPageNo = 0;
public bool isDestroy { get; private set; }
public int SessionCount { get { return m_players.Count; } }
public int Capacity { get; private set; }
public InstanceRoom(string roomId, int instanceId)
{
_roomId = roomId;
_instanceId = instanceId;
}
public async Task<bool> Init()
{
Log.getLogger().info($"InstanceRoom.Init() Start !!! - instanceRoomId:{_roomId}, InstanceMetaId:{_instanceId}");
var result = new Result();
var err_msg = string.Empty;
var server_logic = GameServerApp.getServerLogic();
if (MetaData.Instance._IndunTable.TryGetValue(_instanceId, out var instanceMetaData) == false)
{
Log.getLogger().error($"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{_instanceId} - instanceRoomId:{_roomId}");
return false;
}
if (instanceMetaData.RoomFile.isNullOrWhiteSpace())
{
Log.getLogger().error($"Not Exist InstanceMetaData.RoomFile : instanceMetaId:{_instanceId} - instanceRoomId:{_roomId}");
return false;
}
_contentsType = instanceMetaData.ContentsType;
_placeType = instanceMetaData.placeType();
Capacity = instanceMetaData.LimitCount;
if (_placeType == EPlaceType.MyHome)
{
result = MyhomeHelper.getMyhomeOwnerUserGuidAndMyhomeGuidFromRoomId(_roomId, out var myhomeOwnerUserGuid, out var myhomeGuid);
if (result.isFail())
{
err_msg = $"Failed to getMyhomeOwnerUserGuidAndMyhomeGuidFromRoomId() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return false;
}
(result, var myhome_attrib) = await MyhomeHelper.getEnterMyhomeAttribFromDynamoDb(myhomeOwnerUserGuid, myhomeGuid);
if (result.isFail() || null == myhome_attrib)
{
err_msg = $"Failed to getEnterMyhomeAttribFromDynamoDb() !!! : {result.toBasicString()} - instanceRoomId:{_roomId}";
Log.getLogger().error(err_msg);
return false;
}
(result, var myhome_ugc_info) = await MyhomeHelper.getMyhomeUgcInfo(myhome_attrib);
if (result.isFail() || null == myhome_ugc_info)
{
err_msg = $"Failed to getMyhomeUgcInfo() !!! : {result.toBasicString()} - instanceRoomId:{_roomId}";
Log.getLogger().error(err_msg);
return false;
}
await _map.onInitFromMyhomeUgc(myhome_attrib.MyhomeGuid, myhome_ugc_info, _roomId);
}
else
{
await _map.onInit(instanceMetaData.RoomFile, _roomId, true);
if (true == InstanceRoomHandler.isOnlyOneInstanceRoomID(_roomId))
{
var result_farming = await FarmingHelper.tryFinalyzeUncompletedFarmingByMap(_map);
if (result_farming.isFail())
{
err_msg = $"Fail to tryFinalyzeUncompletedFarmingByMap() !!! : {_map.toBasicString()}, {result_farming.toBasicString()}";
Log.getLogger().error(err_msg);
}
}
}
if (_placeType == EPlaceType.Concert)
{
if (MetaData.Instance._ConcertTable.TryGetValue(instanceMetaData.MapId, out var concertInfo) == false)
{
Log.getLogger().error($"Failed to MetaData.TryGetValue() !!! : concertMetaId:{instanceMetaData.MapId} - instanceRoomId:{_roomId}");
return false;
}
_startBuffID = concertInfo.BuffID;
_concertEnterItemId = concertInfo.DeleteItem;
_concertEnterItemCount = concertInfo.DeleteItemCount;
_concertLength = concertInfo.ConcertLength;
if (concertInfo.StartRequiredType == "InstanceTimeTarget")
{
_isFullMemberStart = true;
_concertStartTime = DateTime.UtcNow.AddSeconds(concertInfo.ITRequiredDetail);
_concertEndTime = _concertStartTime.AddSeconds(_concertLength);
}
else if (concertInfo.StartRequiredType == "RealTimeTarget")
{
_concertStartTime = concertInfo.RTRequiredDetail.UtcDateTime;
_concertEndTime = _concertStartTime.AddSeconds(_concertLength);
}
var roomIdElemnet = _roomId.Split(":");
if (roomIdElemnet[0] == ServerCommon.Constant.PREFIX_PARTY_INSTANCE_ROOM_ID)
{
var party = server_logic.findGlobalEntity<GlobalParty>()?.getParty(roomIdElemnet[1]);
var party_instance_action = party?.getEntityAction<GlobalPartyDetailInstanceAction>();
if (null == party_instance_action || false == party_instance_action.isExist())
{
Log.getLogger().error($"Not Exist partyInstanceAction !!! - instanceRoomId:{_roomId}");
return false;
}
_isPartyInstance = true;
_partyGuid = roomIdElemnet[1];
Capacity = MetaHelper.GameConfigMeta.MaxPartyMembers;
_concertStartTime = party_instance_action.getStartTime().ToDateTime();
_concertEndTime = _concertStartTime.AddSeconds(_concertLength);
}
// instance 정보 추가 등록
var instance_room_storage = new InstanceRoomStorage();
instance_room_storage.Init(server_logic.getRedisDb(), "");
result = await instance_room_storage.setInstanceRoomExtraInfo(_roomId, _placeType, _concertStartTime);
if (result.isFail())
{
Log.getLogger().error($"Failed to setInstanceRoomExtraInfo() !!! : {result.toBasicString()} - instanceRoomId:{_roomId}");
return false;
}
}
if (_placeType == EPlaceType.Movie)
{
if (MetaData.Instance._ConcertTable.TryGetValue(instanceMetaData.MapId, out var concertInfo) == false)
{
Log.getLogger().error($"Failed to MetaData.TryGetValue() !!! : concertMetaId:{instanceMetaData.MapId} - instanceRoomId:{_roomId}");
return false;
}
_startBuffID = concertInfo.BuffID;
}
//GameMode
(var gamemode_init_result, var gamemode_init_handler) = GameModeHelper.getGameModeInitHandler(this, 1, _roomId);
if (gamemode_init_result.isSuccess())
{
var gamemode_validation_result = gamemode_init_handler.gamedModeInstanceInitValidate();
if (gamemode_validation_result.isFail()) return false;
var init_result = await gamemode_init_handler.gamedModeInstanceInit();
if (init_result.isFail())
{
Log.getLogger().error($"battleInstanceInit error roomId : {_roomId}");
return false;
}
}
Log.getLogger().info($"InstanceRoom.Init() Finish !!! - instanceRoomId:{_roomId}, InstanceMetaId:{_instanceId}");
return true;
}
public bool Join(Player player)
{
var user_guid = player.getUserGuid();
Log.getLogger().info($"InstanceRoom.Join() Start !!! - userGuid:{user_guid}, instanceRoomId:{_roomId}, sessionCount:{SessionCount}");
int memberCount = 0;
{
m_players.AddOrUpdate(user_guid, player, (key, oldValue) => player);
memberCount = SessionCount;
}
var location_attribute = player.getEntityAttribute<LocationAttribute>();
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!! - {player.toBasicString()}");
location_attribute.CurrentIndunLocation.InstanceRoomId = _roomId;
location_attribute.CurrentIndunLocation.InstanceMetaId = _instanceId;
location_attribute.EnterIndunLocation.clear();
var game_zone_action = player.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}");
var result = game_zone_action.tryEnterGameZone(_map);
if (result.isFail())
{
return false;
}
if (memberCount == 1)
{
_cts.Dispose();
// TODO: 위치수정 필요
_cts = new CancellationTokenSource();
_ = LogicThread.Factory.StartNew(() => KeepAlive(_cts.Token),
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
if (_placeType == EPlaceType.Concert)
{
_ = LogicThread.Factory.StartNew(() => CheckConcertTime(_cts.Token),
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
//_ = LogicThread.Factory.StartNew(() => CheckSession(_cts.Token),
// CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
//GameMode
(var get_mode_result, var gamemode_join_handler) = GameModeHelper.getGameModeJoinHandler(this, 1, _roomId);
if (get_mode_result.isFail()) return true; //fail 이면 gamemode 인스턴스가 아니므로 그냥 정상 리턴 처리
if (get_mode_result.isSuccess())
{
get_mode_result = gamemode_join_handler.gamedModeInstanceJoinValidate();
if (get_mode_result.isSuccess())
{
//successs 면 gamemod join 설정
var join_result = gamemode_join_handler.gamedModeInstanceJoin(player);
if (join_result.isFail())
{
Log.getLogger().error($"gamedModeInstanceJoin error!!! _placeType : {_placeType}, roomId : {_roomId}, player : {player.toBasicString()}");
return false;
}
}
}
Log.getLogger().info($"{player.getUserGuid()} JoinInstanceRoom {_roomId}");
// LogActionType.StageConcertStart 로그 작성은 인스턴룸이 실제로 시작 상태로 전환될 때 작성한다. 추후 LogActionType.StageConcertEnd 도 정의해야 한다.
//List<ILogInvoker> invokers = new List<ILogInvoker>();
//var stage_log_info = StageBusinessLogHelper.toStageLogInfo(_instanceId, _contentsType, _roomId, SessionCount, Capacity);
//invokers.Add(new StageLog(LogActionType.StageConcertStart, stage_log_info));
//BusinessLogger.collectLogs(LogActionType.StageEnter, session._selectedChar.LastPositionInfo.m_last_stage_exit_tran_guid, session._selectedChar, invokers);
//var invokers = new List<ILogInvoker>();
//var log_action = new LogAction(LogActionType.StageEnter, player._selectedChar.LastPositionInfo.m_last_stage_exit_tran_guid);
//var stage_log_info = StageBusinessLogHelper.toStageLogInfo(_instanceId, _contentsType, _roomId, SessionCount, Capacity);
//invokers.Add(new StageLog(stage_log_info));
//BusinessLogger.collectLogs(log_action, player._selectedChar, invokers);
Log.getLogger().info($"InstanceRoom.Join() Finish !!! - userGuid:{user_guid}, instanceRoomId:{_roomId}, sessionCount:{SessionCount}");
return true;
}
public async Task SendJoinSuccess(Player player)
{
// 입장 성공 패킷
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Response = new ClientToGameRes();
clientToGame.Response.ErrorCode = ServerErrorCode.Success;
clientToGame.Response.JoinInstanceRoomRes = new ClientToGameRes.Types.JoinInstanceRoomRes();
clientToGame.Response.JoinInstanceRoomRes.MeetingRoom = new MeetingRoomInfo();
clientToGame.Response.JoinInstanceRoomRes.MeetingRoom.ScreenPageNo = _screenPageNo;
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
player.send_S2C_NTF_SET_LOCATION();
}
// 기존 맴버 정보 패킷
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.InstanceRoomMember = new ClientToGameMessage.Types.InstanceRoomMember();
var instanceRoomMembers = m_players.Values.Where(s => s.getUserGuid() != player.getUserGuid()).Select(s => s.getUserGuid());
clientToGame.Message.InstanceRoomMember.MemberGuid.Add(instanceRoomMembers);
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
}
// 입장 맴버 정보 패킷
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.JoinInstanceRoomMember = new ClientToGameMessage.Types.JoinInstanceRoomMember();
clientToGame.Message.JoinInstanceRoomMember.MemberGuid = player.getUserGuid();
BroadcastExcept(clientToGame, player);
}
// Concert 정보
if (_placeType == EPlaceType.Concert)
{
if (!_concertStart)
{
// 콘서트 정보 패킷
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.ConcertInfo = new ClientToGameMessage.Types.ConcertInfo();
clientToGame.Message.ConcertInfo.StartTime = _concertStartTime.ToTimestamp();
clientToGame.Message.ConcertInfo.RemainingSeat = Capacity - SessionCount;
Broadcast(clientToGame);
}
if (_isFullMemberStart)
{
if (SessionCount == Capacity)
{
_concertStart = true;
_concertStartTime = DateTime.UtcNow.AddSeconds(5);
_concertEndTime = _concertStartTime.AddSeconds(_concertLength);
// 콘서트 시작 패킷
await SendConcertStartPacket();
}
}
}
else // 콘서트 시작 후 입장
{
// 콘서트 시작 패킷
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.ConcertStart = new ClientToGameMessage.Types.ConcertStart();
clientToGame.Message.ConcertStart.StartTime = _concertStartTime.ToTimestamp();
clientToGame.Message.ConcertStart.EndTime = _concertEndTime.ToTimestamp();
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
}
}
if (_isPartyInstance)
{
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(_partyGuid);
var party_instance_action = party?.getEntityAction<GlobalPartyDetailInstanceAction>();
NullReferenceCheckHelper.throwIfNull(party_instance_action, () => $"GlobalPartyDetailInstanceAction is null !!! - party:{party?.toBasicString()}");
if (true == party_instance_action.isExist())
{
await party_instance_action.changePartyInstance(_concertStartTime.ToTimestamp(),
_concertEndTime.ToTimestamp(), m_players.Count, false, true);
}
}
if (_startBuffID != 0)
{
var buff_action = player.getEntityAction<BuffAction>();
NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {player.toBasicString()}");
var (result, add_buff_attribute, del_buff_attribute) = buff_action.AddBuffProcess((uint)_startBuffID);
BuffNotifyHelper.send_S2C_NTF_DELETE_BUFF(player, del_buff_attribute);
BuffNotifyHelper.send_S2C_NTF_START_BUFF(player, add_buff_attribute);
}
//GameMode
(var handler_result, var gamemode_join_success_handler) = GameModeHelper.getGameModeJoinSuccessHandler(player, this, 1, _roomId);
if (handler_result.isFail() || gamemode_join_success_handler == null) return;
await gamemode_join_success_handler.joinSuccess();
}
async Task SendConcertStartPacket()
{
var result = new Result();
var err_msg = string.Empty;
var server_logic = GameServerApp.getServerLogic();
foreach (var player in m_players.Values)
{
var fn_transaction_runner = async delegate ()
{
var result = new Result();
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.ConcertStart = new ClientToGameMessage.Types.ConcertStart();
//List<ILogInvoker> invokers = new List<ILogInvoker>();
//var log_action = new LogAction(LogActionType.StageConcertStart);
if (_concertEnterItemId != 0 && _concertEnterItemCount != 0)
{
var inventory_action = player.getEntityAction<InventoryActionBase>();
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {player.toBasicString()}");
(result, var deleted_items) = await inventory_action.tryDeleteItemByMetaId((uint)_concertEnterItemId, (ushort)_concertEnterItemCount);
if (result.isFail())
{
return result;
}
foreach (var deleted_item in deleted_items)
{
var deleted_item_attribute = deleted_item.getEntityAttribute<ItemAttributeBase>();
NullReferenceCheckHelper.throwIfNull(deleted_item_attribute, () => $"deleted_item_attribute is null !!! - {player.toBasicString()}");
ItemGuidCount item = new();
item.ItemGuid = deleted_item_attribute.ItemGuid;
item.ItemCount = deleted_item_attribute.ItemStackCount;
clientToGame.Message.ConcertStart.Items.Add(item);
}
//invokers.Add(new BusinessLogInvoker.ItemLog(itemlogData));
}
clientToGame.Message.ConcertStart.StartTime = _concertStartTime.ToTimestamp();
clientToGame.Message.ConcertStart.EndTime = _concertEndTime.ToTimestamp();
await QuestManager.It.QuestCheckWithoutTransaction(player, new QuestConcert(EQuestEventTargetType.CONCERT, EQuestEventNameType.STARTED, _instanceId));
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.None, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
err_msg = $"Failed to sendQueryAndBusinessLog() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
//var stage_log_info = StageBusinessLogHelper.toStageLogInfo(_instanceId, ContentsType.Concert, _roomId, SessionCount, Capacity);
//invokers.Add(new StageLog(stage_log_info));
//BusinessLogger.collectLogs(log_action, player._selectedChar, invokers);
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "ItemDelete", fn_transaction_runner);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
}
}
public async Task Leave(Player player, bool disconnected)
{
var user_guid = player.getUserGuid();
Log.getLogger().info($"InstanceRoom.Leave() Start !!! - userGuid:{user_guid}, instanceRoomId:{_roomId}, sessionCount:{SessionCount}, addConnectedUser:{getMap().getCurrCountAsAddConnectedUser()}");
if (m_players.TryRemove(player.getUserGuid(), out _))
{
await InstanceRoomHandler.leaveInstanceRoom(user_guid, _roomId);
}
var location_attribute = player.getEntityAttribute<LocationAttribute>();
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"LocationAttribute is null !!! - player:{player.toBasicString()}");
location_attribute.CurrentIndunLocation.clear();
var game_zone_action = player.getEntityAction<GameZoneAction>();
await game_zone_action.tryLeaveGameZone();
if (SessionCount + getMap().getCurrCountAsAddConnectedUser() == 0)
{
if (!_isPartyInstance || _concertEnd)
{
await destroyRoom();
}
}
else
{
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.LeaveInstanceRoomMember = new ClientToGameMessage.Types.LeaveInstanceRoomMember();
clientToGame.Message.LeaveInstanceRoomMember.MemberGuid = player.getUserGuid();
Broadcast(clientToGame);
}
if (_placeType == EPlaceType.Concert)
{
if (!_concertStart)
{
// 콘서트 정보 패킷
{
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.ConcertInfo = new ClientToGameMessage.Types.ConcertInfo();
clientToGame.Message.ConcertInfo.StartTime = _concertStartTime.ToTimestamp();
clientToGame.Message.ConcertInfo.RemainingSeat = Capacity - SessionCount;
Broadcast(clientToGame);
}
}
}
}
if (_isPartyInstance)
{
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(_partyGuid);
var party_instance_action = party?.getEntityAction<GlobalPartyDetailInstanceAction>();
if (true == party_instance_action?.isExist())
{
NullReferenceCheckHelper.throwIfNull(party, () => $"GlobalPartyDetail is null !!! - partyGuid:{_partyGuid}");
var log_invokers = new List<ILogInvoker>(2);
if (SessionCount == 0 && _concertEnd)
{
// party Instance Business Log 기록
var party_instance_log_data = PartyBusinessLogHelper.toPartyInstanceLogData(party.PartyGuid, false);
var party_instance_business_log = new PartyInstanceBusinessLog(party_instance_log_data);
log_invokers.Add(party_instance_business_log);
await party_instance_action.finishPartyInstance();
}
else
{
await party_instance_action.changeJoinMemberCount(m_players.Count, true);
// party Instance Business Log 기록
var party_instance_log_data = PartyBusinessLogHelper.toPartyInstanceLogData(party.PartyGuid, false);
var party_instance_business_log = new PartyInstanceBusinessLog(party_instance_log_data);
log_invokers.Add(party_instance_business_log);
}
// party member Business Log 기록
var party_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party.PartyGuid, player.getUserGuid(), PartyMemberActionType.PartyInstanceLeave);
var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data);
log_invokers.Add(party_member_business_log);
BusinessLogger.collectLogs(new LogActionEx(LogActionType.LeavePartyInstance), player, log_invokers);
}
}
Log.getLogger().info($"InstanceRoom.Leave() Finish !!! - userGuid:{user_guid}, instanceRoomId:{_roomId}, sessionCount:{SessionCount}, addConnectedUser:{getMap().getCurrCountAsAddConnectedUser()}");
}
public async Task<ServerErrorCode> ExchangeMyHome(string myhomeGuid, MyHomeInfo myhomeInfo, string roomId)
{
Map new_myhome_map = new();
await new_myhome_map.onInitFromMyhomeUgc(myhomeGuid, myhomeInfo.MyhomeUgcInfo, roomId);
foreach (var player in m_players.Values)
{
var game_zone_action = player.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}");
await game_zone_action.tryLeaveGameZone();
MyhomeNotifyHelper.send_S2C_NTF_MYHOME_UGC_INFO(player, myhomeInfo);
game_zone_action.tryEnterGameZone(new_myhome_map);
}
_map = new_myhome_map;
return ServerErrorCode.Success;
}
public ServerErrorCode MyhomeHostEnterEditRoom(string exceptUserGuid)
{
foreach (var player in m_players.Values)
{
if (player.getUserGuid() == exceptUserGuid)
continue;
MyhomeNotifyHelper.send_GS2C_NTF_MYHOME_HOST_ENTER_EDIT_ROOM(player);
}
return ServerErrorCode.Success;
}
public ServerErrorCode ExchangeCraft(string anchorGuid, Timestamp finish_craft_time)
{
foreach (var player in m_players.Values)
{
var game_zone_action = player.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}");
var ntf_packet = CraftNotifyHelper.makeNtfCraftUpdatePacket(anchorGuid, finish_craft_time);
GameServerApp.getServerLogic().onSendPacket(player, ntf_packet);
}
return ServerErrorCode.Success;
}
async Task SendConcertEnd()
{
isDestroy = true;
if (_isPartyInstance)
{
var party = GameServerApp.getServerLogic().findGlobalEntity<GlobalParty>()?.getParty(_partyGuid);
var party_instance_action = party?.getEntityAction<GlobalPartyDetailInstanceAction>();
NullReferenceCheckHelper.throwIfNull(party_instance_action, () => $"party instance action is null !!! - party:{party?.toBasicString()}");
if (true == party_instance_action.isExist())
{
await party_instance_action.finishPartyInstance(m_players.Count);
}
}
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.NtfConcertEnd = new ClientToGameMessage.Types.GS2C_NTF_CONCERT_END();
Broadcast(clientToGame);
}
public int changeScreenPage(bool isCustom, bool isNext, int customPage)
{
if (isCustom)
{
_screenPageNo = customPage;
return _screenPageNo;
}
_screenPageNo = isNext ? _screenPageNo + 1 : _screenPageNo - 1;
if (_screenPageNo <= 0) _screenPageNo = 0;
return _screenPageNo;
}
public void Broadcast(ClientToGame message)
{
HostID[] allClients = m_players.Values.Select(s => s.getHostId()).ToArray();
GameServerApp.getServerLogic().onSendPacketToHosts(allClients, ServerCore.ProudNetHelper.compressRmi(), message);
}
public void BroadcastExcept(ClientToGame message, Player player)
{
HostID[] allClients = m_players.Values.Where(s => s.getUserGuid() != player.getUserGuid()).Select(s => s.getHostId()).ToArray();
GameServerApp.getServerLogic().onSendPacketToHosts(allClients, ServerCore.ProudNetHelper.compressRmi(), message);
}
public void BroadcastExcept(ClientToGame message, USER_GUID userGuid)
{
HostID[] allClients = m_players.Values.Where(s => s.getUserGuid() != userGuid).Select(s => s.getHostId()).ToArray();
GameServerApp.getServerLogic().onSendPacketToHosts(allClients, ServerCore.ProudNetHelper.compressRmi(), message);
}
public async Task KeepAlive(CancellationToken cancelToken)
{
var server_logic = GameServerApp.getServerLogic();
var instance_room_storage = new InstanceRoomStorage();
instance_room_storage.Init(server_logic.getRedisDb(), "");
while (cancelToken.IsCancellationRequested == false)
{
try
{
await Task.Delay(ServerCommon.Constant.KEEP_INSTANCE_ROOM_TIME, cancelToken);
await instance_room_storage.keepInstanceRoom(_roomId);
if (!InstanceRoomHandler.isOnlyOneInstanceRoomID(_roomId))
{
var instance_room_id_base = InstanceRoomHandler.getInstanceRoomIdBaseFromInstanceRoomId(_roomId);
await instance_room_storage.keepInstanceRoomList(instance_room_id_base);
}
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
Log.getLogger().error($"{ex}");
throw;
}
}
}
public async Task CheckConcertTime(CancellationToken cancelToken)
{
while (cancelToken.IsCancellationRequested == false)
{
try
{
if (_concertStartTime < DateTime.UtcNow && !_concertStart)
{
_concertStart = true;
await SendConcertStartPacket();
}
if (_concertEndTime < DateTime.UtcNow && !_concertEnd)
{
_concertEnd = true;
await SendConcertEnd();
}
if (_concertEnd && SessionCount == 0)
{
await destroyRoom();
InstanceRoomManager.Instance.DestroyRoom(_roomId);
}
await Task.Delay(1000, cancelToken);
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
Log.getLogger().error($"{ex}");
throw;
}
}
}
public Map getMap()
{
return _map;
}
public int getInstanceId()
{
return _instanceId;
}
public async Task destroyRoom()
{
isDestroy = true;
_cts.Cancel();
_map.DestroyP2PGroup();
_map.getCancellationToken().Cancel();
await InstanceRoomHandler.deleteInstanceRoom(_roomId);
Log.getLogger().info($"InstanceRoom.destroyRoom() Complete !!! - instanceRoomId:{_roomId}");
}
//public async Task CheckSession(CancellationToken cancelToken)
//{
// List<Player> errorPlayer = new();
// while (cancelToken.IsCancellationRequested == false || SessionCount == 0)
// {
// try
// {
// foreach (var (key, player) in m_players)
// {
// if (player.IsClosedProcessed)
// {
// Log.getLogger().error($"{player.getUserGuid()} Closed Session in InstanceRoom");
// errorPlayer.Add(player);
// continue;
// }
// }
// foreach (var player in errorPlayer)
// {
// if (!await InstanceRoomManager.Instance.LeaveRoom(player, _roomId))
// await Leave(player);
// }
// errorPlayer.Clear();
// await Task.Delay(1000, cancelToken);
// }
// catch (OperationCanceledException)
// {
// break;
// }
// catch (Exception ex)
// {
// Log.getLogger().error($"{ex}");
// throw;
// }
// }
//}
}