add white/blacklist option for chunkloading

new settings options: misc.chunkloaderDimensionBlacklist and
misc.chunkloaderDimensionWhitelist

closes #2768
This commit is contained in:
payonel 2018-10-27 22:55:12 -07:00
parent 1e35f8e49a
commit a0821f1493
3 changed files with 66 additions and 14 deletions

View File

@ -1381,6 +1381,14 @@ opencomputers {
# Radius the MFU is able to operate in # Radius the MFU is able to operate in
mfuRange: 3 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). # Settings for mod integration (the mod previously known as OpenComponents).

View File

@ -461,6 +461,11 @@ class Settings(val config: Config) {
val registerLuaJArchitecture = config.getBoolean("debug.registerLuaJArchitecture") val registerLuaJArchitecture = config.getBoolean("debug.registerLuaJArchitecture")
val disableLocaleChanging = config.getBoolean("debug.disableLocaleChanging") 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 { object Settings {

View File

@ -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) def isActive(context: Context, args: Arguments): Array[AnyRef] = result(ticket.isDefined)
@Callback(doc = """function(enabled:boolean):boolean -- Enables or disables the chunkloader.""") @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))) def setActive(context: Context, args: Arguments): Array[AnyRef] = result(setActive(args.checkBoolean(0), throwIfBlocked = true))
override def onConnect(node: Node) { override def onConnect(node: Node) {
super.onConnect(node) super.onConnect(node)
if (node == this.node) { if (node == this.node) {
if (ChunkloaderUpgradeHandler.restoredTickets.contains(node.address)) { val restoredTicket = ChunkloaderUpgradeHandler.restoredTickets.remove(node.address)
OpenComputers.log.info(s"Reclaiming chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in dimension ${host.world().provider.dimensionId}.") ticket = if (restoredTicket.isDefined) {
if (!isDimensionAllowed) {
try ForgeChunkManager.releaseTicket(restoredTicket.get) catch {
case _: Throwable => // Ignored.
} }
ticket = ChunkloaderUpgradeHandler.restoredTickets.remove(node.address).orElse(host match { OpenComputers.log.info(s"Releasing chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in blacklisted dimension ${host.world().provider.dimensionId}.")
case context: Context if context.isRunning => Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) 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 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) { if (enabled && ticket.isEmpty) {
ticket = Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) ticket = requestTicket(throwIfBlocked)
ChunkloaderUpgradeHandler.updateLoadedChunk(this) ticket.isDefined
} }
else if (!enabled && ticket.isDefined) { else if (!enabled && ticket.isDefined) {
ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch { ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch {
case _: Throwable => // Ignored. case _: Throwable => // Ignored.
}) })
ticket = None 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
} }
} }