초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,271 @@

using ServerCore;
using ServerBase;
using ServerCommon;
namespace GameServer;
public class ChatAction : EntityActionBase
{
public ChatAction(EntityBase owner)
: base(owner)
{
}
public override Task<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear()
{
return;
}
// 일반 주변 채팅
public Result NormalChat(string message)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var game_zone_action = player.getEntityAction<GameZoneAction>();
ChatNotifyHelper.send_S2C_NTF_CHAT_BROADCAST(player, ChatType.Normal, player.getUserNickname(), string.Empty, PlayerStateType.None, message);
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.ChatNormal);
var cellPos = game_zone_action.GetPlayerCellPos(player);
var task_log_data = ChatBusinessLogHelper.toLogInfo(message, cellPos);
invokers.Add(new ChatBusinessLog(task_log_data));
BusinessLogger.collectLogs(log_action, player, invokers);
return result;
}
// 채널 서버 내 채팅
public Result ChannelChat(string message)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"server_logic is null !!!");
var server_logic = GameServerApp.getServerLogic();
var receivers = server_logic.getPlayerManager().getUsers();
foreach(var receiver in receivers)
{
ChatNotifyHelper.send_S2C_NTF_CHAT(receiver.Value, ChatType.Channel, player.getUserNickname(), string.Empty, PlayerStateType.None, message);
}
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.ChatChannel);
var task_log_data = ChatBusinessLogHelper.toLogInfo(message, string.Empty);
invokers.Add(new ChatBusinessLog(task_log_data));
BusinessLogger.collectLogs(log_action, player, invokers);
return result;
}
// 전서버 채팅
public Result NoticeChat(string message)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"server_logic is null !!!");
var server_logic = GameServerApp.getServerLogic();
// GM인지 확인
//if (AccountAuthorityManager.Instance.IsWhiteListUser(player.getAccountId()) == false)
//{
// err_msg = $"Not Enough Authority to NoticeChat : player - {player.toBasicString()}";
// result.setFail(ServerErrorCode.NotEnoughAuthority, err_msg);
// Log.getLogger().error(err_msg);
// ChatPacketHandler.send_S2C_ACK_CHAT(player, result, ChatType.Notice, player.getUserNickname(), string.Empty, string.Empty, PlayerStateType.None, message);
// return result;
//}
var rabbitMQ4Game = server_logic.getRabbitMqConnector() as RabbitMQ4Game;
NullReferenceCheckHelper.throwIfNull(rabbitMQ4Game, () => $"rabbitMQ4Game is null !!!");
rabbitMQ4Game.sendChat(message, player.getUserNickname(), ChatType.Notice);
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.ChatNotice);
var task_log_data = ChatBusinessLogHelper.toLogInfo(message, string.Empty);
invokers.Add(new ChatBusinessLog(task_log_data));
BusinessLogger.collectLogs(log_action, player, invokers);
return result;
}
// 귓속말 채팅
public async Task<Result> WhisperChat(string receiver_nickname, string message)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var rabbitMQ4Game = server_logic.getRabbitMqConnector() as RabbitMQ4Game;
NullReferenceCheckHelper.throwIfNull(rabbitMQ4Game, () => $"rabbitMQ4Game is null !!!");
var dynamo_db_client = server_logic.getDynamoDbClient();
if (receiver_nickname == player.getUserNickname())
{
err_msg = $"Can't Send Chat to Self. nickname : {receiver_nickname}";
result.setFail(ServerErrorCode.ChatSendSelfFailed, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
(result, var nickname_attrib) = await NicknameHelper.findNickname(receiver_nickname);
if (result.isFail())
{
err_msg = $"Not Found Target. nickname : {receiver_nickname}";
result.setFail(ServerErrorCode.TargetUserNotFound, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
NullReferenceCheckHelper.throwIfNull(nickname_attrib, () => $"nickname_attrib is null !!!");
var receiver_user_guid = nickname_attrib.UserGuid;
var login_cache_request = new LoginCacheOtherUserRequest(player, server_logic.getRedisConnector(), nickname_attrib.UserGuid);
result = await login_cache_request.fetchLogin();
var login_cache = login_cache_request.getLoginCache();
if (result.isFail() || login_cache == null)
{
err_msg = $"Logoff user : target_usenicknamer - {receiver_nickname}";
result.setFail(ServerErrorCode.TargetUserNotLogIn, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
var user_block_action = player.getEntityAction<BlockUserAgentAction>();
if (user_block_action == null)
{
err_msg = $"Failed to get user block action : {nameof(BlockUserAgentAction)}";
result.setFail(ServerErrorCode.EntityActionNotFound, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
//내가 차단한경우
if (user_block_action.isBlockUser(receiver_user_guid))
{
err_msg = $"Failed chat with blocked user.";
result.setFail(ServerErrorCode.ChatBlockUserCannotWhisper, err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
//상대방이 차단한경우 상대방에겐 보내지 않고 정상 처리 되도록
(result, bool isblocked) = await user_block_action.amIBockedFromOthers(receiver_user_guid);
if (result.isFail())
{
return result;
}
if (isblocked == true)
{
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), receiver_user_guid, login_cache.State, message);
return result;
}
if (login_cache.CurrentServer != server_logic.getServerName())
{
ServerMessage chatMessage = new();
chatMessage.Chat = new();
chatMessage.Chat.Type = ChatType.Whisper;
chatMessage.Chat.SenderNickName = player.getUserNickname();
chatMessage.Chat.ReceiverGuid = receiver_user_guid;
chatMessage.Chat.Receiverstate = login_cache.State;
chatMessage.Chat.Message = message;
rabbitMQ4Game.SendMessage(login_cache.CurrentServer, chatMessage);
}
else
{
if(server_logic.getPlayerManager().tryGetUserByPrimaryKey(receiver_user_guid, out var receiver) == false)
{
err_msg = $"Failed to get player from player manager : receiver_user_guid - {receiver_user_guid}";
result.setFail(ServerErrorCode.TargetUserNotLogIn, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
if(receiver == null)
{
err_msg = $"Failed to get player from player manager : receiver_user_guid - {receiver_user_guid}";
result.setFail(ServerErrorCode.TargetUserNotLogIn, err_msg);
Log.getLogger().error(err_msg);
PacketHandler.ChatPacketHandler.send_S2C_ACK_CHAT(player, result, receiver_nickname, ChatType.Whisper, player.getUserNickname(), string.Empty, (int)PlayerStateType.None, message);
return result;
}
ChatNotifyHelper.send_S2C_NTF_CHAT(receiver, ChatType.Whisper, player.getUserNickname(), receiver_nickname, login_cache.State, message);
}
ChatNotifyHelper.send_S2C_NTF_CHAT(player, ChatType.Whisper, player.getUserNickname(), receiver_nickname, login_cache.State, message);
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.ChatWhisper);
var task_log_data = ChatBusinessLogHelper.toLogInfo(message, receiver_nickname);
invokers.Add(new ChatBusinessLog(task_log_data));
BusinessLogger.collectLogs(log_action, player, invokers);
return result;
}
// 파티 채팅
public async Task<Result> PartyChat(string message)
{
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var personal_party_action = player.getEntityAction<PersonalPartyAction>();
NullReferenceCheckHelper.throwIfNull(personal_party_action, () => $"personal_party_action is null !!!");
var result = await personal_party_action.sendPartyChat(message);
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.ChatParty);
//personal_party_action.getPersonalParty().
var task_log_data = ChatBusinessLogHelper.toLogInfo(message, string.Empty);
invokers.Add(new ChatBusinessLog(task_log_data));
BusinessLogger.collectLogs(log_action, player, invokers);
return result;
}
}

View File

@@ -0,0 +1,278 @@
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);
}
}

View File

@@ -0,0 +1,73 @@
using ServerCore; using ServerBase;
using ServerCommon;
using GameServer.PacketHandler;
namespace GameServer.ChatCommandHandler;
[ChatCommandAttribute("warp", typeof(WarpCommandHandler), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
internal class WarpCommandHandler : ChatCommandBase
{
public override async Task invoke(Player player, string token, string[] args)
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out var warp_id)) return;
var result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CheetWarp", warpDelegate);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafely : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
async Task<Result> warpDelegate() => await warpAsync(player, warp_id);
}
private async Task<Result> warpAsync(Player player, int warpId)
{
var result = new Result();
string err_msg;
var server_logic = GameServerApp.getServerLogic();
var res = new ClientToGameRes.Types.WarpRes();
var game_zone_move_action = player.getEntityAction<GameZoneMoveAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_move_action, () => $"game_zone_move_action is null !!! - {player.toBasicString()}");
(result, res, var business_logs) = await game_zone_move_action.tryWarp(warpId);
if (result.isFail())
{
err_msg = $"Failed to tryWarp() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
WarpPacketHandler.send_S2C_ACK_WARP(player, result, res);
return result;
}
NullReferenceCheckHelper.throwIfNull(business_logs, () => $"business_logs is null !!! - warpId:{warpId}, {player.toBasicString()}");
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.Warp, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal());
}
batch.appendBusinessLogs(business_logs);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
WarpPacketHandler.send_S2C_ACK_WARP(player, result, res);
return result;
}
WarpPacketHandler.send_S2C_ACK_WARP(player, result, res);
if (res.PlaceCase == ClientToGameRes.Types.WarpRes.PlaceOneofCase.Pos)
{
player.send_S2C_NTF_SET_LOCATION();
}
return result;
}
}

