diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 9f73b65aa..848fe1ae1 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -22,6 +22,8 @@ import net.minecraft.network.{INetworkManager, NetLoginHandler} import net.minecraft.server.MinecraftServer import net.minecraft.tileentity.TileEntity import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.event.ForgeSubscribe +import net.minecraftforge.event.world.WorldEvent import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -181,4 +183,14 @@ object EventHandler extends ITickHandler with IConnectionHandler with ICraftingH } override def onSmelting(player: EntityPlayer, item: ItemStack) {} + + @ForgeSubscribe + def onWorldUnload(e: WorldEvent.Unload) { + if (!e.world.isRemote) { + import scala.collection.convert.WrapAsScala._ + e.world.loadedTileEntityList.collect { + case te: tileentity.traits.TileEntity => te.onChunkUnload() + } + } + } } diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 3efdf533e..9cd18ce47 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -132,6 +132,7 @@ class Proxy { MinecraftForge.EVENT_BUS.register(AngelUpgradeHandler) MinecraftForge.EVENT_BUS.register(ChunkloaderUpgradeHandler) MinecraftForge.EVENT_BUS.register(ExperienceUpgradeHandler) + MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(Loot) MinecraftForge.EVENT_BUS.register(RobotCommonHandler) MinecraftForge.EVENT_BUS.register(SaveHandler) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala index a6ffbd637..5804f7c39 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala @@ -51,31 +51,39 @@ class Adapter extends traits.Environment with Analyzable { case Some(newDriver) => blocks(d.ordinal()) match { case Some((oldEnvironment, driver)) => if (newDriver != driver) { - // This is... odd. Maybe moved by some other mod? - node.disconnect(oldEnvironment.node) - val environment = newDriver.createEnvironment(world, x, y, z) - blocks(d.ordinal()) = Some((environment, newDriver)) + // This is... odd. Maybe moved by some other mod? First, clean up. + blocks(d.ordinal()) = None updatingBlocks -= oldEnvironment + blocksData(d.ordinal()) = None + node.disconnect(oldEnvironment.node) + + // Then rebuild - if we have something. + val environment = newDriver.createEnvironment(world, x, y, z) + if (environment != null) { + blocks(d.ordinal()) = Some((environment, newDriver)) + if (environment.canUpdate) { + updatingBlocks += environment + } + blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + node.connect(environment.node) + } + } // else: the more things change, the more they stay the same. + case _ => + // A challenger appears. Maybe. + val environment = newDriver.createEnvironment(world, x, y, z) + if (environment != null) { + blocks(d.ordinal()) = Some((environment, newDriver)) if (environment.canUpdate) { updatingBlocks += environment } + blocksData(d.ordinal()) match { + case Some(data) if data.name == environment.getClass.getName => + environment.load(data.data) + case _ => + } blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) node.connect(environment.node) - } // else: the more things change, the more they stay the same. - case _ => - // A challenger appears. - val environment = newDriver.createEnvironment(world, x, y, z) - blocks(d.ordinal()) = Some((environment, newDriver)) - if (environment.canUpdate) { - updatingBlocks += environment } - blocksData(d.ordinal()) match { - case Some(data) if data.name == environment.getClass.getName => - environment.load(data.data) - case _ => - } - blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) - node.connect(environment.node) } case _ => blocks(d.ordinal()) match { case Some((environment, driver)) => diff --git a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala index 0023e7298..ed92ebd19 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala @@ -265,12 +265,16 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB override protected def initialize() { super.initialize() - ServerRack.list += this -> Unit + if (isClient) { + ServerRack.list += this -> Unit + } } override protected def dispose() { super.dispose() - ServerRack.list -= this + if (isClient) { + ServerRack.list -= this + } } override def readFromNBT(nbt: NBTTagCompound) { diff --git a/src/main/scala/li/cil/oc/server/component/Keyboard.scala b/src/main/scala/li/cil/oc/server/component/Keyboard.scala index 49e34f507..d7faceb90 100644 --- a/src/main/scala/li/cil/oc/server/component/Keyboard.scala +++ b/src/main/scala/li/cil/oc/server/component/Keyboard.scala @@ -9,6 +9,7 @@ import li.cil.oc.api.network.{Message, Node, Visibility} import li.cil.oc.common.component import net.minecraft.entity.player.EntityPlayer import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.event.{Event, ForgeSubscribe} import scala.collection.mutable @@ -45,6 +46,13 @@ class Keyboard(val owner: Container) extends component.ManagedComponent with api pressedKeys.remove(e.player) } + @ForgeSubscribe + def onWorldUnload(e: WorldEvent.Unload) { + try MinecraftForge.EVENT_BUS.unregister(this) catch { + case ignore: Throwable => + } + } + // ----------------------------------------------------------------------- // override def onConnect(node: Node) { diff --git a/src/main/scala/li/cil/oc/server/component/machine/Machine.scala b/src/main/scala/li/cil/oc/server/component/machine/Machine.scala index 61a925dc8..7a072cdbf 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/Machine.scala @@ -491,7 +491,7 @@ class Machine(val owner: Owner, constructor: Constructor[_ <: Architecture]) ext } override def onDisconnect(node: Node) { - if (node == this.node) { + if (node == this.node) this.synchronized { close() tmp.foreach(_.node.remove()) }