From cd75e85beca037d7dfc518d09162c72d26ab15a6 Mon Sep 17 00:00:00 2001 From: P0nk Date: Thu, 10 Aug 2023 22:48:10 +0200 Subject: [PATCH] Move some autoban logic to new BanService --- src/main/java/client/Character.java | 19 +----- .../java/client/autoban/AutobanFactory.java | 11 ---- .../java/client/autoban/AutobanManager.java | 44 ++++++------- src/main/java/net/ChannelDependencies.java | 5 +- src/main/java/net/PacketProcessor.java | 14 ++--- src/main/java/net/server/Server.java | 5 +- .../handlers/AbstractDealDamageHandler.java | 17 ++--- .../handlers/CloseRangeDamageHandler.java | 5 +- .../channel/handlers/HealOvertimeHandler.java | 13 +++- .../channel/handlers/MagicDamageHandler.java | 5 +- .../channel/handlers/RangedAttackHandler.java | 5 +- .../channel/handlers/SummonDamageHandler.java | 5 +- .../handlers/TouchMonsterDamageHandler.java | 5 +- .../channel/handlers/UseGachaExpHandler.java | 9 ++- src/main/java/service/BanService.java | 62 +++++++++++++++++++ 15 files changed, 139 insertions(+), 85 deletions(-) create mode 100644 src/main/java/service/BanService.java diff --git a/src/main/java/client/Character.java b/src/main/java/client/Character.java index a34b73114d..b8369e2de4 100644 --- a/src/main/java/client/Character.java +++ b/src/main/java/client/Character.java @@ -644,7 +644,7 @@ public class Character extends AbstractCharacterObject { } public void ban(String reason) { - this.isbanned = true; + setBanned(); try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("UPDATE accounts SET banned = 1, banreason = ? WHERE id = ?")) { ps.setString(1, reason); @@ -10015,23 +10015,6 @@ public class Character extends AbstractCharacterObject { return area_info; } - public void autoban(String reason) { - if (this.isGM() || this.isBanned()) { // thanks RedHat for noticing GM's being able to get banned - return; - } - - this.ban(reason); - sendPacket(PacketCreator.sendPolice(String.format("You have been blocked by the#b %s Police for HACK reason.#k", "Cosmic"))); - TimerManager.getInstance().schedule(new Runnable() { - @Override - public void run() { - client.disconnect(false, false); - } - }, 5000); - - Server.getInstance().broadcastGMMessage(this.getWorld(), PacketCreator.serverNotice(6, Character.makeMapleReadable(this.name) + " was autobanned for " + reason)); - } - public void block(int reason, int days, String desc) { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, days); diff --git a/src/main/java/client/autoban/AutobanFactory.java b/src/main/java/client/autoban/AutobanFactory.java index 811fd7410c..7cd23af41c 100644 --- a/src/main/java/client/autoban/AutobanFactory.java +++ b/src/main/java/client/autoban/AutobanFactory.java @@ -88,10 +88,6 @@ public enum AutobanFactory { return expiretime; } - public void addPoint(AutobanManager ban, String reason) { - ban.addPoint(this, reason); - } - public void alert(Character chr, String reason) { if (YamlConfig.config.server.USE_AUTOBAN) { if (chr != null && isIgnored(chr.getId())) { @@ -105,13 +101,6 @@ public enum AutobanFactory { } } - public void autoban(Character chr, String value) { - if (YamlConfig.config.server.USE_AUTOBAN) { - chr.autoban("Autobanned for (" + this.name() + ": " + value + ")"); - //chr.sendPolice("You will be disconnected for (" + this.name() + ": " + value + ")"); - } - } - /** * Toggle ignored status for a character id. * An ignored character will not trigger GM alerts. diff --git a/src/main/java/client/autoban/AutobanManager.java b/src/main/java/client/autoban/AutobanManager.java index 9232799439..ca2a4c1105 100644 --- a/src/main/java/client/autoban/AutobanManager.java +++ b/src/main/java/client/autoban/AutobanManager.java @@ -36,35 +36,27 @@ public class AutobanManager { this.chr = chr; } - public void addPoint(AutobanFactory fac, String reason) { - if (YamlConfig.config.server.USE_AUTOBAN) { - if (chr.isGM() || chr.isBanned()) { - return; - } - - if (lastTime.containsKey(fac)) { - if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) { - points.put(fac, points.get(fac) / 2); //So the points are not completely gone. - } - } - if (fac.getExpire() != -1) { - lastTime.put(fac, Server.getInstance().getCurrentTime()); - } - - if (points.containsKey(fac)) { - points.put(fac, points.get(fac) + 1); - } else { - points.put(fac, 1); - } - - if (points.get(fac) >= fac.getMaximum()) { - chr.autoban(reason); + /** + * @return true if the added point should result in an autoban + */ + public boolean addPoint(AutobanFactory fac) { + if (lastTime.containsKey(fac)) { + if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) { + points.put(fac, points.get(fac) / 2); //So the points are not completely gone. } } - if (YamlConfig.config.server.USE_AUTOBAN_LOG) { - // Lets log every single point too. - log.info("Autoban - chr {} caused {} {}", Character.makeMapleReadable(chr.getName()), fac.name(), reason); + + if (fac.getExpire() != -1) { + lastTime.put(fac, Server.getInstance().getCurrentTime()); } + + if (points.containsKey(fac)) { + points.put(fac, points.get(fac) + 1); + } else { + points.put(fac, 1); + } + + return points.get(fac) >= fac.getMaximum(); } public void addMiss() { diff --git a/src/main/java/net/ChannelDependencies.java b/src/main/java/net/ChannelDependencies.java index 59597e105d..5b96fc2814 100644 --- a/src/main/java/net/ChannelDependencies.java +++ b/src/main/java/net/ChannelDependencies.java @@ -7,6 +7,7 @@ import database.character.CharacterLoader; import database.character.CharacterSaver; import database.drop.DropProvider; import server.shop.ShopFactory; +import service.BanService; import service.NoteService; import service.TransitionService; @@ -18,7 +19,8 @@ import java.util.Objects; public record ChannelDependencies( CharacterLoader characterLoader, CharacterSaver characterSaver, NoteService noteService, FredrickProcessor fredrickProcessor, MakerProcessor makerProcessor, DropProvider dropProvider, - CommandsExecutor commandsExecutor, ShopFactory shopFactory, TransitionService transitionService + CommandsExecutor commandsExecutor, ShopFactory shopFactory, TransitionService transitionService, + BanService banService ) { public ChannelDependencies { @@ -31,5 +33,6 @@ public record ChannelDependencies( Objects.requireNonNull(commandsExecutor); Objects.requireNonNull(shopFactory); Objects.requireNonNull(transitionService); + Objects.requireNonNull(banService); } } diff --git a/src/main/java/net/PacketProcessor.java b/src/main/java/net/PacketProcessor.java index c48cbacfb7..d038dc12b5 100644 --- a/src/main/java/net/PacketProcessor.java +++ b/src/main/java/net/PacketProcessor.java @@ -156,9 +156,9 @@ public final class PacketProcessor { channelDeps.noteService())); registerHandler(RecvOpcode.CHANGE_MAP, new ChangeMapHandler()); registerHandler(RecvOpcode.MOVE_LIFE, new MoveLifeHandler()); - registerHandler(RecvOpcode.CLOSE_RANGE_ATTACK, new CloseRangeDamageHandler(channelDeps.dropProvider())); - registerHandler(RecvOpcode.RANGED_ATTACK, new RangedAttackHandler(channelDeps.dropProvider())); - registerHandler(RecvOpcode.MAGIC_ATTACK, new MagicDamageHandler(channelDeps.dropProvider())); + registerHandler(RecvOpcode.CLOSE_RANGE_ATTACK, new CloseRangeDamageHandler(channelDeps.dropProvider(), channelDeps.banService())); + registerHandler(RecvOpcode.RANGED_ATTACK, new RangedAttackHandler(channelDeps.dropProvider(), channelDeps.banService())); + registerHandler(RecvOpcode.MAGIC_ATTACK, new MagicDamageHandler(channelDeps.dropProvider(), channelDeps.banService())); registerHandler(RecvOpcode.TAKE_DAMAGE, new TakeDamageHandler()); registerHandler(RecvOpcode.MOVE_PLAYER, new MovePlayerHandler()); registerHandler(RecvOpcode.USE_CASH_ITEM, new UseCashItemHandler(channelDeps.noteService(), @@ -168,7 +168,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.USE_UPGRADE_SCROLL, new ScrollHandler()); registerHandler(RecvOpcode.USE_SUMMON_BAG, new UseSummonBagHandler()); registerHandler(RecvOpcode.FACE_EXPRESSION, new FaceExpressionHandler()); - registerHandler(RecvOpcode.HEAL_OVER_TIME, new HealOvertimeHandler()); + registerHandler(RecvOpcode.HEAL_OVER_TIME, new HealOvertimeHandler(channelDeps.banService())); registerHandler(RecvOpcode.ITEM_PICKUP, new ItemPickupHandler()); registerHandler(RecvOpcode.CHAR_INFO_REQUEST, new CharInfoRequestHandler()); registerHandler(RecvOpcode.SPECIAL_MOVE, new SpecialMoveHandler()); @@ -191,7 +191,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.ENTER_CASHSHOP, new EnterCashShopHandler(channelDeps.characterSaver())); registerHandler(RecvOpcode.DAMAGE_SUMMON, new DamageSummonHandler()); registerHandler(RecvOpcode.MOVE_SUMMON, new MoveSummonHandler()); - registerHandler(RecvOpcode.SUMMON_ATTACK, new SummonDamageHandler(channelDeps.dropProvider())); + registerHandler(RecvOpcode.SUMMON_ATTACK, new SummonDamageHandler(channelDeps.dropProvider(), channelDeps.banService())); registerHandler(RecvOpcode.BUDDYLIST_MODIFY, new BuddylistModifyHandler()); registerHandler(RecvOpcode.USE_ITEMEFFECT, new UseItemEffectHandler()); registerHandler(RecvOpcode.USE_CHAIR, new UseChairHandler()); @@ -227,7 +227,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.PET_EXCLUDE_ITEMS, new PetExcludeItemsHandler()); registerHandler(RecvOpcode.OWL_ACTION, new UseOwlOfMinervaHandler()); registerHandler(RecvOpcode.OWL_WARP, new OwlWarpHandler()); - registerHandler(RecvOpcode.TOUCH_MONSTER_ATTACK, new TouchMonsterDamageHandler(channelDeps.dropProvider())); + registerHandler(RecvOpcode.TOUCH_MONSTER_ATTACK, new TouchMonsterDamageHandler(channelDeps.dropProvider(), channelDeps.banService())); registerHandler(RecvOpcode.TROCK_ADD_MAP, new TrockAddMapHandler()); registerHandler(RecvOpcode.HIRED_MERCHANT_REQUEST, new HiredMerchantRequest()); registerHandler(RecvOpcode.MOB_BANISH_PLAYER, new MobBanishPlayerHandler()); @@ -253,7 +253,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.ALLIANCE_OPERATION, new AllianceOperationHandler()); registerHandler(RecvOpcode.DENY_ALLIANCE_REQUEST, new DenyAllianceRequestHandler()); registerHandler(RecvOpcode.USE_SOLOMON_ITEM, new UseSolomonHandler()); - registerHandler(RecvOpcode.USE_GACHA_EXP, new UseGachaExpHandler()); + registerHandler(RecvOpcode.USE_GACHA_EXP, new UseGachaExpHandler(channelDeps.banService())); registerHandler(RecvOpcode.NEW_YEAR_CARD_REQUEST, new NewYearCardHandler()); registerHandler(RecvOpcode.CASHSHOP_SURPRISE, new CashShopSurpriseHandler()); registerHandler(RecvOpcode.USE_ITEM_REWARD, new ItemRewardHandler()); diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 9f6380290a..92c31135f1 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -76,6 +76,7 @@ import server.expeditions.ExpeditionBossLog; import server.life.PlayerNPCFactory; import server.quest.Quest; import server.shop.ShopFactory; +import service.BanService; import service.NoteService; import service.TransitionService; import tools.DatabaseConnection; @@ -981,6 +982,7 @@ public class Server { CharacterLoader characterLoader = new CharacterLoader(monsterCardDao); CharacterSaver characterSaver = new CharacterSaver(monsterCardDao); TransitionService transitionService = new TransitionService(characterSaver); + BanService banService = new BanService(transitionService); NoteService noteService = new NoteService(new NoteDao(connection)); MakerProcessor makerProcessor = new MakerProcessor(new MakerInfoProvider(new MakerDao(connection))); FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService); @@ -990,7 +992,8 @@ public class Server { characterSaver, transitionService); CommandsExecutor commandsExecutor = new CommandsExecutor(commandContext); ChannelDependencies channelDependencies = new ChannelDependencies(characterLoader, characterSaver, noteService, - fredrickProcessor, makerProcessor, dropProvider, commandsExecutor, shopFactory, transitionService); + fredrickProcessor, makerProcessor, dropProvider, commandsExecutor, shopFactory, transitionService, + banService); PacketProcessor.registerGameHandlerDependencies(channelDependencies); diff --git a/src/main/java/net/server/channel/handlers/AbstractDealDamageHandler.java b/src/main/java/net/server/channel/handlers/AbstractDealDamageHandler.java index 26afbbc9a0..a4c75bb4d8 100644 --- a/src/main/java/net/server/channel/handlers/AbstractDealDamageHandler.java +++ b/src/main/java/net/server/channel/handlers/AbstractDealDamageHandler.java @@ -44,6 +44,7 @@ import server.maps.MapItem; import server.maps.MapObject; import server.maps.MapObjectType; import server.maps.MapleMap; +import service.BanService; import tools.PacketCreator; import tools.Randomizer; @@ -56,12 +57,14 @@ import static java.util.concurrent.TimeUnit.SECONDS; public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { private final DropProvider dropProvider; + private final BanService banService; - public AbstractDealDamageHandler(DropProvider dropProvider) { + public AbstractDealDamageHandler(DropProvider dropProvider, BanService banService) { this.dropProvider = dropProvider; + this.banService = banService; } - public static class AttackInfo { + public class AttackInfo { public int numAttacked, numDamage, numAttackedAndDamage, skill, skilllevel, stance, direction, rangedirection, charge, display; public Map> allDamage; @@ -85,7 +88,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { } if (display > 80) { //Hmm if (!mySkill.getAction()) { - AutobanFactory.FAST_ATTACK.autoban(chr, "WZ Edit; adding action to a skill: " + display); + banService.autoban(chr, AutobanFactory.FAST_ATTACK, "WZ Edit; adding action to a skill: " + display); return null; } } @@ -115,7 +118,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { } if (player.getMp() < attackEffect.getMpCon()) { - AutobanFactory.MPCON.addPoint(player.getAutobanManager(), "Skill: " + attack.skill + "; Player MP: " + player.getMp() + "; MP Needed: " + attackEffect.getMpCon()); + banService.addPoint(player, AutobanFactory.MPCON, "Skill: " + attack.skill + "; Player MP: " + player.getMp() + "; MP Needed: " + attackEffect.getMpCon()); } int mobCount = attackEffect.getMobCount(); @@ -146,7 +149,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { } if (attack.numAttacked > mobCount) { - AutobanFactory.MOB_COUNT.autoban(player, "Skill: " + attack.skill + "; Count: " + attack.numAttacked + " Max: " + attackEffect.getMobCount()); + banService.autoban(player, AutobanFactory.MOB_COUNT, "Skill: " + attack.skill + "; Count: " + attack.numAttacked + " Max: " + attackEffect.getMobCount()); return; } } @@ -419,7 +422,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { if (attack.skill != 0) { if (attackEffect.getFixDamage() != -1) { if (totDamageToOneMonster != attackEffect.getFixDamage() && totDamageToOneMonster != 0) { - AutobanFactory.FIX_DAMAGE.autoban(player, totDamageToOneMonster + " damage"); + banService.autoban(player, AutobanFactory.FIX_DAMAGE, totDamageToOneMonster + " damage"); } int threeSnailsId = player.getJobType() * 10000000 + 1000; @@ -852,7 +855,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler { // Add a ab point if its over 5x what we calculated. if (damage > maxWithCrit * 5) { - AutobanFactory.DAMAGE_HACK.addPoint(chr.getAutobanManager(), "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")"); + banService.addPoint(chr, AutobanFactory.DAMAGE_HACK, "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")"); } if (ret.skill == Marksman.SNIPE || (canCrit && damage > hitDmgMax)) { diff --git a/src/main/java/net/server/channel/handlers/CloseRangeDamageHandler.java b/src/main/java/net/server/channel/handlers/CloseRangeDamageHandler.java index 25d88b4bb8..3376ebde36 100644 --- a/src/main/java/net/server/channel/handlers/CloseRangeDamageHandler.java +++ b/src/main/java/net/server/channel/handlers/CloseRangeDamageHandler.java @@ -31,6 +31,7 @@ import database.drop.DropProvider; import net.netty.GameViolationException; import net.packet.InPacket; import server.StatEffect; +import service.BanService; import tools.PacketCreator; import tools.Pair; @@ -42,8 +43,8 @@ import static java.util.concurrent.TimeUnit.SECONDS; public final class CloseRangeDamageHandler extends AbstractDealDamageHandler { - public CloseRangeDamageHandler(DropProvider dropProvider) { - super(dropProvider); + public CloseRangeDamageHandler(DropProvider dropProvider, BanService banService) { + super(dropProvider, banService); } @Override diff --git a/src/main/java/net/server/channel/handlers/HealOvertimeHandler.java b/src/main/java/net/server/channel/handlers/HealOvertimeHandler.java index 5af9f49931..c63706255a 100644 --- a/src/main/java/net/server/channel/handlers/HealOvertimeHandler.java +++ b/src/main/java/net/server/channel/handlers/HealOvertimeHandler.java @@ -29,9 +29,16 @@ import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; import server.maps.MapleMap; +import service.BanService; import tools.PacketCreator; public final class HealOvertimeHandler extends AbstractPacketHandler { + private final BanService banService; + + public HealOvertimeHandler(BanService banService) { + this.banService = banService; + } + @Override public final void handlePacket(InPacket p, Client c) { Character chr = c.getPlayer(); @@ -47,13 +54,13 @@ public final class HealOvertimeHandler extends AbstractPacketHandler { if (healHP != 0) { abm.setTimestamp(8, timestamp, 28); // thanks Vcoc & Thora for pointing out d/c happening here if ((abm.getLastSpam(0) + 1500) > timestamp) { - AutobanFactory.FAST_HP_HEALING.addPoint(abm, "Fast hp healing"); + banService.addPoint(chr, AutobanFactory.FAST_HP_HEALING, "Fast hp healing"); } MapleMap map = chr.getMap(); int abHeal = (int) (77 * map.getRecovery() * 1.5); // thanks Ari for noticing players not getting healed in sauna in certain cases if (healHP > abHeal) { - AutobanFactory.HIGH_HP_HEALING.autoban(chr, "Healing: " + healHP + "; Max is " + abHeal + "."); + banService.autoban(chr, AutobanFactory.HIGH_HP_HEALING, "Healing: " + healHP + "; Max is " + abHeal + "."); return; } @@ -65,7 +72,7 @@ public final class HealOvertimeHandler extends AbstractPacketHandler { if (healMP != 0 && healMP < 1000) { abm.setTimestamp(9, timestamp, 28); if ((abm.getLastSpam(1) + 1500) > timestamp) { - AutobanFactory.FAST_MP_HEALING.addPoint(abm, "Fast mp healing"); + banService.addPoint(chr, AutobanFactory.FAST_MP_HEALING, "Fast mp healing"); return; // thanks resinate for noticing mp being gained even after detection } chr.addMP(healMP); diff --git a/src/main/java/net/server/channel/handlers/MagicDamageHandler.java b/src/main/java/net/server/channel/handlers/MagicDamageHandler.java index f89deb82be..e26c9c0c0d 100644 --- a/src/main/java/net/server/channel/handlers/MagicDamageHandler.java +++ b/src/main/java/net/server/channel/handlers/MagicDamageHandler.java @@ -34,14 +34,15 @@ import net.netty.GameViolationException; import net.packet.InPacket; import net.packet.Packet; import server.StatEffect; +import service.BanService; import tools.PacketCreator; import static java.util.concurrent.TimeUnit.SECONDS; public final class MagicDamageHandler extends AbstractDealDamageHandler { - public MagicDamageHandler(DropProvider dropProvider) { - super(dropProvider); + public MagicDamageHandler(DropProvider dropProvider, BanService banService) { + super(dropProvider, banService); } @Override public final void handlePacket(InPacket p, Client c) { diff --git a/src/main/java/net/server/channel/handlers/RangedAttackHandler.java b/src/main/java/net/server/channel/handlers/RangedAttackHandler.java index fd26177603..844b203141 100644 --- a/src/main/java/net/server/channel/handlers/RangedAttackHandler.java +++ b/src/main/java/net/server/channel/handlers/RangedAttackHandler.java @@ -41,6 +41,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import server.ItemInformationProvider; import server.StatEffect; +import service.BanService; import tools.PacketCreator; import tools.Randomizer; @@ -50,8 +51,8 @@ import static java.util.concurrent.TimeUnit.SECONDS; public final class RangedAttackHandler extends AbstractDealDamageHandler { private static final Logger log = LoggerFactory.getLogger(RangedAttackHandler.class); - public RangedAttackHandler(DropProvider dropProvider) { - super(dropProvider); + public RangedAttackHandler(DropProvider dropProvider, BanService banService) { + super(dropProvider, banService); } @Override diff --git a/src/main/java/net/server/channel/handlers/SummonDamageHandler.java b/src/main/java/net/server/channel/handlers/SummonDamageHandler.java index 2609676b20..7c40695454 100644 --- a/src/main/java/net/server/channel/handlers/SummonDamageHandler.java +++ b/src/main/java/net/server/channel/handlers/SummonDamageHandler.java @@ -40,6 +40,7 @@ import server.StatEffect; import server.life.Monster; import server.life.MonsterInformationProvider; import server.maps.Summon; +import service.BanService; import tools.PacketCreator; import java.util.ArrayList; @@ -48,8 +49,8 @@ import java.util.List; public final class SummonDamageHandler extends AbstractDealDamageHandler { private static final Logger log = LoggerFactory.getLogger(SummonDamageHandler.class); - public SummonDamageHandler(DropProvider dropProvider) { - super(dropProvider); + public SummonDamageHandler(DropProvider dropProvider, BanService banService) { + super(dropProvider, banService); } public final class SummonAttackEntry { diff --git a/src/main/java/net/server/channel/handlers/TouchMonsterDamageHandler.java b/src/main/java/net/server/channel/handlers/TouchMonsterDamageHandler.java index 110e1af365..ab69001c13 100644 --- a/src/main/java/net/server/channel/handlers/TouchMonsterDamageHandler.java +++ b/src/main/java/net/server/channel/handlers/TouchMonsterDamageHandler.java @@ -26,11 +26,12 @@ import client.Character; import client.Client; import database.drop.DropProvider; import net.packet.InPacket; +import service.BanService; public final class TouchMonsterDamageHandler extends AbstractDealDamageHandler { - public TouchMonsterDamageHandler(DropProvider dropProvider) { - super(dropProvider); + public TouchMonsterDamageHandler(DropProvider dropProvider, BanService banService) { + super(dropProvider, banService); } @Override diff --git a/src/main/java/net/server/channel/handlers/UseGachaExpHandler.java b/src/main/java/net/server/channel/handlers/UseGachaExpHandler.java index ba1384297d..9d0e495c87 100644 --- a/src/main/java/net/server/channel/handlers/UseGachaExpHandler.java +++ b/src/main/java/net/server/channel/handlers/UseGachaExpHandler.java @@ -26,6 +26,7 @@ import client.Client; import client.autoban.AutobanFactory; import net.AbstractPacketHandler; import net.packet.InPacket; +import service.BanService; import tools.PacketCreator; /** @@ -34,6 +35,11 @@ import tools.PacketCreator; * Modified by -- Ronan - concurrency protection */ public class UseGachaExpHandler extends AbstractPacketHandler { + private final BanService banService; + + public UseGachaExpHandler(BanService banService) { + this.banService = banService; + } @Override public void handlePacket(InPacket p, Client c) { @@ -41,7 +47,8 @@ public class UseGachaExpHandler extends AbstractPacketHandler { if (c.tryacquireClient()) { try { if (c.getPlayer().getGachaExp() <= 0) { - AutobanFactory.GACHA_EXP.autoban(c.getPlayer(), "Player tried to redeem GachaEXP, but had none to redeem."); + banService.autoban(c.getPlayer(), AutobanFactory.GACHA_EXP, "Player tried to redeem GachaEXP, but had none to redeem."); + return; } c.getPlayer().gainGachaExp(); } finally { diff --git a/src/main/java/service/BanService.java b/src/main/java/service/BanService.java new file mode 100644 index 0000000000..bae344c3d1 --- /dev/null +++ b/src/main/java/service/BanService.java @@ -0,0 +1,62 @@ +package service; + +import client.Character; +import client.autoban.AutobanFactory; +import config.YamlConfig; +import net.packet.Packet; +import net.server.Server; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import server.TimerManager; +import tools.PacketCreator; + +import java.util.concurrent.TimeUnit; + +public class BanService { + private static final Logger log = LoggerFactory.getLogger(BanService.class); + private final TransitionService transitionService; + + public BanService(TransitionService transitionService) { + this.transitionService = transitionService; + } + + public void autoban(Character chr, AutobanFactory type, String reason) { + autoban(chr, "Autobanned for (" + type.name() + ": " + reason + ")"); + } + + private void autoban(Character chr, String reason) { + if (isExempt(chr)) { + return; + } + + chr.ban(reason); + + chr.sendPacket(PacketCreator.sendPolice("You have been blocked by the#b %s Police for HACK reason.#k".formatted("Cosmic"))); + TimerManager.getInstance().schedule(() -> transitionService.disconnect(chr.getClient(), false, false), + TimeUnit.SECONDS.toMillis(5)); + + var bannedName = Character.makeMapleReadable(chr.getName()); + Packet autobanGmNotice = PacketCreator.serverNotice(6, bannedName + " was autobanned for " + reason); + Server.getInstance().broadcastGMMessage(chr.getWorld(), autobanGmNotice); + } + + public void addPoint(Character chr, AutobanFactory type, String reason) { + if (isExempt(chr)) { + return; + } + + var autobanManager = chr.getAutobanManager(); + boolean shouldAutoban = autobanManager.addPoint(type); + if (shouldAutoban) { + autoban(chr, type, reason); + } + + if (YamlConfig.config.server.USE_AUTOBAN_LOG) { + log.info("Autoban - chr {} caused {} {}", Character.makeMapleReadable(chr.getName()), type.name(), reason); + } + } + + private boolean isExempt(Character chr) { + return !YamlConfig.config.server.USE_AUTOBAN || chr.isGM() || chr.isBanned(); + } +}