View File

@@ -0,0 +1,32 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class ChatBusinessLog : ILogInvokerEx
{
private ChatLogData m_data_to_log;
public ChatBusinessLog(ChatLogData log_data_param)
: base(LogDomainType.Chat)
{
m_data_to_log = log_data_param;
}
public override bool hasLog()
{
return true;
}
protected override void fillup(ref BusinessLog.LogBody body)
{
body.append(new ChatLogData(this, m_data_to_log));
}
}

View File

@@ -0,0 +1,39 @@

using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public static class ChatBusinessLogHelper
{
static public ChatLogData toLogInfo(string chatMessage, CellPos cellpos)
{
var logData = new ChatLogData();
logData.setInfo(chatMessage, cellpos);
return logData;
}
static public ChatLogData toLogInfo(string chatMessage, string targetUser = "")
{
var logData = new ChatLogData();
logData.setInfo(chatMessage, targetUser);
return logData;
}
static public void setInfo(this ChatLogData logData, string chatMessage, string targetUser)
{
logData.TargetUser = targetUser;
logData.ChatMessage = chatMessage;
}
static public void setInfo(this ChatLogData logData, string chatMessage, CellPos cellpos)
{
logData.ChatMessage = chatMessage;
logData.cellPosX = cellpos.CellX;
logData.cellPosX = cellpos.CellY;
}
}

