From b1ed4461af71d6fcd5aad08f9f7be4180baa3345 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Thu, 30 Mar 2023 22:39:42 +0000 Subject: [PATCH] Fixed incorrect teleporting to house portal on logout House now kicks guests when owner leaves More aggressively unload old house regions (experiment) Added DEBUG log type (currently unused, but shows up in cyan when used and the world is in development mode) --- .../skill/construction/HouseManager.java | 13 ++-- .../global/skill/construction/HouseZone.java | 63 +++++++++++++++---- .../src/main/core/game/world/map/Region.java | 29 ++++++--- .../main/core/game/world/map/RegionManager.kt | 9 +++ .../game/world/map/build/DynamicRegion.java | 6 +- Server/src/main/core/tools/SystemLogger.kt | 15 ++++- 6 files changed, 98 insertions(+), 37 deletions(-) diff --git a/Server/src/main/content/global/skill/construction/HouseManager.java b/Server/src/main/content/global/skill/construction/HouseManager.java index aa576bef9..e219ac44b 100644 --- a/Server/src/main/content/global/skill/construction/HouseManager.java +++ b/Server/src/main/content/global/skill/construction/HouseManager.java @@ -64,7 +64,7 @@ public final class HouseManager { /** * The house zone. */ - private final HouseZone zone = new HouseZone(this); + private HouseZone zone = new HouseZone(this); /** * The player's house rooms. @@ -198,10 +198,6 @@ public final class HouseManager { player.lock(1); player.sendMessage("House location: " + houseRegion.getBaseLocation() + ", entry: " + getEnterLocation()); player.getProperties().setTeleportLocation(getEnterLocation()); - registerLogoutListener(player, "houselogout", (p) -> { - p.setLocation(location.getExitLocation()); - return Unit.INSTANCE; - }); openLoadInterface(player); checkForAndSpawnServant(player); updateVarbits(player, buildingMode); @@ -254,7 +250,6 @@ public final class HouseManager { */ public static void leave(Player player) { HouseManager house = player.getAttribute("poh_entry", player.getHouseManager()); - clearLogoutListener(player, "houselogout"); if (house.getHouseRegion() == null){ return; } @@ -278,8 +273,7 @@ public final class HouseManager { if (enable) { expelGuests(player); } - buildingMode = enable; - reload(player, enable); + enter(player, enable); player.getPacketDispatch().sendMessage("Building mode is now " + (buildingMode ? "on." : "off.")); } } @@ -288,6 +282,7 @@ public final class HouseManager { * Reloads the house. * @param player The player. * @param buildingMode If building mode should be enabled. + * NOTE: I think we should avoid this method, it might be causing some issues. It's actually really suspicious... */ public void reload(Player player, boolean buildingMode) { int diffX = player.getLocation().getLocalX(); @@ -902,4 +897,4 @@ public final class HouseManager { public HouseZone getZone() { return zone; } -} \ No newline at end of file +} diff --git a/Server/src/main/content/global/skill/construction/HouseZone.java b/Server/src/main/content/global/skill/construction/HouseZone.java index f3f894b8c..dd0075f23 100644 --- a/Server/src/main/content/global/skill/construction/HouseZone.java +++ b/Server/src/main/content/global/skill/construction/HouseZone.java @@ -5,6 +5,11 @@ import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.world.map.zone.MapZone; import core.game.world.map.zone.ZoneRestriction; +import core.game.world.map.RegionManager; +import core.game.world.map.Region; +import core.game.system.task.Pulse; + +import static core.api.ContentAPIKt.*; /** * Handles the player owned house zone. @@ -38,20 +43,36 @@ public final class HouseZone extends MapZone { @Override public void configure() { - if (previousRegion != -1) { - unregisterRegion(previousRegion); - } - if (previousDungeon != -1) { - unregisterRegion(previousDungeon); - } + unregisterOldRegions(); registerRegion(house.getHouseRegion().getId()); if (house.getDungeonRegion() != null) { registerRegion(house.getDungeonRegion().getId()); } } + private void unregisterOldRegions() { + if (previousRegion != -1) { + unregisterRegion(previousRegion); + } + if (previousDungeon != -1) { + unregisterRegion(previousDungeon); + } + } + @Override public boolean enter(Entity e) { + if (e instanceof Player) { + Player pl = (Player) e; + if (house == pl.getHouseManager()) { + previousRegion = house.getHouseRegion().getId(); + if (house.getDungeonRegion() != null) + previousDungeon = house.getDungeonRegion().getId(); + } + registerLogoutListener(pl, "houselogout", (p) -> { + p.setLocation(house.getLocation().getExitLocation()); + return kotlin.Unit.INSTANCE; + }); + } return super.enter(e); } @@ -66,13 +87,31 @@ public final class HouseZone extends MapZone { @Override public boolean leave(Entity e, boolean logout) { - if (logout) { - if (e instanceof Player) { - Player p = (Player) e; - HouseManager.leave(p); - return true; + if (e instanceof Player) { + Player p = (Player) e; + if (house == p.getHouseManager()) { + house.expelGuests(p); + int toRemove = previousRegion; + int dungRemove = previousDungeon; + submitWorldPulse(new Pulse(2) { + public boolean pulse() { + Region r = RegionManager.forId(toRemove); + Region dr = dungRemove != -1 ? RegionManager.forId(dungRemove) : null; + RegionManager.removeRegion(toRemove); + unregisterRegion(toRemove); + r.setActive(false); + if (dungRemove != -1) { + RegionManager.removeRegion(dungRemove); + unregisterRegion(dungRemove); + dr.setActive(false); + } + return true; + } + }); } + clearLogoutListener(p, "houselogout"); + return true; } return true; } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/world/map/Region.java b/Server/src/main/core/game/world/map/Region.java index edc7af134..fc52f472f 100644 --- a/Server/src/main/core/game/world/map/Region.java +++ b/Server/src/main/core/game/world/map/Region.java @@ -268,16 +268,20 @@ public class Region { } } + public boolean flagInactive(boolean force) { + if (unload(this, force)) { + active = false; + return true; + } else { + return false; + } + } + /** * Flags the region as inactive. */ - protected boolean flagInactive() { - if(unload(this)) { - active = false; - return true; - } else { - return false; - } + public boolean flagInactive() { + return flagInactive(false); } /** @@ -341,18 +345,22 @@ public class Region { } } + public static boolean unload(Region r) { + return unload(r, false); + } + /** * Unloads a region. * @param r The region. */ - private static boolean unload(Region r) { - if (r.isViewed()) { + public static boolean unload(Region r, boolean force) { + if (!force && r.isViewed()) { log(CommunicationInfo.class, Log.ERR, "Players viewing region!"); r.flagActive(); return false; } for (RegionPlane p : r.planes) { - if (!p.getPlayers().isEmpty()) { + if (!force && !p.getPlayers().isEmpty()) { log(CommunicationInfo.class, Log.ERR, "Players still in region!"); r.flagActive(); return false; @@ -366,6 +374,7 @@ public class Region { } } } + r.activityPulse.stop(); return true; } diff --git a/Server/src/main/core/game/world/map/RegionManager.kt b/Server/src/main/core/game/world/map/RegionManager.kt index 4eea03930..c75fd2d6d 100644 --- a/Server/src/main/core/game/world/map/RegionManager.kt +++ b/Server/src/main/core/game/world/map/RegionManager.kt @@ -855,6 +855,15 @@ object RegionManager { } } + @JvmStatic + fun removeRegion(id: Int) { + if (lock.tryLock() || LOCK.tryLock(10000, TimeUnit.MILLISECONDS)) { + val r = REGION_CACHE.remove(id) + r?.flagInactive(true) + LOCK.unlock() + } + } + /** * Gets the regionCache. * @return The regionCache. diff --git a/Server/src/main/core/game/world/map/build/DynamicRegion.java b/Server/src/main/core/game/world/map/build/DynamicRegion.java index 02f61db29..2ccbabc69 100644 --- a/Server/src/main/core/game/world/map/build/DynamicRegion.java +++ b/Server/src/main/core/game/world/map/build/DynamicRegion.java @@ -343,7 +343,7 @@ public final class DynamicRegion extends Region { } @Override - public boolean flagInactive() { + public boolean flagInactive(boolean force) { if (!permanent) { if (parentRegion != null && parentRegion.isActive()) { parentRegion.checkInactive(); @@ -356,7 +356,7 @@ public final class DynamicRegion extends Region { } } } - if(!super.flagInactive()) { + if(!super.flagInactive(force)) { return false; } for (RegionPlane plane : getPlanes()) { @@ -381,7 +381,7 @@ public final class DynamicRegion extends Region { boolean allLinkedInactive = true; if (linked != null) { for (DynamicRegion r : linked) { - allLinkedInactive &= r.flagInactive(); + allLinkedInactive &= r.flagInactive(force); } } return allLinkedInactive; diff --git a/Server/src/main/core/tools/SystemLogger.kt b/Server/src/main/core/tools/SystemLogger.kt index 86f682bf9..eb65de9ea 100644 --- a/Server/src/main/core/tools/SystemLogger.kt +++ b/Server/src/main/core/tools/SystemLogger.kt @@ -4,7 +4,8 @@ import com.github.ajalt.mordant.rendering.TextColors import com.github.ajalt.mordant.terminal.* import com.google.protobuf.ByteString.Output import core.ServerConstants -import core.api.log +import core.game.world.GameWorld +import core.api.* import java.io.OutputStream import java.io.PrintStream import java.text.SimpleDateFormat @@ -27,6 +28,13 @@ object SystemLogger { @JvmStatic fun processLogEntry(clazz: Class<*>, log: Log, message: String) { when (log) { + Log.DEBUG -> { + if (GameWorld.settings?.isDevMode != true) + return + val msg = TextColors.cyan("${getTime()}: [${clazz.simpleName}] $message") + t.println(msg) + } + Log.FINE -> { if (ServerConstants.LOG_LEVEL < LogLevel.VERBOSE) return @@ -88,5 +96,6 @@ enum class Log { FINE, INFO, WARN, - ERR -} \ No newline at end of file + ERR, + DEBUG +}