/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package handling.channel.handler; import client.MapleCharacter; import client.MapleCharacterUtil; import client.MapleClient; import constants.ServerConstants.CommandType; import handling.channel.ChannelServer; import handling.world.MapleMessenger; import handling.world.MapleMessengerCharacter; import handling.world.World; import server.commands.CommandProcessor; import tools.data.LittleEndianAccessor; import tools.packet.CField; import tools.packet.CWvsContext; public class ChatHandler { public static void GeneralChat(final String text, final byte unk, final MapleClient c, final MapleCharacter chr) { if (text.length() > 0 && chr != null && chr.getMap() != null && !CommandProcessor.processCommand(c, text, CommandType.NORMAL)) { if (!chr.isIntern() && text.length() >= 80) { return; } if (chr.getCanTalk() || chr.isStaff()) { //Note: This patch is needed to prevent chat packet from being broadcast to people who might be packet sniffing. if (chr.isHidden()) { if (chr.isIntern() && !chr.isSuperGM() && unk == 0) { chr.getMap().broadcastGMMessage(chr, CField.getChatText(chr.getId(), text, c.getPlayer().isSuperGM(), (byte) 1), true); if (unk == 0) { chr.getMap().broadcastGMMessage(chr, CWvsContext.broadcastMsg(2, chr.getName() + " : " + text), true); } } else { chr.getMap().broadcastGMMessage(chr, CField.getChatText(chr.getId(), text, c.getPlayer().isSuperGM(), unk), true); } } else { chr.getCheatTracker().checkMsg(); if (chr.isIntern() && !chr.isSuperGM() && unk == 0) { //chr.getMap().broadcastMessage(CField.getChatText(chr.getId(), text, false, (byte) 1), c.getPlayer().getTruePosition()); chr.getMap().broadcastMessage(ColourChat(chr, text, unk, chr.getChatType())); chr.getMap().broadcastMessage(CField.getChatText(chr.getId(), text, c.getPlayer().isSuperGM(), 1)); /*if (unk == 0) { //chr.getMap().broadcastMessage(CWvsContext.broadcastMsg(2, chr.getName() + " : " + text), c.getPlayer().getTruePosition()); chr.getMap().broadcastMessage(ColourChat(chr, text, unk, chr.getChatType())); chr.getMap().broadcastMessage(CField.getChatText(chr.getId(), text, false, 1)); }*/ } else { //chr.getMap().broadcastMessage(CField.getChatText(chr.getId(), text, c.getPlayer().isSuperGM(), unk), c.getPlayer().getTruePosition()); chr.getMap().broadcastMessage(ColourChat(chr, text, unk, chr.getChatType())); chr.getMap().broadcastMessage(CField.getChatText(chr.getId(), text, c.getPlayer().isSuperGM(), 1));//was1 } } if (text.equalsIgnoreCase(c.getChannelServer().getServerName() + " rocks")) { chr.finishAchievement(11); } } else { c.getSession().write(CWvsContext.broadcastMsg(6, "You have been muted and are therefore unable to talk.")); } } } public static void AdminChat(final LittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) { if (!c.getPlayer().isGM()) {//if ( (signed int)CWvsContext::GetAdminLevel((void *)v294) > 2 ) return; } byte mode = slea.readByte(); //not saving slides... byte[] packet = CWvsContext.broadcastMsg(slea.readByte(), slea.readMapleAsciiString());//maybe I should make a check for the slea.readByte()... but I just hope gm's don't fuck things up :) switch (mode) { case 0:// /alertall, /noticeall, /slideall World.Broadcast.broadcastMessage(packet); break; case 1:// /alertch, /noticech, /slidech c.getChannelServer().broadcastMessage(packet); break; case 2:// /alertm /alertmap, /noticem /noticemap, /slidem /slidemap c.getPlayer().getMap().broadcastMessage(packet); break; } } public static byte[] ColourChat(final MapleCharacter chr, String text, final byte unk, short colour) { String rank = ""; switch (chr.getGMLevel()) { case 1: rank = "[Intern] "; //colour = 5; break; case 2: rank = "[GM] "; //colour = 1; break; case 3: rank = "[Head GM] "; //colour = 9; break; case 4: rank = "[Admin] "; //colour = 8; break; } if (chr.isDonator()) { colour = 13; if (rank.isEmpty()) { rank = "[Donor] "; } } byte[] packet; switch (colour) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: packet = CField.getGameMessage(rank + chr.getName() + " : " + text, colour); break; default: packet = CField.getChatText(chr.getId(), text, false, unk); } return packet; } public static void Others(final LittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) { final int type = slea.readByte(); final byte numRecipients = slea.readByte(); if (numRecipients <= 0) { return; } int recipients[] = new int[numRecipients]; for (byte i = 0; i < numRecipients; i++) { recipients[i] = slea.readInt(); } final String chattext = slea.readMapleAsciiString(); if (chr == null || !chr.getCanTalk()) { c.getSession().write(CWvsContext.broadcastMsg(6, "You have been muted and are therefore unable to talk.")); return; } if (c.isMonitored()) { String chattype = "Unknown"; switch (type) { case 0: chattype = "Buddy"; break; case 1: chattype = "Party"; break; case 2: chattype = "Guild"; break; case 3: chattype = "Alliance"; break; case 4: chattype = "Expedition"; break; } World.Broadcast.broadcastGMMessage( CWvsContext.broadcastMsg(6, "[GM Message] " + MapleCharacterUtil.makeMapleReadable(chr.getName()) + " said (" + chattype + "): " + chattext)); } if (chattext.length() <= 0 || CommandProcessor.processCommand(c, chattext, CommandType.NORMAL)) { return; } chr.getCheatTracker().checkMsg(); switch (type) { case 0: World.Buddy.buddyChat(recipients, chr.getId(), chr.getName(), chattext); break; case 1: if (chr.getParty() == null) { break; } World.Party.partyChat(chr.getParty().getId(), chattext, chr.getName()); break; case 2: if (chr.getGuildId() <= 0) { break; } World.Guild.guildChat(chr.getGuildId(), chr.getName(), chr.getId(), chattext); break; case 3: if (chr.getGuildId() <= 0) { break; } World.Alliance.allianceChat(chr.getGuildId(), chr.getName(), chr.getId(), chattext); break; case 4: if (chr.getParty().getExpeditionId() <= 0) { break; } World.Party.expedChat(chr.getParty().getExpeditionId(), chattext, chr.getName()); break; } } public static void Messenger(final LittleEndianAccessor slea, final MapleClient c) { String input; MapleMessenger messenger = c.getPlayer().getMessenger(); switch (slea.readByte()) { case 0x00: // open System.out.println("0"); if (messenger == null) { System.out.println("1"); slea.readByte(); byte mode = slea.readByte(); int messengerid = slea.readInt(); if (messengerid == 0) { // create System.out.println("2"); c.getPlayer().setMessenger(World.Messenger.createMessenger(new MapleMessengerCharacter(c.getPlayer()))); } else { // join System.out.println("3"); messenger = World.Messenger.getMessenger(messengerid); if (messenger != null) { System.out.println("4"); final int position = messenger.getLowestPosition(); if (position > -1 && position < 7) { System.out.println("5"); c.getPlayer().setMessenger(messenger); World.Messenger.joinMessenger(messenger.getId(), new MapleMessengerCharacter(c.getPlayer()), c.getPlayer().getName(), c.getChannel()); } } } } break; case 0x02: // exit if (messenger != null) { final MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(c.getPlayer()); World.Messenger.leaveMessenger(messenger.getId(), messengerplayer); c.getPlayer().setMessenger(null); } break; case 0x03: // invite if (messenger != null) { final int position = messenger.getLowestPosition(); if (position <= -1 || position >= 7) { return; } input = slea.readMapleAsciiString(); final MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(input); if (target != null) { if (target.getMessenger() == null) { if (!target.isIntern() || c.getPlayer().isIntern()) { c.getSession().write(CField.messengerNote(input, 4, 1)); target.getClient().getSession().write(CField.messengerInvite(c.getPlayer().getName(), messenger.getId())); } else { c.getSession().write(CField.messengerNote(input, 4, 0)); } } else { c.getSession().write(CField.messengerChat(c.getPlayer().getName(), " : " + target.getName() + " is already using Maple Messenger.")); } } else { if (World.isConnected(input)) { World.Messenger.messengerInvite(c.getPlayer().getName(), messenger.getId(), input, c.getChannel(), c.getPlayer().isIntern()); } else { c.getSession().write(CField.messengerNote(input, 4, 0)); } } } break; case 0x05: // decline final String targeted = slea.readMapleAsciiString(); final MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(targeted); if (target != null) { // This channel if (target.getMessenger() != null) { target.getClient().getSession().write(CField.messengerNote(c.getPlayer().getName(), 5, 0)); } } else { // Other channel if (!c.getPlayer().isIntern()) { World.Messenger.declineChat(targeted, c.getPlayer().getName()); } } break; case 0x06: // message if (messenger != null) { final String charname = slea.readMapleAsciiString(); final String text = slea.readMapleAsciiString(); if (!c.getPlayer().isIntern() && text.length() >= 1000) { return; } final String chattext = charname + "" + text; World.Messenger.messengerChat(messenger.getId(), charname, text, c.getPlayer().getName()); if (messenger.isMonitored() && chattext.length() > c.getPlayer().getName().length() + 3) { //name : NOT name0 or name1 World.Broadcast.broadcastGMMessage( CWvsContext.broadcastMsg( 6, "[GM Message] " + MapleCharacterUtil.makeMapleReadable(c.getPlayer().getName()) + "(Messenger: " + messenger.getMemberNamesDEBUG() + ") said: " + chattext)); } } break; case 0x09: //like if (messenger != null) { String charname = slea.readMapleAsciiString(); //todo send like packet here } break; case 0x0A: //guidance if (messenger != null) { slea.readByte(); String charname = slea.readMapleAsciiString(); String targetname = slea.readMapleAsciiString(); //todo send guide packet here } break; case 0x0B: //char info if (messenger != null) { String charname = slea.readMapleAsciiString(); MapleCharacter character = c.getChannelServer().getPlayerStorage().getCharacterByName(charname); c.getSession().write(CField.messengerCharInfo(character)); } break; case 0x0E: //whisper if (messenger != null) { String charname = slea.readMapleAsciiString(); //todo send whisper packet here } break; } } public static void Command(final LittleEndianAccessor slea, final MapleClient c) { final byte mode = slea.readByte(); slea.readInt(); //ticks switch (mode) { case 68: //buddy case 5: { // Find final String recipient = slea.readMapleAsciiString(); MapleCharacter player = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient); if (player != null) { if (!player.isIntern() || c.getPlayer().isIntern() && player.isIntern()) { c.getSession().write(CField.getFindReplyWithMap(player.getName(), player.getMap().getId(), mode == 72));//68 } else { c.getSession().write(CField.getWhisperReply(recipient, (byte) 0)); } } else { // Not found int ch = World.Find.findChannel(recipient); if (ch > 0) { player = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(recipient); if (player == null) { break; } if (player != null) { if (!player.isIntern() || (c.getPlayer().isIntern() && player.isIntern())) { c.getSession().write(CField.getFindReply(recipient, (byte) ch, mode == 68)); } else { c.getSession().write(CField.getWhisperReply(recipient, (byte) 0)); } return; } } if (ch == -10) { c.getSession().write(CField.getFindReplyWithCS(recipient, mode == 68)); } else { c.getSession().write(CField.getWhisperReply(recipient, (byte) 0)); } } break; } case 6: { // Whisper if (c.getPlayer() == null || c.getPlayer().getMap() == null) { return; } if (!c.getPlayer().getCanTalk()) { c.getSession().write(CWvsContext.broadcastMsg(6, "You have been muted and are therefore unable to talk.")); return; } c.getPlayer().getCheatTracker().checkMsg(); final String recipient = slea.readMapleAsciiString(); final String text = slea.readMapleAsciiString(); final int ch = World.Find.findChannel(recipient); if (!c.getPlayer().isIntern() && text.length() >= 80) { return; } if (ch > 0) { MapleCharacter player = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(recipient); if (player == null) { break; } player.getClient().getSession().write(CField.getWhisper(c.getPlayer().getName(), c.getChannel(), text)); if (!c.getPlayer().isIntern() && player.isIntern()) { c.getSession().write(CField.getWhisperReply(recipient, (byte) 0)); } else { c.getSession().write(CField.getWhisperReply(recipient, (byte) 1)); } if (c.isMonitored()) { World.Broadcast.broadcastGMMessage(CWvsContext.broadcastMsg(6, c.getPlayer().getName() + " whispered " + recipient + " : " + text)); } else if (player.getClient().isMonitored()) { World.Broadcast.broadcastGMMessage(CWvsContext.broadcastMsg(6, c.getPlayer().getName() + " whispered " + recipient + " : " + text)); } } else { c.getSession().write(CField.getWhisperReply(recipient, (byte) 0)); } } break; } } }