View File

@@ -0,0 +1,81 @@
using ServerCore; using ServerBase;
using static ServerMessage.Types;
namespace GameServer
{
public class ChatNotifyHelper
{
public static ClientToGame makeChatMessage(ChatType chat_type, string sender_nickname, string receiver_nickname, PlayerStateType receiver_state, string message)
{
var noti_packet = new ClientToGame();
noti_packet.Message = new();
noti_packet.Message.Chat = new();
noti_packet.Message.Chat.Type = chat_type;
noti_packet.Message.Chat.Sender = sender_nickname;
noti_packet.Message.Chat.Receiver = receiver_nickname;
noti_packet.Message.Chat.Receiverstate = receiver_state;
noti_packet.Message.Chat.Message = message;
return noti_packet;
}
public static bool send_S2C_NTF_CHAT(Player player, ChatType chat_type, string sender_nickname, string receiver_nickname, PlayerStateType receiver_state, string message)
{
var noti_packet = makeChatMessage(chat_type, sender_nickname, receiver_nickname, receiver_state, message);
if (false == GameServerApp.getServerLogic().onSendPacket(player, noti_packet))
{
return false;
}
return true;
}
public static bool send_S2C_NTF_CHAT_BROADCAST(Player player, ChatType chat_type, string sender_nickname, string receiver_nickname, PlayerStateType receiver_state, string message)
{
var noti_packet = makeChatMessage(chat_type, sender_nickname, receiver_nickname, receiver_state, message);
var game_zone_action = player.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
game_zone_action.broadcast(player, noti_packet);
return true;
}
public static void send_S2C_NTF_MQ_CHAT(Chat chat)
{
var server_logic = GameServerApp.getServerLogic();
var player_manager = server_logic.getPlayerManager();
switch (chat.Type)
{
case ChatType.Notice:
{
var players = player_manager.getUsers();
foreach (var player in players)
{
ChatNotifyHelper.send_S2C_NTF_CHAT(player.Value, chat.Type, chat.SenderNickName, "", PlayerStateType.None, chat.Message);
}
break;
}
case ChatType.Whisper:
{
if (player_manager.tryGetUserByPrimaryKey(chat.ReceiverGuid, out var found_user) == false) return;
if (found_user == null) return;
ChatNotifyHelper.send_S2C_NTF_CHAT(found_user, chat.Type, chat.SenderNickName, found_user.getUserNickname(), PlayerStateType.None, chat.Message);
break;
}
case ChatType.Party:
{
//await PartyManager.Instance.ChatBroadcast(chat.Receiver, clientToGame);
break;
}
default:
break;
}
}
}
}

