Disconnect client by throwing exception in handler
This makes it easier to add checks in handlers, which should improve security over time. I think this approach is more readable and testable than calling Client#disconnect straight up, while it also decentralizes the handling.
This commit is contained in:
@@ -29,6 +29,8 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import net.PacketHandler;
|
||||
import net.PacketProcessor;
|
||||
import net.netty.DisconnectException;
|
||||
import net.netty.GameViolationException;
|
||||
import net.netty.InvalidPacketHeaderException;
|
||||
import net.packet.InPacket;
|
||||
import net.packet.Packet;
|
||||
@@ -201,6 +203,8 @@ public class Client extends ChannelInboundHandlerAdapter {
|
||||
try {
|
||||
MonitoredChrLogger.logPacketIfMonitored(this, opcode, packet.getBytes());
|
||||
handler.handlePacket(packet, this);
|
||||
} catch (GameViolationException gve) {
|
||||
throw new DisconnectException(this, gve.getMessage());
|
||||
} catch (final Throwable t) {
|
||||
final String chrInfo = player != null ? player.getName() + " on map " + player.getMapId() : "?";
|
||||
log.warn("Error in packet handler {}. Chr {}, account {}. Packet: {}", handler.getClass().getSimpleName(),
|
||||
@@ -229,6 +233,8 @@ public class Client extends ChannelInboundHandlerAdapter {
|
||||
SessionCoordinator.getInstance().closeSession(this, true);
|
||||
} else if (cause instanceof IOException) {
|
||||
closeMapleSession();
|
||||
} else {
|
||||
ctx.fireExceptionCaught(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1018,7 +1024,7 @@ public class Client extends ChannelInboundHandlerAdapter {
|
||||
//getChannelServer().removePlayer(player); already being done
|
||||
|
||||
player.cancelAllDebuffs();
|
||||
player.saveCharToDB(true);
|
||||
player.saveCharToDB();
|
||||
|
||||
player.logOff();
|
||||
if (YamlConfig.config.server.INSTANT_NAME_CHANGE) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import client.inventory.manipulator.KarmaManipulator;
|
||||
import config.YamlConfig;
|
||||
import constants.id.ItemId;
|
||||
import constants.inventory.ItemConstants;
|
||||
import net.netty.GameViolationException;
|
||||
import net.server.channel.Channel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -296,24 +297,22 @@ public class DueyProcessor {
|
||||
if (sendMessage != null && sendMessage.length() > 100) {
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with Quick Delivery on duey.");
|
||||
log.warn("Chr {} tried to use duey with too long of a text", c.getPlayer().getName());
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw GameViolationException.textLength(sendMessage);
|
||||
}
|
||||
|
||||
if (!quick) {
|
||||
fee += 5000;
|
||||
} else if (!c.getPlayer().haveItem(ItemId.QUICK_DELIVERY_TICKET)) {
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with Quick Delivery on duey.");
|
||||
log.warn("Chr {} tried to use duey with Quick Delivery without a ticket, mesos {} and amount {}", c.getPlayer().getName(), sendMesos, amount);
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw new GameViolationException("Send Duey quick delivery without having a ticket");
|
||||
}
|
||||
|
||||
long finalcost = (long) sendMesos + fee;
|
||||
if (finalcost < 0 || finalcost > Integer.MAX_VALUE || (amount < 1 && sendMesos == 0)) {
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with duey.");
|
||||
log.warn("Chr {} tried to use duey with mesos {} and amount {}", c.getPlayer().getName(), sendMesos, amount);
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw new GameViolationException("Send invalid mesos with duey");
|
||||
}
|
||||
|
||||
if(c.getPlayer().getMeso() < finalcost) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import client.inventory.manipulator.KarmaManipulator;
|
||||
import config.YamlConfig;
|
||||
import constants.id.ItemId;
|
||||
import constants.inventory.ItemConstants;
|
||||
import net.netty.GameViolationException;
|
||||
import net.packet.InPacket;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -69,8 +70,7 @@ public class StorageProcessor {
|
||||
if (slot < 0 || slot > storage.getSlots()) { // removal starts at zero
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with storage.");
|
||||
log.warn("Chr {} tried to work with storage slot {}", c.getPlayer().getName(), slot);
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw new GameViolationException("Withdraw item from invalid slot");
|
||||
}
|
||||
|
||||
slot = storage.getSlot(InventoryType.getByType(type), slot);
|
||||
@@ -128,8 +128,7 @@ public class StorageProcessor {
|
||||
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(),
|
||||
c.getPlayer().getName() + " tried to packet edit with storage.");
|
||||
log.warn("Chr {} tried to store item at slot {}", c.getPlayer().getName(), slot);
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw new GameViolationException("Store item at invalid slot");
|
||||
}
|
||||
|
||||
if (hasGMRestrictions(chr)) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import config.YamlConfig;
|
||||
import constants.skills.*;
|
||||
import net.netty.GameViolationException;
|
||||
import net.packet.InPacket;
|
||||
import tools.PacketCreator;
|
||||
import tools.Randomizer;
|
||||
@@ -385,9 +386,7 @@ public class AssignAPProcessor {
|
||||
} else {
|
||||
if (inPacket.available() < 16) {
|
||||
AutobanFactory.PACKET_EDIT.alert(chr, "Didn't send full packet for Auto Assign.");
|
||||
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
throw new GameViolationException("Auto Assign packet is too small");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import client.SkillFactory;
|
||||
import client.autoban.AutobanFactory;
|
||||
import constants.game.GameConstants;
|
||||
import constants.skills.Aran;
|
||||
import net.netty.GameViolationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.PacketCreator;
|
||||
@@ -50,9 +51,7 @@ public class AssignSPProcessor {
|
||||
if ((!GameConstants.isPqSkillMap(player.getMapId()) && GameConstants.isPqSkill(skillid)) || (!player.isGM() && GameConstants.isGMSkills(skillid)) || (!GameConstants.isInJobTree(skillid, player.getJob().getId()) && !player.isGM())) {
|
||||
AutobanFactory.PACKET_EDIT.alert(player, "tried to packet edit in distributing sp.");
|
||||
log.warn("Chr {} tried to use skill {} without it being in their job.", c.getPlayer().getName(), skillid);
|
||||
|
||||
c.disconnect(true, false);
|
||||
return false;
|
||||
throw new GameViolationException("Assign SP into invalid skill");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user