초기커밋
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
|
||||
public class ReservationManagerBase
|
||||
{
|
||||
public const int RESERVATION_TASK_DELAY_SEC = 10;
|
||||
|
||||
protected readonly ReservationUserManager m_reservation_user_manager = new();
|
||||
protected readonly ReservationMessageManager m_reservation_message_manager = new();
|
||||
|
||||
private ServerLogicBase? m_server_logic { get; set; }
|
||||
|
||||
private ConcurrentDictionary<string, Task> m_cancelled_tasks { get; set; } = new();
|
||||
|
||||
public virtual void onInit(ServerLogicBase serverLogic)
|
||||
{
|
||||
m_server_logic = serverLogic;
|
||||
m_reservation_user_manager.onInit(serverLogic);
|
||||
}
|
||||
|
||||
public int getReservedUserCount() => m_reservation_user_manager.Count;
|
||||
public ReservationMessageManager getMessageManager() => m_reservation_message_manager;
|
||||
|
||||
public async Task checkLimitReservedUsers() => await m_reservation_user_manager.checkLimitReservedUsers();
|
||||
|
||||
public async Task<Result> checkReservation(USER_GUID userGuid)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
var result = new Result();
|
||||
|
||||
var check = m_reservation_user_manager.checkReserved(userGuid);
|
||||
if (false == check)
|
||||
{
|
||||
var err_msg = $"Failed to check reservation enter to server !!! : UserGuid - {userGuid}";
|
||||
Log.getLogger().error(err_msg);
|
||||
result.setFail(ServerErrorCode.InvalidReservationUser, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
m_reservation_user_manager.deleteReserved(userGuid);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER?> registerReservationEnterToServer(ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER message, string destServerName)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
long elapsed_msec;
|
||||
var event_tid = Guid.NewGuid().ToString();
|
||||
stopwatch.Start();
|
||||
|
||||
var next_task = new Task<ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER?>(() => getMessageManager().ackTask(message.RequestUserGuid));
|
||||
ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER? reserved = null;
|
||||
|
||||
// 1. task manager 에 등록
|
||||
var is_add = m_reservation_message_manager.addReservationMessage(message.RequestUserGuid, message, next_task);
|
||||
if (false == is_add)
|
||||
{
|
||||
var err_msg = $"fail to add reservation message: userGuid[{message.RequestUserGuid}] message[{message}]";
|
||||
result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. server manager 전송
|
||||
var server_message = new ServerMessage();
|
||||
server_message.ReqReservationEnterToServer = message;
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
var rabbit_mq = m_server_logic.getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
rabbit_mq.SendMessage(destServerName, server_message);
|
||||
|
||||
try
|
||||
{
|
||||
reserved = await next_task.WaitAsync(TimeSpan.FromSeconds(RESERVATION_TASK_DELAY_SEC));
|
||||
|
||||
// 3. 예약 실패 체크
|
||||
if (null == reserved || reserved.Result.isFail())
|
||||
{
|
||||
Log.getLogger().warn($"Failed to reservation enter to game server!!! - {reserved?.Result.toBasicString() ?? string.Empty}");
|
||||
|
||||
elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
Log.getLogger().debug($"registerReservationEnterToServer Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, UserGuid:{message.RequestUserGuid}, srcServer:{message.RequestServerName}, destServer:{destServerName}");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Task Cancelled
|
||||
deleteReservationEnterToServer(message.RequestUserGuid);
|
||||
|
||||
Log.getLogger().warn($"Failed to reservation enter to game server!!! - {e}");
|
||||
|
||||
elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
Log.getLogger().debug($"registerReservationEnterToServer Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, UserGuid:{message.RequestUserGuid}, srcServer:{message.RequestServerName}, destServer:{destServerName}");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
Log.getLogger().debug($"registerReservationEnterToServer Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, UserGuid:{message.RequestUserGuid}, srcServer:{message.RequestServerName}, destServer:{destServerName}");
|
||||
|
||||
return reserved;
|
||||
|
||||
}
|
||||
|
||||
public async Task<Result> cancelReservationEnterToServer(USER_GUID userGuid, string destServerName)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
|
||||
var server_message = new ServerMessage();
|
||||
server_message.ReqReservationCancelToServer = new();
|
||||
server_message.ReqReservationCancelToServer.RequestServerName = m_server_logic.getServerName();
|
||||
server_message.ReqReservationCancelToServer.RequestUserGuid = userGuid;
|
||||
|
||||
// 1. 취소 전송
|
||||
var rabbit_mq = m_server_logic.getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
rabbit_mq.SendMessage(destServerName, server_message);
|
||||
|
||||
// 2. 응답 대기
|
||||
var task = new Task(() =>
|
||||
{
|
||||
Log.getLogger().debug($"cancelReservationEnterToServer: ack cancel reservation - userGuid[{userGuid}]");
|
||||
m_cancelled_tasks.Remove(userGuid, out _);
|
||||
});
|
||||
m_cancelled_tasks.TryAdd(userGuid, task);
|
||||
|
||||
try
|
||||
{
|
||||
await task.WaitAsync(TimeSpan.FromSeconds(RESERVATION_TASK_DELAY_SEC));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.getLogger().debug($"cancelReservationEnterToServer: exception cancel reservation - userGuid[{userGuid}] / {e}");
|
||||
m_cancelled_tasks.Remove(userGuid, out _);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task ackCancelProcess(string userGuid)
|
||||
{
|
||||
if (!m_cancelled_tasks.TryGetValue(userGuid, out var task)) return;
|
||||
task.Start();
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void deleteReservationEnterToServer(USER_GUID userGuid) => m_reservation_message_manager.deleteReservationMessage(userGuid);
|
||||
|
||||
public async Task cancelProcess(ServerMessage.Types.GS2GS_REQ_RESERVATION_CANCEL_TO_SERVER message)
|
||||
{
|
||||
m_reservation_user_manager.deleteReserved(message.RequestUserGuid);
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task ackProcess(ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER message)
|
||||
=> await m_reservation_message_manager.onReceivedReservationEnterToServer(message);
|
||||
|
||||
public async Task reqProcess(ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER request)
|
||||
{
|
||||
var stopwatch = new Stopwatch();
|
||||
var event_tid = Guid.NewGuid().ToString();
|
||||
|
||||
stopwatch.Start();
|
||||
|
||||
var server_message = new ServerMessage();
|
||||
server_message.AckReservationEnterToServer = new();
|
||||
server_message.AckReservationEnterToServer.ReservationUserGuid = request.RequestUserGuid;
|
||||
server_message.AckReservationEnterToServer.Result = new();
|
||||
|
||||
// 1. 조건 체크
|
||||
var is_check_condition = await checkReservationCondition(request.MoveType, request.RequestUserGuid);
|
||||
if (false == is_check_condition)
|
||||
{
|
||||
server_message.AckReservationEnterToServer.Result.setFail(ServerErrorCode.FailedToReserveEnterCondition, $"Failed to reservation enter !!! : check condition failed {nameof(reqProcess)}");
|
||||
sendAckReservationEnterToServer(server_message, request.RequestServerName);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 예약 하기
|
||||
Log.getLogger().debug($"add reserve user : userGuid[{request.RequestUserGuid}]");
|
||||
var is_reserved = m_reservation_user_manager.AddReserved(request.RequestUserGuid);
|
||||
if (false == is_reserved)
|
||||
{
|
||||
server_message.AckReservationEnterToServer.Result.setFail(ServerErrorCode.FailedToReservationEnter, $"Failed to reserve enter !!! - {nameof(reqProcess)}");
|
||||
sendAckReservationEnterToServer(server_message, request.RequestServerName);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 예약 결과 전송
|
||||
server_message.AckReservationEnterToServer.Result.setSuccess();
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
server_message.AckReservationEnterToServer.ReservationServerName = m_server_logic.getServerName();
|
||||
sendAckReservationEnterToServer(server_message, request.RequestServerName);
|
||||
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
Log.getLogger().debug($"ReservationEnterToServer reqProcess Stopwatch Stop: ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, UserGuid:{request.RequestUserGuid}, srcServer:{request.RequestServerName}, destServer:{m_server_logic.getServerName()}");
|
||||
}
|
||||
|
||||
protected virtual async Task<bool> checkReservationCondition(ServerMoveType moveType, USER_GUID reservationUserGuid) => await Task.FromResult(true);
|
||||
|
||||
protected virtual async Task<int> checkFreeSessionCount() => await Task.FromResult(0);
|
||||
|
||||
protected bool calculateConnectionRate(int freeCount)
|
||||
{
|
||||
var rate = MetaHelper.GameConfigMeta.AutoMoveRate;
|
||||
|
||||
var allow_count = freeCount - 1;
|
||||
if (allow_count <= 0) return false;
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
var proud_net_listener = m_server_logic.getProudNetListener();
|
||||
|
||||
var current_rate = ((float)(proud_net_listener.getMaxConnectionCount() - allow_count) / proud_net_listener.getMaxConnectionCount()) * 100;
|
||||
return current_rate <= rate;
|
||||
}
|
||||
|
||||
private void sendAckReservationEnterToServer(ServerMessage message, string destServerName)
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
var rabbit_mq = m_server_logic.getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
|
||||
rabbit_mq.SendMessage(destServerName, message);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
public class ReservationMessageArgument
|
||||
{
|
||||
public ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER m_req_message { get; set; } = null!;
|
||||
public ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER? m_ack_message { get; set; }
|
||||
}
|
||||
|
||||
public class ReservationMessageManager
|
||||
{
|
||||
private ConcurrentDictionary<USER_GUID, ReservationMessageArgument> m_messages { get; set; } = new();
|
||||
private ConcurrentDictionary<USER_GUID, Task> m_tasks { get; set; } = new();
|
||||
|
||||
public bool addReservationMessage(USER_GUID userGuid, ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER reqMessage, Task<ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER?> action)
|
||||
{
|
||||
var args = new ReservationMessageArgument();
|
||||
args.m_req_message = reqMessage;
|
||||
|
||||
var is_add = m_tasks.TryAdd(userGuid, action);
|
||||
if (is_add)
|
||||
{
|
||||
m_messages[userGuid] = args;
|
||||
return true;
|
||||
}
|
||||
|
||||
deleteReservationMessage(userGuid);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public void deleteReservationMessage(USER_GUID userGuid)
|
||||
{
|
||||
m_messages.Remove(userGuid, out _);
|
||||
m_tasks.Remove(userGuid, out _);
|
||||
}
|
||||
|
||||
private ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER? getMessage(USER_GUID userGuid)
|
||||
{
|
||||
return m_messages.TryGetValue(userGuid, out var args) ? args.m_ack_message : null;
|
||||
}
|
||||
|
||||
public async Task onReceivedReservationEnterToServer(ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER message)
|
||||
{
|
||||
// 1. message 저장
|
||||
await addAckMessage(message);
|
||||
|
||||
// 2. task 찾기
|
||||
if (!m_tasks.TryGetValue(message.ReservationUserGuid, out var task))
|
||||
{
|
||||
Log.getLogger().error($"Failed to get reservation task !!! : userGuid - {message.ReservationUserGuid}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. task 실행
|
||||
task.Start();
|
||||
}
|
||||
|
||||
public ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER? ackTask(USER_GUID userGuid)
|
||||
{
|
||||
var message = getMessage(userGuid);
|
||||
deleteReservationMessage(userGuid);
|
||||
return message;
|
||||
}
|
||||
|
||||
private async Task addAckMessage(ServerMessage.Types.GS2GS_ACK_RESERVATION_ENTER_TO_SERVER message)
|
||||
{
|
||||
if (!m_messages.TryGetValue(message.ReservationUserGuid, out var args))
|
||||
{
|
||||
Log.getLogger().error($"Failed to get reservation task !!! : userGuid - {message.ReservationUserGuid}");
|
||||
return;
|
||||
}
|
||||
|
||||
args.m_ack_message = message;
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
public class ReservationUserManager
|
||||
{
|
||||
private ServerLogicBase? m_server_logic { get; set; }
|
||||
|
||||
private ConcurrentDictionary<string, DateTime> m_reserved_user_ids { get; set; } = new();
|
||||
|
||||
public int Count => m_reserved_user_ids.Count;
|
||||
|
||||
public void onInit(ServerLogicBase serverLogic) => m_server_logic = serverLogic;
|
||||
|
||||
public bool AddReserved(string userGuid)
|
||||
{
|
||||
if (checkReserved(userGuid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
var config = m_server_logic.getServerConfig();
|
||||
return m_reserved_user_ids.TryAdd(userGuid, DateTime.UtcNow.AddMilliseconds(config.GameConfig.ReservationWaitTimeMSec));
|
||||
}
|
||||
|
||||
public bool checkReserved(string userGuid) => m_reserved_user_ids.ContainsKey(userGuid);
|
||||
|
||||
public bool deleteReserved(string userGuid) => m_reserved_user_ids.Remove(userGuid, out _);
|
||||
|
||||
public async Task checkLimitReservedUsers()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var delete_list = (from user in m_reserved_user_ids
|
||||
where user.Value <= DateTime.UtcNow select user.Key).ToList();
|
||||
|
||||
foreach (var del in delete_list)
|
||||
{
|
||||
deleteReserved(del);
|
||||
}
|
||||
}
|
||||
}
|
||||
102
ServerCommon/Contents/ReturnUserToServer/ReturnManagerBase.cs
Normal file
102
ServerCommon/Contents/ReturnUserToServer/ReturnManagerBase.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
|
||||
using USER_GUID = System.String;
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
public class ReturnManagerBase
|
||||
{
|
||||
private ServerLogicBase? m_server_logic { get; set; }
|
||||
|
||||
private ReturnUserManager m_return_user_manager { get; set; } = new();
|
||||
|
||||
public void onInit(ServerLogicBase serverLogic)
|
||||
{
|
||||
m_server_logic = serverLogic;
|
||||
m_return_user_manager.setReturnKickTimeMinutes(MetaHelper.GameConfigMeta.ReturnKickTimeMinute);
|
||||
}
|
||||
|
||||
public int getReturnUserCount() => m_return_user_manager.Count;
|
||||
|
||||
public async Task checkLimitReturnUsers() => await m_return_user_manager.checkLimitReturnUsers();
|
||||
|
||||
public bool isReturnUser(USER_GUID userGuid) => m_return_user_manager.checkReturnUser(userGuid);
|
||||
|
||||
public bool addReturnUser(USER_GUID userGuid) => m_return_user_manager.addReturnUser(userGuid);
|
||||
|
||||
public async Task<Result> checkReturnUser(USER_GUID userGuid)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
var result = new Result();
|
||||
|
||||
var check = m_return_user_manager.checkReturnUser(userGuid);
|
||||
if (false == check)
|
||||
{
|
||||
var err_msg = $"not return user to server !!! : UserGuid - {userGuid}";
|
||||
Log.getLogger().info(err_msg);
|
||||
result.setFail(ServerErrorCode.InvalidReturnUser, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
m_return_user_manager.deleteReturnUser(userGuid);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task notifyReturnUserLogout(EntityBase entityUser)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_logic, () => $"m_server_logic is null !!!");
|
||||
var rabbit_mq = m_server_logic.getRabbitMqConnector() as RabbitMqConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!");
|
||||
|
||||
var location_attribute = entityUser.getEntityAttribute<LocationAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!!");
|
||||
var user_attribute = entityUser.getEntityAttribute<UserAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!!");
|
||||
|
||||
var redis_connector = m_server_logic.getRedisConnector();
|
||||
var redis_database = redis_connector.getDatabase();
|
||||
NullReferenceCheckHelper.throwIfNull(redis_database, () => $"redis_database is null !!!");
|
||||
|
||||
var message = new ServerMessage();
|
||||
message.NtfReturnUserLogout = new();
|
||||
message.NtfReturnUserLogout.ReturnUserGuid = user_attribute.UserGuid;
|
||||
|
||||
// 1. channel server 요청
|
||||
if (m_server_logic.getServerType().toServerType() != ServerType.Channel)
|
||||
{
|
||||
rabbit_mq.SendMessage(location_attribute.LastestChannelServerLocation.ServerName, message);
|
||||
}
|
||||
|
||||
// 2. indun server 요청
|
||||
foreach (var location in location_attribute.ReturnIndunLocations)
|
||||
{
|
||||
var roomId = location.InstanceRoomId;
|
||||
|
||||
var instance_room_storage = new InstanceRoomStorage();
|
||||
instance_room_storage.Init(redis_database, "");
|
||||
|
||||
InstanceRoomInfo? instanceRoom = await instance_room_storage.GetInstanceRoomInfo(roomId);
|
||||
if (instanceRoom == null)
|
||||
{
|
||||
var err_msg = $"Not found InstanceRoomInfo. roomId:{roomId}";
|
||||
Log.getLogger().error(err_msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
var server_name = ServerBase.ServerHelper.makeServerNameByNetworkAddress(ServerType.Indun,
|
||||
instanceRoom.InstanceAddress, (ushort)instanceRoom.InstancePort);
|
||||
rabbit_mq.SendMessage(server_name, message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task replyReturnUserLogout(ServerMessage.Types.GS2GS_NTF_RETURN_USER_LOGOUT notify)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
m_return_user_manager.deleteReturnUser(notify.ReturnUserGuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
||||
namespace ServerCommon;
|
||||
|
||||
public class ReturnUserManager
|
||||
{
|
||||
private ConcurrentDictionary<string, DateTime> m_return_user_ids { get; set; } = new();
|
||||
private int m_return_wait_time { get; set; } = 60;
|
||||
|
||||
public int Count => m_return_user_ids.Count;
|
||||
|
||||
public void setReturnKickTimeMinutes(int time) => m_return_wait_time = time;
|
||||
|
||||
public bool addReturnUser(string userGuid) =>
|
||||
m_return_user_ids.TryAdd(userGuid, DateTime.UtcNow.AddMinutes(m_return_wait_time));
|
||||
|
||||
public bool checkReturnUser(string userGuid) => m_return_user_ids.ContainsKey(userGuid);
|
||||
|
||||
public bool deleteReturnUser(string userGuid) => m_return_user_ids.Remove(userGuid, out _);
|
||||
|
||||
public async Task checkLimitReturnUsers()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var delete_list = (from user in m_return_user_ids
|
||||
where user.Value <= DateTime.UtcNow select user.Key).ToList();
|
||||
|
||||
foreach (var del in delete_list)
|
||||
{
|
||||
deleteReturnUser(del);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user