View File

@@ -0,0 +1,180 @@
using Google.Protobuf;
using ServerCore;
using ServerBase;
using ServerCommon;
using static ClientToGameReq.Types;
using static ClientToGameRes.Types;
namespace GameServer.PacketHandler;
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ChatReq), typeof(ChatPacketHandler), typeof(GameLoginListener))]
public class ChatPacketHandler : PacketRecvHandler
{
public static bool send_S2C_ACK_CHAT(Player player, Result result, string receiver_nickname, ChatType chat_type = ChatType.None, string sender_nickname = "", string receiver_guid = "", PlayerStateType receiver_state = PlayerStateType.None, string message = "")
{
var ack_packet = new ClientToGame();
ack_packet.Response = new ClientToGameRes();
ack_packet.Response.ErrorCode = result.ErrorCode;
ack_packet.Response.ChatRes = new ChatRes();
ack_packet.Response.ChatRes.Type = chat_type;
ack_packet.Response.ChatRes.Sender = sender_nickname;
ack_packet.Response.ChatRes.Receiver = receiver_nickname;
ack_packet.Response.ChatRes.Receiverid = receiver_guid;
ack_packet.Response.ChatRes.Receiverstate = receiver_state;
ack_packet.Response.ChatRes.Message = message;
if (false == GameServerApp.getServerLogic().onSendPacket(player, ack_packet))
{
return false;
}
return true;
}
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
{
var result = new Result();
var err_msg = string.Empty;
var entity_player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var chat_action = entity_player.getEntityAction<ChatAction>();
NullReferenceCheckHelper.throwIfNull(chat_action, () => $"chat_action is null !!!");
// 1. 메시지 체크
var game_msg = recvMessage as ClientToGame;
if (game_msg == null)
{
err_msg = $"Failed to cast ClientToGame !!! : {nameof(ClientToGame.Request.ChatReq)}";
result.setFail(ServerErrorCode.ClassTypeCastIsNull, err_msg);
Log.getLogger().error(result.toBasicString());
send_S2C_ACK_CHAT(entity_player, result, "");
return result;
}
var request = game_msg.Request.ChatReq;
// 2. 유저 block 체크
var account_attribute = entity_player.getEntityAttribute<AccountAttribute>();
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {entity_player.toBasicString()}");
var account_base_doc = account_attribute.getOriginDocBase<AccountAttribute>() as AccountBaseDoc;
NullReferenceCheckHelper.throwIfNull(account_base_doc, () => $"account_base_doc is null !!!");
var doc_account_base_attrib = account_base_doc.getAttrib<AccountBaseAttrib>();
NullReferenceCheckHelper.throwIfNull(doc_account_base_attrib, () => $"doc_account_base_attrib is null !!!");
var block_policy = UserBlockHelper.convertBlockPolicyToJavaPolicy(doc_account_base_attrib.BlockPolicy);
if (block_policy.Contains(UserBlockPolicyType.ChattingRestrictions.ToString()))
{
//여기서 강제로 리턴
send_S2C_ACK_CHAT(entity_player, result, request.ToNickName);
return result;
}
// 3. cheat 체크
if (server_logic.ChatCommand.isCheatCommand(request.Message) == true)
{
await server_logic.ChatCommand.HandleCommand(entity_player, request.Message);
send_S2C_ACK_CHAT(entity_player, result, request.ToNickName);
return result;
}
// 4. chat 기본 조건 체크
result = checkChatConditions(request.Message);
if (result.isFail())
{
send_S2C_ACK_CHAT(entity_player, result, request.ToNickName);
return result;
}
var chat_type = request.Type;
// 5. 채팅 처리
switch (chat_type)
{
case ChatType.Normal:
result = chat_action.NormalChat(request.Message);
break;
case ChatType.Channel:
result = chat_action.ChannelChat(request.Message);
break;
case ChatType.Notice:
result = chat_action.NoticeChat(request.Message);
break;
case ChatType.Whisper:
result = await chat_action.WhisperChat(request.ToNickName, request.Message);
break;
case ChatType.Party:
result = await chat_action.PartyChat(request.Message);
break;
default:
err_msg = $"Invalid EChatType !!! EChatType : {request.Type} - {entity_player.toBasicString()}";
result.setFail(ServerErrorCode.ChatInvalidChatType, err_msg);
Log.getLogger().error(err_msg);
break;
}
if (result.isFail())
{
err_msg = $"Failed to trySendMail() !!! : {result.toBasicString()} - {entity_player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
await QuestManager.It.QuestCheck(entity_player, new QuestChat(EQuestEventTargetType.CHAT, EQuestEventNameType.USED, chat_type.ToString(), request.Message));
return result;
}
private Result checkChatConditions(string message)
{
var result = new Result();
string err_msg;
// 1. 총 길이 체크
if (message.Length > MetaHelper.GameConfigMeta.ChatStringInputMax)
{
err_msg = $"fail to send chat !!! : invalid chat message length - {message.Length}";
result.setFail(ServerErrorCode.ChatInvalidMessageLength, err_msg);
Log.getLogger().error(err_msg);
return result;
}
// 2. 금칙어 체크 ( Client 에서 처리함 )
/*if (ServerUtil.isBanWorld(message, false))
{
err_msg = $"fail to send chat !!! : include ban word - {message}";
result.setFail(ServerErrorCode.ChatIncludeBanWord, err_msg);
Log.getLogger().error(err_msg);
return result;
}*/
return result;
}
public override async Task onProcessPacketException(ISession entityWithSession, IMessage recvMessage
, Result errorResult)
{
await Task.CompletedTask;
var player = entityWithSession as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!! - {entityWithSession.toBasicString()}");
var recv_msg = recvMessage as ClientToGame;
NullReferenceCheckHelper.throwIfNull(recv_msg, () => $"recv_msg is null !!! - {player.toBasicString()}");
var request = recv_msg.Request.ChatReq;
NullReferenceCheckHelper.throwIfNull(request, () => $"request is null !!! - {player.toBasicString()}");
send_S2C_ACK_CHAT(player, errorResult, request.ToNickName);
}
}

View File

@@ -0,0 +1,116 @@
using Newtonsoft.Json;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class RabbitNoticeChatHandler
{
public void MOS2GS_noticeChatSend(ServerMessage.Types.MOS2GS_NTF_NOTICE_CHAT chatMsg)
{
//OperationSystemNoticeChatType
Log.getLogger().debug("MOS2GS_noticeChatSend call start");
// 1. 메시지 체크
if (chatMsg == null)
{
var err_msg = $"chatMsg is null !!! : {nameof(ServerMessage.Types.MOS2GS_NTF_NOTICE_CHAT)}";
Log.getLogger().error(err_msg);
return;
}
//await server_logic.getNoticeChatManager().LoadDB();
var notice_type = chatMsg.NoticeType.ToString();
var chat_msgs = chatMsg.ChatMessage;
var senders = chatMsg.Sender;
Dictionary<int, string> dic_msg_by_lang = new();
Dictionary<int, string> dic_sender_by_lang = new();
foreach(var chat_msg in chat_msgs)
{
var txt = StringRuleHelper.convertStringFromBase64(chat_msg.Text);
dic_msg_by_lang.Add((int)chat_msg.LanguageType, txt);
}
foreach(var sender in senders)
{
var sender_txt = StringRuleHelper.convertStringFromBase64(sender.Text);
dic_sender_by_lang.Add((int)sender.LanguageType, sender_txt);
}
var server_logic = GameServerApp.getServerLogic();
var player_manager = server_logic.getPlayerManager();
// if (notice_type.Equals(OperationSystemNoticeChatType.CHATTING.ToString()))
// {
//일단 채팅이든 토스트든 전부 notice로 전달한다.
var users = player_manager.getUsers();
foreach (var user in users)
{
var player = user.Value;
var account_attribute = player.getEntityAttribute<AccountAttribute>();
if(account_attribute == null) continue;
if(dic_msg_by_lang.TryGetValue((int)account_attribute.LanguageType, out var chat_msg) == false)
{
var err_msg = $"dic_msg_by_lang error accountid : {account_attribute.AccountId}, langtype : {account_attribute.LanguageType}, {JsonConvert.SerializeObject(dic_msg_by_lang)}";
Log.getLogger().error(err_msg);
continue;
}
if (dic_sender_by_lang.TryGetValue((int)account_attribute.LanguageType, out var sender) == false)
{
var err_msg = $"dic_sender_by_lang error accountid : {account_attribute.AccountId}, langtype : {account_attribute.LanguageType}, {JsonConvert.SerializeObject(dic_sender_by_lang)}";
Log.getLogger().error(err_msg);
continue;
}
ChatNotifyHelper.send_S2C_NTF_CHAT(player, ChatType.Notice, sender, player.getUserNickname(), PlayerStateType.None, chat_msg);
}
Log.getLogger().debug($"MOS2GS_noticeChatSend call end userCount = {users.Count}, lang_msg : {JsonConvert.SerializeObject(dic_msg_by_lang)}, sender_msg : {JsonConvert.SerializeObject(dic_sender_by_lang)}");
// }
// else if (notice_type.Equals(OperationSystemNoticeChatType.CHATTING_TOAST.ToString()))
// {
// var err_msg = $"CHATTING_TOAST not implement !!!";
// return;
// }
//메시지에 대한 필터링을 어떻게 해야하지?
// 4. 채팅 처리
// switch (chat_type)
// {
// case ChatType.Normal:
// result = chat_action.NormalChat(request.Message);
// break;
// case ChatType.Channel:
// result = chat_action.ChannelChat(request.Message);
// break;
// case ChatType.Notice:
//result = chat_action.NoticeChat(request.Message);
// break;
// case ChatType.Whisper:
// result = await chat_action.WhisperChat(request.ToNickName, request.Message);
// break;
// case ChatType.Party:
// result = await chat_action.PartyChat(request.Message);
// break;
// if (result.isFail())
// {
// err_msg = $"Failed to trySendMail() !!! : {result.toBasicString()} - {entity_player.toBasicString()}";
// Log.getLogger().error(err_msg);
// return result;
// }
// return result;
}
}