From 5cae3fc3366fa504ad626d1aec4e029ec42a855f Mon Sep 17 00:00:00 2001 From: P0nk Date: Tue, 28 Sep 2021 18:26:27 +0200 Subject: [PATCH] Implement merchant blacklist, blocking any listed characters from entering --- .../handlers/PlayerInteractionHandler.java | 28 +++++++++--- src/main/java/server/maps/HiredMerchant.java | 43 +++++++++++++++++-- src/main/java/tools/PacketCreator.java | 2 +- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java b/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java index fbb8c757cc..8fdfa362cb 100644 --- a/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java @@ -44,7 +44,6 @@ import tools.PacketCreator; import java.awt.*; import java.sql.SQLException; import java.util.Arrays; -import java.util.List; /** * @author Matze @@ -286,8 +285,7 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { int oid = p.readInt(); MapObject ob = chr.getMap().getMapObject(oid); - if (ob instanceof PlayerShop) { - PlayerShop shop = (PlayerShop) ob; + if (ob instanceof PlayerShop shop) { shop.visitShop(chr); } else if (ob instanceof MiniGame) { p.skip(1); @@ -691,10 +689,26 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { } c.sendPacket(PacketCreator.viewMerchantVisitorHistory(merchant.getVisitorHistory())); } else if (mode == Action.VIEW_BLACKLIST.getCode()) { - List blacklistedNames = List.of("Blanca", "Betsy", "Kevin", "Rosa", "Evan", "Terence", - "Cecilia", "Gayle", "Erma", "Dorothy", "Willis", "Alberta", "Marilyn", "Myron", "Sheryl", - "Marco", "Jose", "Kendra", "Laurence", "Victoria", "NonListed"); - c.sendPacket(PacketCreator.viewMerchantBlacklist(blacklistedNames)); + HiredMerchant merchant = chr.getHiredMerchant(); + if (merchant == null || !merchant.isOwner(chr)) { + return; + } + + c.sendPacket(PacketCreator.viewMerchantBlacklist(merchant.getBlacklist())); + } else if (mode == Action.ADD_TO_BLACKLIST.getCode()) { + HiredMerchant merchant = chr.getHiredMerchant(); + if (merchant == null || !merchant.isOwner(chr)) { + return; + } + String chrName = p.readString(); + merchant.addToBlacklist(chrName); + } else if (mode == Action.REMOVE_FROM_BLACKLIST.getCode()) { + HiredMerchant merchant = chr.getHiredMerchant(); + if (merchant == null || !merchant.isOwner(chr)) { + return; + } + String chrName = p.readString(); + merchant.removeFromBlacklist(chrName); } else if (mode == Action.MERCHANT_ORGANIZE.getCode()) { HiredMerchant merchant = chr.getHiredMerchant(); if (merchant == null || !merchant.isOwner(chr)) { diff --git a/src/main/java/server/maps/HiredMerchant.java b/src/main/java/server/maps/HiredMerchant.java index c8010172f5..dfd9bc9668 100644 --- a/src/main/java/server/maps/HiredMerchant.java +++ b/src/main/java/server/maps/HiredMerchant.java @@ -47,10 +47,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; @@ -78,6 +75,7 @@ public class HiredMerchant extends AbstractMapObject { private MapleMap map; private final Visitor[] visitors = new Visitor[3]; private final LinkedList visitorHistory = new LinkedList<>(); + private final LinkedHashSet blacklist = new LinkedHashSet<>(); // case-sensitive character names private final Lock visitorLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.VISITOR_MERCH, true); private record Visitor(Character chr, Instant enteredAt) {} @@ -489,6 +487,9 @@ public class HiredMerchant extends AbstractMapObject { } else if (!this.isOpen()) { chr.sendPacket(PacketCreator.getMiniRoomError(18)); return; + } else if (isBlacklisted(chr.getName())) { + chr.sendPacket(PacketCreator.getMiniRoomError(17)); + return; } else if (!this.addVisitor(chr)) { chr.sendPacket(PacketCreator.getMiniRoomError(2)); return; @@ -722,6 +723,40 @@ public class HiredMerchant extends AbstractMapObject { return Collections.unmodifiableList(visitorHistory); } + public void addToBlacklist(String chrName) { + visitorLock.lock(); + try { + if (blacklist.size() >= BLACKLIST_LIMIT) { + return; + } + blacklist.add(chrName); + } finally { + visitorLock.unlock(); + } + } + + public void removeFromBlacklist(String chrName) { + visitorLock.lock(); + try { + blacklist.remove(chrName); + } finally { + visitorLock.unlock(); + } + } + + public Set getBlacklist() { + return Collections.unmodifiableSet(blacklist); + } + + private boolean isBlacklisted(String chrName) { + visitorLock.lock(); + try { + return blacklist.contains(chrName); + } finally { + visitorLock.unlock(); + } + } + public int getMapId() { return map.getId(); } diff --git a/src/main/java/tools/PacketCreator.java b/src/main/java/tools/PacketCreator.java index ce2a95acf9..7227677280 100644 --- a/src/main/java/tools/PacketCreator.java +++ b/src/main/java/tools/PacketCreator.java @@ -5221,7 +5221,7 @@ public class PacketCreator { /** * @param chrNames Blacklisted names. The first 20 names will be displayed, anything beyond does no difference. */ - public static Packet viewMerchantBlacklist(List chrNames) { + public static Packet viewMerchantBlacklist(Set chrNames) { final OutPacket p = OutPacket.create(SendOpcode.PLAYER_INTERACTION); p.writeByte(PlayerInteractionHandler.Action.VIEW_BLACKLIST.getCode()); p.writeShort(chrNames.size());