279 lines
8.6 KiB
C#
279 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Security.Claims;
|
|
|
|
|
|
using Amazon.DynamoDBv2.Model;
|
|
using Amazon.DynamoDBv2;
|
|
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
|
using Google.Protobuf;
|
|
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using GameServer.PacketHandler;
|
|
using MetaAssets;
|
|
|
|
|
|
using static ClientToGameReq.Types;
|
|
using static ClientToGameRes.Types;
|
|
using static ClientToGameMessage.Types;
|
|
|
|
|
|
using SESSION_ID = System.Int32;
|
|
using WORLD_META_ID = System.UInt32;
|
|
using META_ID = System.UInt32;
|
|
using ENTITY_GUID = System.String;
|
|
using ACCOUNT_ID = System.String;
|
|
using OWNER_GUID = System.String;
|
|
using USER_GUID = System.String;
|
|
using CHARACTER_GUID = System.String;
|
|
using ITEM_GUID = System.String;
|
|
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class ChatCommand : Attribute
|
|
{
|
|
Dictionary<string, ChatCommandBase> command_base_map = new Dictionary<string, ChatCommandBase>();
|
|
|
|
public ChatCommand()
|
|
{
|
|
loadChatCommand();
|
|
|
|
}
|
|
|
|
private void loadChatCommand()
|
|
{
|
|
// ChatCommand 클래스의 모든 메서드를 가져옵니다.
|
|
|
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
|
|
foreach (var assembly in assemblies)
|
|
{
|
|
foreach (Type type in assembly.GetTypes())
|
|
{
|
|
ChatCommandAttribute[] attributes = (ChatCommandAttribute[])type.GetCustomAttributes(typeof(ChatCommandAttribute), false);
|
|
|
|
|
|
foreach (var attrib in attributes)
|
|
{
|
|
var command_key = attrib.getCommand();
|
|
if (command_key == null)
|
|
{
|
|
Log.getLogger().error($"ChatCommand Key is null !!!, in ChatCommandAttributes : {attrib.getHandlerClass().FullName}");
|
|
continue;
|
|
}
|
|
|
|
var handler_class = Activator.CreateInstance(attrib.getHandlerClass()) as ChatCommandBase;
|
|
if (handler_class == null)
|
|
{
|
|
Log.getLogger().error($"Failed to create ChatCommand !!! : commandKey:{command_key}");
|
|
continue;
|
|
}
|
|
|
|
handler_class.setAuthAdminLevelType(attrib.getAdminLevel());
|
|
handler_class.setClassName(attrib.getHandlerClass().Name);
|
|
if (command_base_map.TryAdd(command_key, handler_class) == false)
|
|
{
|
|
Log.getLogger().error($"Failed to TryAdd() !!!, Already added CommandKey !!! : commandKey:{command_key}");
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public bool isCheatCommand(string input)
|
|
{
|
|
return input.StartsWith("//");
|
|
}
|
|
|
|
|
|
public async Task<bool> HandleCommand(Player player, string input)
|
|
{
|
|
var tokenArr = input.Split(" ", 2);
|
|
|
|
try
|
|
{
|
|
var command = tokenArr[0].Remove(0, 2);
|
|
|
|
if (command_base_map.TryGetValue(command.ToLower(), out var handler_class) == false)
|
|
{
|
|
Log.getLogger().error($"Command Not Exist Command : {command.ToLower()}");
|
|
return false;
|
|
}
|
|
|
|
if (await hasAuthority(handler_class, player) == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (tokenArr.Length > 1)
|
|
{
|
|
var args = tokenArr[1].Split(" ", StringSplitOptions.RemoveEmptyEntries);
|
|
await handler_class.invoke(player, tokenArr[1], args);
|
|
}
|
|
else
|
|
{
|
|
await handler_class.invoke(player, String.Empty, new string[] { });
|
|
}
|
|
}
|
|
catch (TaskCanceledException e)
|
|
{
|
|
Log.getLogger().error($"TaskCanceledException !!!, Failed to perform in HandleCommand() !!! : exception:{e}, inputString:{input} - {player.toBasicString()}");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.getLogger().error($"Exception !!!, Failed to perform in HandleCommand() !!! : exception:{e}, inputString:{input} - {player.toBasicString()}");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task<bool> hasAuthority(ChatCommandBase handlerClass, Player player)
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
var server_config = ServerConfigHelper.getServerConfig();
|
|
NullReferenceCheckHelper.throwIfNull(server_config, () => $"server_config is null !!!");
|
|
|
|
// ServiceType.Dev 타입일 경우 무조건 치트 사용이 가능 하다. !!!
|
|
if (server_config.ServiceType.Equals(ServiceType.Dev.ToString()))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// CheatCommandAlwaysAllow == true 일 경우 무조건 치트 사용이 가능 하다. !!!
|
|
if (true == server_config.CheatCommandAlwaysAllow)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var account_attribute = player.getEntityAttribute<AccountAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!!");
|
|
|
|
var admin_level_type = account_attribute.AuthAdminLevelType;
|
|
//여기에 유저 레벨이랑, 클래스에 할당된 레벨이랑 비교 필요
|
|
var class_admin_level_type = handlerClass.getAuthAddminLevelType();
|
|
|
|
if (class_admin_level_type.Contains(admin_level_type) == false)
|
|
{
|
|
Log.getLogger().info($"Not Match Admin LevelType !!! : className = {handlerClass.getAuthAddminLevelType().ToString()}, className:{handlerClass.getClassName()} - {player.toBasicString()}");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Class)]
|
|
internal class ChatCommandAttribute : Attribute
|
|
{
|
|
readonly string m_cheat_comment;
|
|
private readonly Type m_handler_class;
|
|
private readonly HashSet<AuthAdminLevelType> m_auth_admin_level_type;
|
|
|
|
public ChatCommandAttribute(string cheatCommend, Type handlerClass, params AuthAdminLevelType[] authAdminLevelType)
|
|
{
|
|
m_cheat_comment = cheatCommend;
|
|
m_handler_class = handlerClass;
|
|
m_auth_admin_level_type = new HashSet<AuthAdminLevelType>(authAdminLevelType);
|
|
}
|
|
|
|
public string getCommand()
|
|
{
|
|
return m_cheat_comment;
|
|
}
|
|
|
|
public HashSet<AuthAdminLevelType> getAdminLevel()
|
|
{
|
|
return m_auth_admin_level_type;
|
|
}
|
|
|
|
public Type getHandlerClass()
|
|
{
|
|
return m_handler_class;
|
|
}
|
|
}
|
|
|
|
public abstract class ChatCommandBase
|
|
{
|
|
private HashSet<AuthAdminLevelType> m_auth_admin_level_type = new();
|
|
private string m_class_name = string.Empty;
|
|
|
|
public void setAuthAdminLevelType(HashSet<AuthAdminLevelType> typeSet)
|
|
{
|
|
m_auth_admin_level_type = typeSet;
|
|
}
|
|
|
|
public HashSet<AuthAdminLevelType> getAuthAddminLevelType()
|
|
{
|
|
return m_auth_admin_level_type;
|
|
}
|
|
|
|
|
|
public void setClassName(string className)
|
|
{
|
|
m_class_name = className;
|
|
}
|
|
|
|
public string getClassName()
|
|
{
|
|
return m_class_name;
|
|
}
|
|
|
|
|
|
|
|
public virtual async Task invoke(Player player, string token, string[] args)
|
|
{
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
}
|
|
|
|
[ChatCommandAttribute("sessionkeepalivetime", typeof(ChatCommandSessionKeepAliveTime), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
|
|
internal class ChatCommandSessionKeepAliveTime : ChatCommandBase
|
|
{
|
|
public override async Task invoke(Player player, string token, string[] args)
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
Log.getLogger().info($"Call sessionkeepalivetime !!! - {player.toBasicString()}");
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
if (args.Length < 1)
|
|
{
|
|
err_msg = $"Not enough argument !!! : argCount:{args.Length} == 3 - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return;
|
|
}
|
|
|
|
var keep_alive_minutes = int.Parse(args[0]);
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}");
|
|
|
|
|
|
var session = player as IEntityWithSession;
|
|
NullReferenceCheckHelper.throwIfNull(session, () => $"session is null !!! - {player.toBasicString()}");
|
|
|
|
var timeout_ms = keep_alive_minutes * ConstValue.default_1_min_to_sec * ConstValue.default_1_sec_to_milisec;
|
|
|
|
var net_server = server_logic.getProudNetListener().getNetServer();
|
|
NullReferenceCheckHelper.throwIfNull(net_server, () => $"net_server is null !!!");
|
|
net_server.SetTimeoutTimeMs(session.getHostId(), timeout_ms);
|
|
}
|
|
}
|