271 lines
9.3 KiB
C#
271 lines
9.3 KiB
C#
|
|
using System.Collections.Concurrent;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class InstanceRoomManager
|
|
{
|
|
private static readonly InstanceRoomManager _instance = new InstanceRoomManager();
|
|
static InstanceRoomManager() { }
|
|
private InstanceRoomManager() { }
|
|
public static InstanceRoomManager Instance { get { return _instance; } }
|
|
|
|
ConcurrentDictionary<string, InstanceRoom> m_instance_rooms = new();
|
|
|
|
/// <summary>
|
|
/// 현재 생성된 모든 인스턴스룸들의 최대 인원수의 합
|
|
/// </summary>
|
|
public int Capacity { get { return _capacity; } }
|
|
int _capacity = 0;
|
|
|
|
/// <summary>
|
|
/// 인스턴스룸 입장<br/>
|
|
/// 입장 성공 후 <see cref="SendJoinRoomSuccess"/> 사용하여 클라로 패킷 전송
|
|
/// </summary>
|
|
/// <param name="player">인스턴스룸에 입장할 세션</param>
|
|
/// <param name="roomId">입장할 인스턴스룸 아이디</param>
|
|
/// <param name="instanceId">입장할 인스턴스룸의 인스턴스 아이디, 없는 경우 0</param>
|
|
/// <param name="joinedRoom">입장 성공 시 입장한 방, 실패 시 <see langword="null"/></param>
|
|
/// <returns><see langword="true"/> 입장 성공, <see langword="false"/> 입장 실패</returns>
|
|
public async Task<InstanceRoom?> JoinRoom(Player player, string roomId, int instanceId)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
room = new InstanceRoom(roomId, instanceId);
|
|
if (false == await room.Init())
|
|
{
|
|
Log.getLogger().error($"Failed to InstanceRoom.init() !!! - instanceRoomId:{roomId}, {player.toBasicString()}");
|
|
return null;
|
|
}
|
|
|
|
if (false == m_instance_rooms.TryAdd(roomId, room))
|
|
{
|
|
if (!m_instance_rooms.TryGetValue(roomId, out room))
|
|
{
|
|
Log.getLogger().error($"Failed to Add & Get InstanceRoom !!! - instanceRoomId:{roomId}, {player.toBasicString()}");
|
|
return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Interlocked.Add(ref _capacity, room.Capacity);
|
|
NamedPipeMonitor.SetCurrentCapacity(_capacity);
|
|
ServerBase.Monitor.It.incRoomCounter();
|
|
}
|
|
}
|
|
|
|
if (room.Join(player) == false)
|
|
{
|
|
Log.getLogger().error($"Failed to InstanceRoom.Join() !!! - instanceRoomId:{roomId}, {player.toBasicString()}");
|
|
return null;
|
|
}
|
|
|
|
return room;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 인스턴스룸 입장 관련 패킷 보내기<br/>
|
|
/// <see cref="JoinRoom"/> 성공 후 사용해야 함
|
|
/// </summary>
|
|
/// <param name="player">인스턴스룸에 입장 성공한 세션</param>
|
|
/// <param name="roomId">입장 성공한 인스턴스룸 아이디</param>
|
|
/// <returns>방이 존재하지 않을 경우 <see langword="false"/>, 그 외 <see langword="true"/></returns>
|
|
public async Task<bool> SendJoinRoomSuccess(Player player, string roomId)
|
|
{
|
|
if (!m_instance_rooms.TryGetValue(roomId, out var room))
|
|
{
|
|
Log.getLogger().error($"Failed to Get InstanceRoom !!! - instanceRoomId:{roomId}");
|
|
return false;
|
|
}
|
|
|
|
await room.SendJoinSuccess(player);
|
|
|
|
return true;
|
|
}
|
|
|
|
public async Task<bool> LeaveRoom(Player player, string roomId, bool disconnected = false)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
Log.getLogger().error($"Failed to Get InstanceRoom !!! - instanceRoomId:{roomId}");
|
|
return false;
|
|
}
|
|
|
|
await room.Leave(player, disconnected);
|
|
|
|
if (room.isDestroy)
|
|
{
|
|
DestroyRoom(roomId);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void DestroyRoom(string roomId)
|
|
{
|
|
if (!m_instance_rooms.TryRemove(roomId, out var room))
|
|
{
|
|
if (m_instance_rooms.ContainsKey(roomId))
|
|
{
|
|
Log.getLogger().fatal("Failed to Remove InstanceRoom !!! - instanceRoomId:{roomId}");
|
|
return;
|
|
}
|
|
|
|
Log.getLogger().info($"InstanceRoomManager.DestroyRoom() Not Exist !!! - instanceRoomId:{roomId}");
|
|
return;
|
|
}
|
|
|
|
Interlocked.Add(ref _capacity, -room.Capacity);
|
|
NamedPipeMonitor.SetCurrentCapacity(_capacity);
|
|
ServerBase.Monitor.It.decRoomCounter();
|
|
|
|
Log.getLogger().info($"InstanceRoomManager.DestroyRoom() Complete !!! - instanceRoomId:{roomId}");
|
|
}
|
|
|
|
public int getRoomCapacity(string roomId)
|
|
{
|
|
if (!m_instance_rooms.TryGetValue(roomId, out var room))
|
|
{
|
|
Log.getLogger().error($"InstanceRoomManager.getRoomCapacity() Not Exist !!! - instanceRoomId:{roomId}");
|
|
return 0;
|
|
}
|
|
|
|
return room.Capacity;
|
|
}
|
|
|
|
/*public async Task KickMyHomeNotiToFriendCauseHostLeave(ClientSession mySession, string instanceRoomId)
|
|
{
|
|
//내방이 아니면 리턴
|
|
if (!instanceRoomId.Contains(mySession.Id)) return;
|
|
|
|
Log.getLogger().debug($"KickMyHomeNotiToFriendCauseHostLeave Called Id : {mySession.Id}");
|
|
|
|
//실제 인던에 멤버로 있는 id리스트 조회 자기는 제외
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var instance_room_storage = new InstanceRoomStorage();
|
|
instance_room_storage.Init(server_logic.getRedisDb(), "");
|
|
|
|
List<string> roomMemberList = await instance_room_storage.GetInstanceRoomMemberList(instanceRoomId);
|
|
List<string> memberNotiList = new();
|
|
foreach (string id in roomMemberList)
|
|
{
|
|
if (id.Equals(mySession.Id)) continue;
|
|
memberNotiList.Add(id);
|
|
}
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
foreach (string memberId in memberNotiList)
|
|
{
|
|
FriendErrorMember errorMember = new();
|
|
errorMember.ErrorCode = ServerErrorCode.Success;
|
|
ClientSession? friendSession = ClientSessionManager.Instance.GetSessionByName(memberId);
|
|
|
|
if (friendSession == null)
|
|
{
|
|
continue;
|
|
}
|
|
ClientToGame clientToGameNoti = new ClientToGame();
|
|
clientToGameNoti.Message = new ClientToGameMessage();
|
|
clientToGameNoti.Message.NtfHostfriendLeavedHome = new();
|
|
friendSession.Send(RmiContext.ReliableSend, clientToGameNoti);
|
|
|
|
stringBuilder.Append(memberId).Append(":");
|
|
}
|
|
Log.getLogger().debug($"NotiToFriendCauseHostLeave Send friendsId : {stringBuilder.ToString()}");
|
|
|
|
}*/
|
|
|
|
public async Task<ServerErrorCode> ExchangeMyHome(string roomId, string myhomeGuid, MyHomeInfo myhomeInfo)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
Log.getLogger().error($"not exist instance room : {roomId}");
|
|
return ServerErrorCode.NotExistInstanceRoom;
|
|
}
|
|
|
|
var error_code = await room.ExchangeMyHome(myhomeGuid, myhomeInfo, roomId);
|
|
if (error_code.isFail())
|
|
{
|
|
Log.getLogger().error("Fail ExchangeMyHome map");
|
|
return error_code;
|
|
}
|
|
|
|
return ServerErrorCode.Success;
|
|
}
|
|
|
|
public ServerErrorCode MyhomeHostEnterEditRoom(string roomId, string exceptUserGuid)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
Log.getLogger().error($"not exist instance room : {roomId}");
|
|
return ServerErrorCode.NotExistInstanceRoom;
|
|
}
|
|
|
|
var error_code = room.MyhomeHostEnterEditRoom(exceptUserGuid);
|
|
if (error_code.isFail())
|
|
{
|
|
Log.getLogger().error($"Fail to MyhomeHostEnterEditRoom() !!! {error_code.toBasicString()}");
|
|
return error_code;
|
|
}
|
|
|
|
return ServerErrorCode.Success;
|
|
}
|
|
|
|
public ServerErrorCode ExchangeCraft(string roomId, string anchor_guid, Timestamp finish_craft_time)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
Log.getLogger().error($"not exist instance room : {roomId}");
|
|
return ServerErrorCode.NotExistInstanceRoom;
|
|
}
|
|
|
|
var error_code = room.ExchangeCraft(anchor_guid, finish_craft_time);
|
|
if (error_code.isFail())
|
|
{
|
|
Log.getLogger().error("Fail ExchangeCraft map");
|
|
return error_code;
|
|
}
|
|
|
|
return ServerErrorCode.Success;
|
|
}
|
|
|
|
public int changeScreenPage(string roomId, bool isCustom, bool isNext, int customPage)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
Log.getLogger().error($"not exist instance room : {roomId}");
|
|
return -1;
|
|
}
|
|
|
|
return room.changeScreenPage(isCustom, isNext, customPage);
|
|
}
|
|
|
|
public int getRoomId(string roomId)
|
|
{
|
|
if (m_instance_rooms.TryGetValue(roomId, out var room) == false)
|
|
{
|
|
return 0;
|
|
}
|
|
return room.getInstanceId();
|
|
}
|
|
|
|
public InstanceRoom? getInstanceRoomByRoomId(string roomId)
|
|
=> m_instance_rooms.GetValueOrDefault(roomId);
|
|
|
|
public ConcurrentDictionary<string, InstanceRoom> getInstanceRooms()
|
|
{
|
|
return m_instance_rooms;
|
|
}
|
|
}
|