diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala index 1eae5089c..03012806f 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala @@ -105,7 +105,14 @@ trait Environment extends TileEntity with network.Environment with network.Envir override def onDisconnect(node: network.Node) { if (node == this.node) node match { - case connector: Connector => connector.setLocalBufferSize(0) + case connector: Connector => + // Set it to zero to push all energy into other nodes, to + // avoid energy loss when removing nodes. Set it back to the + // original value though, as there are cases where the node + // is re-used afterwards, without re-adjusting its buffer size. + var bufferSize = connector.localBufferSize() + connector.setLocalBufferSize(0) + connector.setLocalBufferSize(bufferSize) case _ => } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala index ed8514fc4..b23e0c119 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala @@ -2,6 +2,7 @@ package li.cil.oc.integration.opencomputers import li.cil.oc import li.cil.oc.Constants +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.network.EnvironmentHost @@ -18,6 +19,8 @@ import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.DimensionManager object DriverFileSystem extends Item { + val UUIDVerifier = """^([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})$""".r + override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get(Constants.ItemName.HDDTier1), api.Items.get(Constants.ItemName.HDDTier2), @@ -85,7 +88,14 @@ object DriverFileSystem extends Item { private def addressFromTag(tag: NBTTagCompound) = if (tag.hasKey("node") && tag.getCompoundTag("node").hasKey("address")) { - tag.getCompoundTag("node").getString("address") + tag.getCompoundTag("node").getString("address") match { + case UUIDVerifier(address) => address + case _ => // Invalid disk address. + val newAddress = java.util.UUID.randomUUID().toString + tag.getCompoundTag("node").setString("address", newAddress) + OpenComputers.log.warn(s"Generated new address for disk '${newAddress}'.") + newAddress + } } else java.util.UUID.randomUUID().toString diff --git a/src/main/scala/li/cil/oc/integration/redlogic/ModRedLogic.scala b/src/main/scala/li/cil/oc/integration/redlogic/ModRedLogic.scala index a762a2f5b..a41a0f7b8 100644 --- a/src/main/scala/li/cil/oc/integration/redlogic/ModRedLogic.scala +++ b/src/main/scala/li/cil/oc/integration/redlogic/ModRedLogic.scala @@ -19,7 +19,7 @@ object ModRedLogic extends ModProxy with RedstoneProvider { } override def computeInput(pos: BlockPosition, side: ForgeDirection): Int = { - pos.world.get.getTileEntity(pos) match { + pos.world.get.getTileEntity(pos.offset(side)) match { case emitter: IRedstoneEmitter => var strength = 0 for (i <- -1 to 5) { diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala index 6150b80ec..5e717a5d1 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala @@ -12,7 +12,7 @@ trait InventoryTransfer extends traits.WorldAware with traits.SideRestricted { // Return None on success, else Some("failure reason") def onTransferContents(): Option[String] - @Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number[, sourceSlot:number[, sinkSlot:number]]]):number -- Transfer some items between two inventories.""") + @Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number[, sourceSlot:number[, sinkSlot:number]]]):boolean -- Transfer some items between two inventories.""") def transferItem(context: Context, args: Arguments): Array[AnyRef] = { val sourceSide = checkSideForAction(args, 0) val sourcePos = position.offset(sourceSide) diff --git a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala index 527cf02a2..d7c47aaea 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala @@ -16,19 +16,21 @@ trait ItemInventoryControl extends InventoryAware { withItemInventory(args.checkSlot(inventory, 0), itemInventory => result(itemInventory.getSlots)) } - @Callback(doc = "function(inventorySlot:number, slot:number[, count:number=64]):number -- The size of an item inventory in the specified slot.") + @Callback(doc = "function(inventorySlot:number, slot:number[, count:number=64]):number -- Drops an item into the specified slot in the item inventory.") def dropIntoItemInventory(context: Context, args: Arguments): Array[AnyRef] = { withItemInventory(args.checkSlot(inventory, 0), itemInventory => { - val count = args.optItemCount(1) - result(InventoryUtils.extractAnyFromInventory(InventoryUtils.insertIntoInventory(_, itemInventory), inventory, null, count)) + val slot = args.checkSlot(itemInventory, 1) + val count = args.optItemCount(2) + result(InventoryUtils.extractAnyFromInventory(InventoryUtils.insertIntoInventorySlot(_, itemInventory, slot), inventory, null, count)) }) } - @Callback(doc = "function(inventorySlot:number, slot:number[, count:number=64]):number -- The size of an item inventory in the specified slot.") + @Callback(doc = "function(inventorySlot:number, slot:number[, count:number=64]):number -- Sucks an item out of the specified slot in the item inventory.") def suckFromItemInventory(context: Context, args: Arguments): Array[AnyRef] = { withItemInventory(args.checkSlot(inventory, 0), itemInventory => { - val count = args.optItemCount(1) - result(InventoryUtils.extractAnyFromInventory(InventoryUtils.insertIntoInventory(_, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots)), itemInventory, count)) + val slot = args.checkSlot(itemInventory, 1) + val count = args.optItemCount(2) + result(InventoryUtils.extractFromInventorySlot(InventoryUtils.insertIntoInventory(_, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots)), itemInventory, slot, count)) }) } diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index de36e8066..6ae0cdd07 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -766,7 +766,11 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach }) override def save(nbt: NBTTagCompound): Unit = Machine.this.synchronized(state.synchronized { - assert(!isExecuting) // Lock on 'this' should guarantee this. + // The lock on 'this' should guarantee that this never happens regularly. + // If something other than regular saving tries to save while we are executing code, + // e.g. SpongeForge saving during robot.move due to block changes being captured, + // just don't save this at all. What could possibly go wrong? + if(isExecuting) return if (SaveHandler.savingForClients) { return @@ -1077,4 +1081,4 @@ object Machine extends MachineAPI { } private val threadPool = ThreadPoolFactory.create("Computer", Settings.get.threads) -} \ No newline at end of file +} diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala index 4ad333ed2..2c8b2388b 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala @@ -231,7 +231,7 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture recomputeMemory(machine.host.internalComponents) - val kernel = lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "machine.lua"), "=kernel", "t", lua) + val kernel = lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "machine.lua"), "=machine", "t", lua) thread = new LuaThread(lua, kernel) // Left as the first value on the stack. true