Merge pull request #23 from RubenD96/master

Complete rework of WhisperHandler including proper chase functionality
This commit is contained in:
Ponk
2021-08-19 11:57:49 +02:00
committed by GitHub
5 changed files with 279 additions and 303 deletions

View File

@@ -21,153 +21,160 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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();
}
}
}
}

View File

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

View File

@@ -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) {