From a0821f14930ca05a08df75801cdf88b253b0b162 Mon Sep 17 00:00:00 2001 From: payonel Date: Sat, 27 Oct 2018 22:55:12 -0700 Subject: [PATCH] add white/blacklist option for chunkloading new settings options: misc.chunkloaderDimensionBlacklist and misc.chunkloaderDimensionWhitelist closes #2768 --- src/main/resources/application.conf | 8 +++ src/main/scala/li/cil/oc/Settings.scala | 5 ++ .../server/component/UpgradeChunkloader.scala | 67 +++++++++++++++---- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 5fef37726..0b50c0dca 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1381,6 +1381,14 @@ opencomputers { # Radius the MFU is able to operate in mfuRange: 3 + + # list of dimension ids blacklisted for the chunk loader upgrade + # a blacklisted dimension blocks a whitelisted dimension + chunkloaderDimensionBlacklist: [] + + # list of dimension ids whitelisted for the chunk loader upgrade + # a non-empty whitelist denies all unlisted dimensions + chunkloaderDimensionWhitelist: [] } # Settings for mod integration (the mod previously known as OpenComponents). diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index f28dada71..c163339d2 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -461,6 +461,11 @@ class Settings(val config: Config) { val registerLuaJArchitecture = config.getBoolean("debug.registerLuaJArchitecture") val disableLocaleChanging = config.getBoolean("debug.disableLocaleChanging") + + val chunkloadDimensionBlacklist = if (config.hasPath("misc.chunkloaderDimensionBlacklist")) config.getIntList("misc.chunkloaderDimensionBlacklist") + else new java.util.LinkedList[Integer]() + val chunkloadDimensionWhitelist = if (config.hasPath("misc.chunkloaderDimensionWhitelist")) config.getIntList("misc.chunkloaderDimensionWhitelist") + else new java.util.LinkedList[Integer]() } object Settings { diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala b/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala index 6f40b986e..87573be1b 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala @@ -55,23 +55,31 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends prefab.ManagedEnviro } } - @Callback(doc = """function():boolean -- Gets whether the chunkloader is currently active.""") + @Callback(doc = "function():boolean -- Gets whether the chunkloader is currently active.") def isActive(context: Context, args: Arguments): Array[AnyRef] = result(ticket.isDefined) - @Callback(doc = """function(enabled:boolean):boolean -- Enables or disables the chunkloader.""") - def setActive(context: Context, args: Arguments): Array[AnyRef] = result(setActive(args.checkBoolean(0))) + @Callback(doc = "function(enabled:boolean):boolean -- Enables or disables the chunkloader, returns true if active changed") + def setActive(context: Context, args: Arguments): Array[AnyRef] = result(setActive(args.checkBoolean(0), throwIfBlocked = true)) override def onConnect(node: Node) { super.onConnect(node) if (node == this.node) { - if (ChunkloaderUpgradeHandler.restoredTickets.contains(node.address)) { - OpenComputers.log.info(s"Reclaiming chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in dimension ${host.world().provider.dimensionId}.") - } - ticket = ChunkloaderUpgradeHandler.restoredTickets.remove(node.address).orElse(host match { - case context: Context if context.isRunning => Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) + val restoredTicket = ChunkloaderUpgradeHandler.restoredTickets.remove(node.address) + ticket = if (restoredTicket.isDefined) { + if (!isDimensionAllowed) { + try ForgeChunkManager.releaseTicket(restoredTicket.get) catch { + case _: Throwable => // Ignored. + } + OpenComputers.log.info(s"Releasing chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in blacklisted dimension ${host.world().provider.dimensionId}.") + None + } else { + OpenComputers.log.info(s"Reclaiming chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in dimension ${host.world().provider.dimensionId}.") + restoredTicket + } + } else host match { + case context: Context if context.isRunning => requestTicket() case _ => None - }) - ChunkloaderUpgradeHandler.updateLoadedChunk(this) + } } } @@ -95,17 +103,48 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends prefab.ManagedEnviro } } - private def setActive(enabled: Boolean) = { + private def setActive(enabled: Boolean, throwIfBlocked: Boolean = false) = { if (enabled && ticket.isEmpty) { - ticket = Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) - ChunkloaderUpgradeHandler.updateLoadedChunk(this) + ticket = requestTicket(throwIfBlocked) + ticket.isDefined } else if (!enabled && ticket.isDefined) { ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch { case _: Throwable => // Ignored. }) ticket = None + true + } else { + false + } + } + + private def isDimensionAllowed: Boolean = { + val id: Int = host.world().provider.dimensionId + val whitelist = Settings.get.chunkloadDimensionWhitelist + val blacklist = Settings.get.chunkloadDimensionBlacklist + if (!whitelist.isEmpty) { + if (!whitelist.contains(id)) + return false + } + if (!blacklist.isEmpty) { + if (blacklist.contains(id)) { + return false + } + } + true + } + + private def requestTicket(throwIfBlocked: Boolean = false): Option[Ticket] = { + if (!isDimensionAllowed) { + if (throwIfBlocked) { + throw new Exception("this dimension is blacklisted") + } + None + } else { + val result = Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) + ChunkloaderUpgradeHandler.updateLoadedChunk(this) + result } - ticket.isDefined } }