blob: 11234badc5ddde5698de863db0e1fe827876cc60 [file] [log] [blame] [raw]
package li.cil.oc.server.component
import java.util
import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.driver.DeviceInfo
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.EnvironmentHost
import li.cil.oc.api.network._
import li.cil.oc.api.prefab
import li.cil.oc.common.event.ChunkloaderUpgradeHandler
import net.minecraftforge.common.ForgeChunkManager
import net.minecraftforge.common.ForgeChunkManager.Ticket
import scala.collection.convert.WrapAsJava._
class UpgradeChunkloader(val host: EnvironmentHost) extends prefab.ManagedEnvironment with DeviceInfo {
override val node = api.Network.newNode(this, Visibility.Network).
withComponent("chunkloader").
withConnector().
create()
private final lazy val deviceInfo = Map(
DeviceAttribute.Class -> DeviceClass.Generic,
DeviceAttribute.Description -> "World stabilizer",
DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor,
DeviceAttribute.Product -> "Realizer9001-CL"
)
override def getDeviceInfo: util.Map[String, String] = deviceInfo
var ticket: Option[Ticket] = None
override val canUpdate = true
override def update() {
super.update()
if (host.world.getTotalWorldTime % Settings.get.tickFrequency == 0 && ticket.isDefined) {
if (!node.tryChangeBuffer(-Settings.get.chunkloaderCost * Settings.get.tickFrequency)) {
ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch {
case _: Throwable => // Ignored.
})
ticket = None
}
}
}
@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)))
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))
case _ => None
})
ChunkloaderUpgradeHandler.updateLoadedChunk(this)
}
}
override def onDisconnect(node: Node) {
super.onDisconnect(node)
if (node == this.node) {
ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch {
case _: Throwable => // Ignored.
})
ticket = None
}
}
override def onMessage(message: Message) {
super.onMessage(message)
if (message.name == "computer.stopped") {
setActive(enabled = false)
}
else if (message.name == "computer.started") {
setActive(enabled = true)
}
}
private def setActive(enabled: Boolean) = {
if (enabled && ticket.isEmpty) {
ticket = Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL))
ChunkloaderUpgradeHandler.updateLoadedChunk(this)
}
else if (!enabled && ticket.isDefined) {
ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch {
case _: Throwable => // Ignored.
})
ticket = None
}
ticket.isDefined
}
}