From 708f751fb66579a78f5668f711b8e93dd596f383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 17 Mar 2014 11:36:27 +0100 Subject: [PATCH 1/2] added missing side check when stopping running sound for computers --- src/main/scala/li/cil/oc/common/tileentity/Computer.scala | 4 +++- src/main/scala/li/cil/oc/common/tileentity/Rack.scala | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/Computer.scala index d3ce5357e..cd66a50e8 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Computer.scala @@ -135,7 +135,9 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B // Note: chunk unload is handled by sound via event handler. override def invalidate() { super.invalidate() - Sound.stopLoop(this) + if (isClient) { + Sound.stopLoop(this) + } } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala index 3e5ede36d..428ad8385 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala @@ -237,7 +237,9 @@ class Rack extends PowerAcceptor with Hub with PowerBalancer with Inventory with // Note: chunk unload is handled by sound via event handler. override def invalidate() { super.invalidate() - Sound.stopLoop(this) + if (isClient) { + Sound.stopLoop(this) + } } // ----------------------------------------------------------------------- // From a65ccb7407705506386ae85b976dd401f1265adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 17 Mar 2014 12:11:38 +0100 Subject: [PATCH 2/2] fixed save system for computer states. god that was stupid. warning: computers saved in build 266-273 won't be restored properly. --- .../scala/li/cil/oc/common/SaveHandler.scala | 55 +++++++++++-------- .../machine/NativeLuaArchitecture.scala | 11 ++-- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/SaveHandler.scala b/src/main/scala/li/cil/oc/common/SaveHandler.scala index 43fa5a520..cce5925a5 100644 --- a/src/main/scala/li/cil/oc/common/SaveHandler.scala +++ b/src/main/scala/li/cil/oc/common/SaveHandler.scala @@ -3,7 +3,7 @@ package li.cil.oc.common import java.io import java.util.logging.Level import li.cil.oc.{OpenComputers, Settings} -import net.minecraft.world.ChunkCoordIntPair +import net.minecraft.world.{World, ChunkCoordIntPair} import net.minecraftforge.common.DimensionManager import net.minecraftforge.event.ForgeSubscribe import net.minecraftforge.event.world.{ChunkDataEvent, WorldEvent} @@ -13,19 +13,20 @@ import scala.collection.mutable // files instead of directly in the tile entity data, avoiding potential // problems with the tile entity data becoming too large. object SaveHandler { - val saveData = mutable.Map.empty[ChunkCoordIntPair, mutable.Map[String, Array[Byte]]] + val saveData = mutable.Map.empty[Int, mutable.Map[ChunkCoordIntPair, mutable.Map[String, Array[Byte]]]] def savePath = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "state") - def scheduleSave(chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized { + def scheduleSave(dimension: Int, chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized { if (chunk == null) throw new IllegalArgumentException("chunk is null") - else saveData.getOrElseUpdate(chunk, mutable.Map.empty[String, Array[Byte]]) += name -> data + else saveData.getOrElseUpdate(dimension, mutable.Map.empty).getOrElseUpdate(chunk, mutable.Map.empty) += name -> data } - def load(chunk: ChunkCoordIntPair, name: String): Array[Byte] = { + def load(dimension: Int, chunk: ChunkCoordIntPair, name: String): Array[Byte] = { if (chunk == null) throw new IllegalArgumentException("chunk is null") val path = savePath - val chunkPath = new io.File(path, s"${chunk.chunkXPos}.${chunk.chunkZPos}") + val dimPath = new io.File(path, dimension.toString) + val chunkPath = new io.File(dimPath, s"${chunk.chunkXPos}.${chunk.chunkZPos}") val file = new io.File(chunkPath, name) try { // val bis = new io.BufferedInputStream(new GZIPInputStream(new io.FileInputStream(file))) @@ -52,32 +53,40 @@ object SaveHandler { @ForgeSubscribe def onChunkSave(e: ChunkDataEvent.Save) = saveData.synchronized { val path = savePath + val dimension = e.world.provider.dimensionId val chunk = e.getChunk.getChunkCoordIntPair - val chunkPath = new io.File(path, s"${chunk.chunkXPos}.${chunk.chunkZPos}") + val dimPath = new io.File(path, dimension.toString) + val chunkPath = new io.File(dimPath, s"${chunk.chunkXPos}.${chunk.chunkZPos}") if (chunkPath.exists && chunkPath.isDirectory) { for (file <- chunkPath.listFiles()) file.delete() } - saveData.get(chunk) match { - case Some(entries) => - chunkPath.mkdirs() - for ((name, data) <- entries) { - val file = new io.File(chunkPath, name) - try { - // val fos = new GZIPOutputStream(new io.FileOutputStream(file)) - val fos = new io.BufferedOutputStream(new io.FileOutputStream(file)) - fos.write(data) - fos.close() + saveData.get(dimension) match { + case Some(chunks) => chunks.get(chunk) match { + case Some(entries) => + chunkPath.mkdirs() + for ((name, data) <- entries) { + val file = new io.File(chunkPath, name) + try { + // val fos = new GZIPOutputStream(new io.FileOutputStream(file)) + val fos = new io.BufferedOutputStream(new io.FileOutputStream(file)) + fos.write(data) + fos.close() + } + catch { + case e: io.IOException => OpenComputers.log.log(Level.WARNING, s"Error saving auxiliary tile entity data to '${file.getAbsolutePath}.", e) + } } - catch { - case e: io.IOException => OpenComputers.log.log(Level.WARNING, s"Error saving auxiliary tile entity data to '${file.getAbsolutePath}.", e) - } - } - case _ => chunkPath.delete() + case _ => chunkPath.delete() + } + case _ => } } @ForgeSubscribe def onWorldSave(e: WorldEvent.Save) = saveData.synchronized { - saveData.clear() + saveData.get(e.world.provider.dimensionId) match { + case Some(chunks) => chunks.clear() + case _ => + } } } diff --git a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala index 6fc7996fe..384dc6da2 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala @@ -598,9 +598,10 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu // on. First, clear the stack, meaning the current kernel. lua.setTop(0) + val dimension = nbt.getInteger("dimension") val kernel = if (nbt.hasKey("kernel")) nbt.getByteArray("kernel") - else SaveHandler.load(new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel") + else SaveHandler.load(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel") unpersist(kernel) if (!lua.isThread(1)) { // This shouldn't really happen, but there's a chance it does if @@ -610,7 +611,7 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) { val stack = if (nbt.hasKey("stack")) nbt.getByteArray("stack") - else SaveHandler.load(new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack") + else SaveHandler.load(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack") unpersist(stack) if (!(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))) { // Same as with the above, should not really happen normally, but @@ -638,12 +639,14 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu // Try persisting Lua, because that's what all of the rest depends on. // Save the kernel state (which is always at stack index one). assert(lua.isThread(1)) - SaveHandler.scheduleSave(new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel", persist(1)) + val dimension = machine.owner.world.provider.dimensionId + nbt.setInteger("dimension", dimension) + SaveHandler.scheduleSave(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_kernel", persist(1)) // While in a driver call we have one object on the global stack: either // the function to call the driver with, or the result of the call. if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) { assert(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2)) - SaveHandler.scheduleSave(new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack", persist(2)) + SaveHandler.scheduleSave(dimension, new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4), node.address + "_stack", persist(2)) } nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt)