Files
2025-05-01 07:20:41 +09:00

181 lines
7.1 KiB
C#

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);
}
}