diff --git a/src/main/java/client/MapleCharacter.java b/src/main/java/client/MapleCharacter.java index 5434e00e2d..b1a57fbc5c 100644 --- a/src/main/java/client/MapleCharacter.java +++ b/src/main/java/client/MapleCharacter.java @@ -255,6 +255,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { private long lastExpGainTime; private boolean pendingNameChange; //only used to change name on logout, not to be relied upon elsewhere private long loginTime; + private boolean chasing = false; private MapleCharacter() { super.setListener(new AbstractCharacterListener() { @@ -11323,5 +11324,12 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public int getLanguage() { return getClient().getLanguage(); } - + + public boolean isChasing() { + return chasing; + } + + public void setChasing(boolean chasing) { + this.chasing = chasing; + } } diff --git a/src/main/java/net/server/channel/handlers/ChangeMapHandler.java b/src/main/java/net/server/channel/handlers/ChangeMapHandler.java index d3be7548ab..5ea0701d62 100644 --- a/src/main/java/net/server/channel/handlers/ChangeMapHandler.java +++ b/src/main/java/net/server/channel/handlers/ChangeMapHandler.java @@ -21,153 +21,160 @@ along with this program. If not, see . */ package net.server.channel.handlers; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Calendar; - -import net.AbstractMaplePacketHandler; import client.MapleCharacter; import client.MapleClient; import client.inventory.MapleInventoryType; import client.inventory.manipulator.MapleInventoryManipulator; -import server.maps.MaplePortal; +import net.AbstractMaplePacketHandler; import server.MapleTrade; import server.maps.MapleMap; +import server.maps.MaplePortal; import tools.FilePrinter; import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; +import java.awt.*; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Calendar; + public final class ChangeMapHandler extends AbstractMaplePacketHandler { - @Override - public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - MapleCharacter chr = c.getPlayer(); + @Override + public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + MapleCharacter chr = c.getPlayer(); - if (chr.isChangingMaps() || chr.isBanned()) { - if(chr.isChangingMaps()) { - FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps. Timestamp: " + Calendar.getInstance().getTime().toString() + " Last visited mapids: " + chr.getLastVisitedMapids()); + if (chr.isChangingMaps() || chr.isBanned()) { + if (chr.isChangingMaps()) { + FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps. Timestamp: " + Calendar.getInstance().getTime().toString() + " Last visited mapids: " + chr.getLastVisitedMapids()); + } + + c.announce(MaplePacketCreator.enableActions()); + return; + } + if (chr.getTrade() != null) { + MapleTrade.cancelTrade(chr, MapleTrade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); + } + if (slea.available() == 0) { //Cash Shop :) + if (!chr.getCashShop().isOpened()) { + c.disconnect(false, false); + return; + } + String[] socket = c.getChannelServer().getIP().split(":"); + chr.getCashShop().open(false); + + chr.setSessionTransitionState(); + try { + c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]))); + } catch (UnknownHostException ex) { + ex.printStackTrace(); + } + } else { + if (chr.getCashShop().isOpened()) { + c.disconnect(false, false); + return; + } + try { + slea.readByte(); // 1 = from dying 0 = regular portals + int targetid = slea.readInt(); + String startwp = slea.readMapleAsciiString(); + MaplePortal portal = chr.getMap().getPortal(startwp); + slea.readByte(); + boolean wheel = slea.readByte() > 0; + + boolean chasing = slea.readByte() == 1 && chr.isGM(); + if (chasing) { + chr.setChasing(true); + chr.setPosition(new Point(slea.readInt(), slea.readInt())); + } + + if (targetid != -1) { + if (!chr.isAlive()) { + MapleMap map = chr.getMap(); + if (wheel && chr.haveItemWithId(5510000, false)) { + // thanks lucasziron (lziron) for showing revivePlayer() triggering by Wheel + + MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, 5510000, 1, true, false); + chr.announce(MaplePacketCreator.showWheelsLeft(chr.getItemQuantity(5510000, false))); + + chr.updateHp(50); + chr.changeMap(map, map.findClosestPlayerSpawnpoint(chr.getPosition())); + } else { + boolean executeStandardPath = true; + if (chr.getEventInstance() != null) { + executeStandardPath = chr.getEventInstance().revivePlayer(chr); + } + if (executeStandardPath) { + chr.respawn(map.getReturnMapId()); + } } - - c.announce(MaplePacketCreator.enableActions()); - return; - } - if (chr.getTrade() != null) { - MapleTrade.cancelTrade(chr, MapleTrade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); - } - if (slea.available() == 0) { //Cash Shop :) - if(!chr.getCashShop().isOpened()) { - c.disconnect(false, false); - return; - } - String[] socket = c.getChannelServer().getIP().split(":"); - chr.getCashShop().open(false); - - chr.setSessionTransitionState(); - try { - c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]))); - } catch (UnknownHostException ex) { - ex.printStackTrace(); - } - } else { - if(chr.getCashShop().isOpened()) { - c.disconnect(false, false); - return; - } - try { - slea.readByte(); // 1 = from dying 0 = regular portals - int targetid = slea.readInt(); - String startwp = slea.readMapleAsciiString(); - MaplePortal portal = chr.getMap().getPortal(startwp); - slea.readByte(); - boolean wheel = slea.readShort() > 0; - - if (targetid != -1) { - if (!chr.isAlive()) { - MapleMap map = chr.getMap(); - if (wheel && chr.haveItemWithId(5510000, false)) { - // thanks lucasziron (lziron) for showing revivePlayer() triggering by Wheel - - MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, 5510000, 1, true, false); - chr.announce(MaplePacketCreator.showWheelsLeft(chr.getItemQuantity(5510000, false))); - - chr.updateHp(50); - chr.changeMap(map, map.findClosestPlayerSpawnpoint(chr.getPosition())); - } else { - boolean executeStandardPath = true; - if (chr.getEventInstance() != null) { - executeStandardPath = chr.getEventInstance().revivePlayer(chr); - } - if (executeStandardPath) { - chr.respawn(map.getReturnMapId()); - } - } - } else { - if (chr.isGM()) { - MapleMap to = chr.getWarpMap(targetid); - chr.changeMap(to, to.getPortal(0)); - } else { - final int divi = chr.getMapId() / 100; - boolean warp = false; - if (divi == 0) { - if (targetid == 10000) { - warp = true; - } - } else if (divi == 20100) { - if (targetid == 104000000) { - c.announce(MaplePacketCreator.lockUI(false)); - c.announce(MaplePacketCreator.disableUI(false)); - warp = true; - } - } else if (divi == 9130401) { // Only allow warp if player is already in Intro map, or else = hack - if (targetid == 130000000 || targetid / 100 == 9130401) { // Cygnus introduction - warp = true; - } - } else if (divi == 9140900) { // Aran Introduction - if (targetid == 914090011 || targetid == 914090012 || targetid == 914090013 || targetid == 140090000) { - warp = true; - } - } else if (divi / 10 == 1020) { // Adventurer movie clip Intro - if (targetid == 1020000) { - warp = true; - } - } else if(divi / 10 >= 980040 && divi / 10 <= 980045) { - if(targetid == 980040000) { - warp = true; - } - } - if (warp) { - final MapleMap to = chr.getWarpMap(targetid); - chr.changeMap(to, to.getPortal(0)); - } - } - } + } else { + if (chr.isGM()) { + MapleMap to = chr.getWarpMap(targetid); + chr.changeMap(to, to.getPortal(0)); + } else { + final int divi = chr.getMapId() / 100; + boolean warp = false; + if (divi == 0) { + if (targetid == 10000) { + warp = true; } - - if (portal != null && !portal.getPortalStatus()) { - c.announce(MaplePacketCreator.blockedMessage(1)); - c.announce(MaplePacketCreator.enableActions()); - return; - } - - if (chr.getMapId() == 109040004) { - chr.getFitness().resetTimes(); - } else if (chr.getMapId() == 109030003 || chr.getMapId() == 109030103) { - chr.getOla().resetTimes(); - } - - if (portal != null) { - if(portal.getPosition().distanceSq(chr.getPosition()) > 400000) { - c.announce(MaplePacketCreator.enableActions()); - return; - } - - portal.enterPortal(c); - } else { - c.announce(MaplePacketCreator.enableActions()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } + } else if (divi == 20100) { + if (targetid == 104000000) { + c.announce(MaplePacketCreator.lockUI(false)); + c.announce(MaplePacketCreator.disableUI(false)); + warp = true; + } + } else if (divi == 9130401) { // Only allow warp if player is already in Intro map, or else = hack + if (targetid == 130000000 || targetid / 100 == 9130401) { // Cygnus introduction + warp = true; + } + } else if (divi == 9140900) { // Aran Introduction + if (targetid == 914090011 || targetid == 914090012 || targetid == 914090013 || targetid == 140090000) { + warp = true; + } + } else if (divi / 10 == 1020) { // Adventurer movie clip Intro + if (targetid == 1020000) { + warp = true; + } + } else if (divi / 10 >= 980040 && divi / 10 <= 980045) { + if (targetid == 980040000) { + warp = true; + } + } + if (warp) { + final MapleMap to = chr.getWarpMap(targetid); + chr.changeMap(to, to.getPortal(0)); + } + } + } + } + + if (portal != null && !portal.getPortalStatus()) { + c.announce(MaplePacketCreator.blockedMessage(1)); + c.announce(MaplePacketCreator.enableActions()); + return; + } + + if (chr.getMapId() == 109040004) { + chr.getFitness().resetTimes(); + } else if (chr.getMapId() == 109030003 || chr.getMapId() == 109030103) { + chr.getOla().resetTimes(); + } + + if (portal != null) { + if (portal.getPosition().distanceSq(chr.getPosition()) > 400000) { + c.announce(MaplePacketCreator.enableActions()); + return; + } + + portal.enterPortal(c); + } else { + c.announce(MaplePacketCreator.enableActions()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } } \ No newline at end of file diff --git a/src/main/java/net/server/channel/handlers/WhisperHandler.java b/src/main/java/net/server/channel/handlers/WhisperHandler.java index 6799f2524d..1d622d16ff 100644 --- a/src/main/java/net/server/channel/handlers/WhisperHandler.java +++ b/src/main/java/net/server/channel/handlers/WhisperHandler.java @@ -26,121 +26,86 @@ import client.MapleClient; import client.autoban.AutobanFactory; import config.YamlConfig; import net.AbstractMaplePacketHandler; -import net.server.world.World; -import tools.DatabaseConnection; import tools.FilePrinter; import tools.LogHelper; import tools.MaplePacketCreator; +import tools.MaplePacketCreator.WhisperFlag; import tools.data.input.SeekableLittleEndianAccessor; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - /** - * - * @author Matze + * @author Chronos */ public final class WhisperHandler extends AbstractMaplePacketHandler { - - @Override - public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - byte mode = slea.readByte(); - if (mode == 6) { // whisper - String recipient = slea.readMapleAsciiString(); - String text = slea.readMapleAsciiString(); - MapleCharacter player = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient); - if (c.getPlayer().getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) { - return; - } - if (text.length() > Byte.MAX_VALUE && !player.isGM()) { - AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with whispers."); - FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + text.length()); - c.disconnect(true, false); - return; - } - if (player != null) { - player.getClient().announce(MaplePacketCreator.getWhisper(c.getPlayer().getName(), c.getChannel(), text)); - if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) { - LogHelper.logChat(c, "Whisper To " + player.getName(), text); - } - if(player.isHidden() && player.gmLevel() >= c.getPlayer().gmLevel()) { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - } else { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 1)); - } - } else {// not found - World world = c.getWorldServer(); - if (world.isConnected(recipient)) { - world.whisper(c.getPlayer().getName(), recipient, c.getChannel(), text); - if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) { - LogHelper.logChat(c, "Whisper To " + recipient, text); - } - player = world.getPlayerStorage().getCharacterByName(recipient); - if(player.isHidden() && player.gmLevel() >= c.getPlayer().gmLevel()) - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - else - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 1)); - } else { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - } - } - c.getPlayer().getAutobanManager().spam(7); - } else if (mode == 5) { // - /find - String recipient = slea.readMapleAsciiString(); - MapleCharacter victim = c.getWorldServer().getPlayerStorage().getCharacterByName(recipient); - if (victim != null && c.getPlayer().gmLevel() >= victim.gmLevel()) { - if (victim.getCashShop().isOpened()) { // in CashShop - c.announce(MaplePacketCreator.getFindReply(victim.getName(), -1, 2)); - } else if (victim.isAwayFromWorld()) { // in MTS - c.announce(MaplePacketCreator.getFindReply(victim.getName(), -1, 0)); - } else if (victim.getClient().getChannel() != c.getChannel()) { // in another channel, issue detected thanks to MedicOP - c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getClient().getChannel() - 1, 3)); - } else { - c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getMap().getId(), 1)); - } - } else if (c.getPlayer().isGM()) { // not found - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT gm FROM characters WHERE name = ?")) { - ps.setString(1, recipient); - try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - if (rs.getInt("gm") >= c.getPlayer().gmLevel()) { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - return; - } - } - } - byte channel = (byte) (c.getWorldServer().find(recipient) - 1); - if (channel > -1) { - c.announce(MaplePacketCreator.getFindReply(recipient, channel, 3)); - } else { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } else { - c.announce(MaplePacketCreator.getWhisperReply(recipient, (byte) 0)); - } - } else if (mode == 0x44) { - //Buddy find, thanks to Atoot - - String recipient = slea.readMapleAsciiString(); - MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterByName(recipient); - if (player != null && c.getPlayer().gmLevel() >= player.gmLevel()) { - if (player.getCashShop().isOpened()) { // in CashShop - c.announce(MaplePacketCreator.getBuddyFindReply(player.getName(), -1, 2)); - } else if (player.isAwayFromWorld()) { // in MTS - c.announce(MaplePacketCreator.getBuddyFindReply(player.getName(), -1, 0)); - } else if (player.getClient().getChannel() != c.getChannel()) { // in another channel - c.announce(MaplePacketCreator.getBuddyFindReply(player.getName(), player.getClient().getChannel() - 1, 3)); - } else { - c.announce(MaplePacketCreator.getBuddyFindReply(player.getName(), player.getMap().getId(), 1)); - } - } + // result types, not sure if there are proper names for these + public static final byte RT_ITC = 0x00; + public static final byte RT_SAME_CHANNEL = 0x01; + public static final byte RT_CASH_SHOP = 0x02; + public static final byte RT_DIFFERENT_CHANNEL = 0x03; + + @Override + public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + byte request = slea.readByte(); + String name = slea.readMapleAsciiString(); + MapleCharacter target = c.getWorldServer().getPlayerStorage().getCharacterByName(name); + + if (target == null) { + c.announce(MaplePacketCreator.getWhisperResult(name, false)); + return; + } + + switch (request) { + case WhisperFlag.LOCATION | WhisperFlag.REQUEST: + handleFind(c.getPlayer(), target, WhisperFlag.LOCATION); + break; + case WhisperFlag.WHISPER | WhisperFlag.REQUEST: + String message = slea.readMapleAsciiString(); + handleWhisper(message, c.getPlayer(), target); + break; + case WhisperFlag.LOCATION_FRIEND | WhisperFlag.REQUEST: + handleFind(c.getPlayer(), target, WhisperFlag.LOCATION_FRIEND); + break; + default: + FilePrinter.printError(FilePrinter.PACKET_HANDLER + c.getPlayer().getName() + ".txt", "Unknown request " + request + " triggered by " + c.getPlayer().getName()); + break; } } + + private void handleFind(MapleCharacter user, MapleCharacter target, byte flag) { + if (user.gmLevel() >= target.gmLevel()) { + if (target.getCashShop().isOpened()) { + user.announce(MaplePacketCreator.getFindResult(target, RT_CASH_SHOP, -1, flag)); + } else if (target.getClient().getChannel() == user.getClient().getChannel()) { + user.announce(MaplePacketCreator.getFindResult(target, RT_SAME_CHANNEL, target.getMapId(), flag)); + } else { + user.announce(MaplePacketCreator.getFindResult(target, RT_DIFFERENT_CHANNEL, target.getClient().getChannel() - 1, flag)); + } + } else { + // not found for whisper is the same message + user.announce(MaplePacketCreator.getWhisperResult(target.getName(), false)); + } + } + + private void handleWhisper(String message, MapleCharacter user, MapleCharacter target) { + if (user.getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) { + return; + } + user.getAutobanManager().spam(7); + + if (message.length() > Byte.MAX_VALUE) { + AutobanFactory.PACKET_EDIT.alert(user, user.getName() + " tried to packet edit with whispers."); + FilePrinter.printError(FilePrinter.EXPLOITS + user.getName() + ".txt", user.getName() + " tried to send text with length of " + message.length()); + user.getClient().disconnect(true, false); + return; + } + + if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) { + LogHelper.logChat(user.getClient(), "Whisper To " + target.getName(), message); + } + + target.announce(MaplePacketCreator.getWhisperReceive(user.getName(), user.getClient().getChannel() - 1, user.isGM(), message)); + + boolean hidden = target.isHidden() && target.gmLevel() > user.gmLevel(); + user.announce(MaplePacketCreator.getWhisperResult(target.getName(), !hidden)); + } } diff --git a/src/main/java/net/server/world/World.java b/src/main/java/net/server/world/World.java index 7fb78eb2fe..c4fb749fa6 100644 --- a/src/main/java/net/server/world/World.java +++ b/src/main/java/net/server/world/World.java @@ -1190,12 +1190,6 @@ public class World { return getPlayerStorage().getCharacterByName(charName) != null; } - public void whisper(String sender, String target, int channel, String message) { - if (isConnected(target)) { - getPlayerStorage().getCharacterByName(target).getClient().announce(MaplePacketCreator.getWhisper(sender, channel, message)); - } - } - public BuddyAddResult requestBuddyAdd(String addName, int channelFrom, int cidFrom, String nameFrom) { MapleCharacter addChar = getPlayerStorage().getCharacterByName(addName); if (addChar != null) { diff --git a/src/main/java/tools/MaplePacketCreator.java b/src/main/java/tools/MaplePacketCreator.java index c84994030b..1c321610d5 100644 --- a/src/main/java/tools/MaplePacketCreator.java +++ b/src/main/java/tools/MaplePacketCreator.java @@ -43,6 +43,7 @@ import net.server.Server; import net.server.channel.Channel; import net.server.channel.handlers.PlayerInteractionHandler; import net.server.channel.handlers.SummonDamageHandler.SummonAttackEntry; +import net.server.channel.handlers.WhisperHandler; import net.server.guild.MapleAlliance; import net.server.guild.MapleGuild; import net.server.guild.MapleGuildCharacter; @@ -1038,7 +1039,12 @@ public class MaplePacketCreator { mplew.writeInt(to.getId()); mplew.write(spawnPoint); mplew.writeShort(chr.getHp()); - mplew.writeBool(false); + mplew.writeBool(chr.isChasing()); + if (chr.isChasing()) { + chr.setChasing(false); + mplew.writeInt(chr.getPosition().x); + mplew.writeInt(chr.getPosition().y); + } mplew.writeLong(getTime(Server.getInstance().getCurrentTime())); return mplew.getPacket(); } @@ -3671,31 +3677,6 @@ public class MaplePacketCreator { return pOutPacket.getPacket(); } - public static byte[] getWhisper(String sender, int channel, String text) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.WHISPER.getValue()); - mplew.write(0x12); - mplew.writeMapleAsciiString(sender); - mplew.writeShort(channel - 1); // I guess this is the channel - mplew.writeMapleAsciiString(text); - return mplew.getPacket(); - } - - /** - * - * @param target name of the target character - * @param reply error code: 0x0 = cannot find char, 0x1 = success - * @return the MaplePacket - */ - public static byte[] getWhisperReply(String target, byte reply) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.WHISPER.getValue()); - mplew.write(0x0A); // whisper? - mplew.writeMapleAsciiString(target); - mplew.write(reply); - return mplew.getPacket(); - } - public static byte[] getInventoryFull() { return modifyInventory(true, Collections.emptyList()); } @@ -6359,43 +6340,64 @@ public class MaplePacketCreator { return showCash(mc); } - /** - * - * @param target - * @param mapid - * @param MTSmapCSchannel 0: MTS 1: Map 2: CS 3: Different Channel - * @return - */ - public static byte[] getFindReply(String target, int mapid, int MTSmapCSchannel) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.WHISPER.getValue()); - mplew.write(9); - mplew.writeMapleAsciiString(target); - mplew.write(MTSmapCSchannel); // 0: mts 1: map 2: cs - mplew.writeInt(mapid); // -1 if mts, cs - if (MTSmapCSchannel == 1) { - mplew.write(new byte[8]); - } - return mplew.getPacket(); + public static class WhisperFlag { + public static final byte LOCATION = 0x01; + public static final byte WHISPER = 0x02; + public static final byte REQUEST = 0x04; + public static final byte RESULT = 0x08; + public static final byte RECEIVE = 0x10; + public static final byte BLOCKED = 0x20; + public static final byte LOCATION_FRIEND = 0x40; } /** + * User for /find, buddy find and /c (chase) + * CField::OnWhisper * - * @param target - * @param mapid - * @param MTSmapCSchannel 0: MTS 1: Map 2: CS 3: Different Channel - * @return + * @param target Name String from the command parameter + * @param type Location of the target + * @param fieldOrChannel If true & chr is not null, shows different channel message + * @param flag LOCATION or LOCATION_FRIEND + * @return packet structure */ - public static byte[] getBuddyFindReply(String target, int mapid, int MTSmapCSchannel) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + public static byte[] getFindResult(MapleCharacter target, byte type, int fieldOrChannel, byte flag) { + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.WHISPER.getValue()); - mplew.write(72); - mplew.writeMapleAsciiString(target); - mplew.write(MTSmapCSchannel); // 0: mts 1: map 2: cs - mplew.writeInt(mapid); // -1 if mts, cs - if (MTSmapCSchannel == 1) { - mplew.write(new byte[8]); + + mplew.write(flag | WhisperFlag.RESULT); + mplew.writeMapleAsciiString(target.getName()); + mplew.write(type); + mplew.writeInt(fieldOrChannel); + + if (type == WhisperHandler.RT_SAME_CHANNEL) { + mplew.writeInt(target.getPosition().x); + mplew.writeInt(target.getPosition().y); } + + return mplew.getPacket(); + } + + public static byte[] getWhisperResult(String target, boolean success) { + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + mplew.writeShort(SendOpcode.WHISPER.getValue()); + + mplew.write(WhisperFlag.WHISPER | WhisperFlag.RESULT); + mplew.writeMapleAsciiString(target); + mplew.writeBool(success); + + return mplew.getPacket(); + } + + public static byte[] getWhisperReceive(String sender, int channel, boolean fromAdmin, String message) { + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + mplew.writeShort(SendOpcode.WHISPER.getValue()); + + mplew.write(WhisperFlag.WHISPER | WhisperFlag.RECEIVE); + mplew.writeMapleAsciiString(sender); + mplew.write(channel); + mplew.writeBool(fromAdmin); + mplew.writeMapleAsciiString(message); + return mplew.getPacket(); }