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 +}