diff --git a/src/main/java/li/cil/oc/api/API.java b/src/main/java/li/cil/oc/api/API.java index 05d44ccf0..0623789c7 100644 --- a/src/main/java/li/cil/oc/api/API.java +++ b/src/main/java/li/cil/oc/api/API.java @@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*; */ public class API { public static final String ID_OWNER = "OpenComputers|Core"; - public static final String VERSION = "5.5.1"; + public static final String VERSION = "5.5.2"; public static DriverAPI driver = null; public static FileSystemAPI fileSystem = null; diff --git a/src/main/java/li/cil/oc/api/internal/Database.java b/src/main/java/li/cil/oc/api/internal/Database.java index aa8e943c1..ac9b66cf8 100644 --- a/src/main/java/li/cil/oc/api/internal/Database.java +++ b/src/main/java/li/cil/oc/api/internal/Database.java @@ -34,6 +34,16 @@ public interface Database { */ ItemStack getStackInSlot(int slot); + /** + * Set the contents of a slot in the database upgrade. + *
+ * Use this to change the configuration of a database upgrade. + * + * @param slot the slot to configure. + * @param stack the stack to configure the slot to, null to clear. + */ + void setStackInSlot(int slot, ItemStack stack); + /** * Get an item stack with the specified hash stored in this database. * diff --git a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala index 4fa1fe754..dc23df988 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala @@ -5,8 +5,11 @@ import li.cil.oc.OpenComputers 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.Node import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.common.EventHandler +import li.cil.oc.util.DatabaseAccess +import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.Item @@ -25,6 +28,8 @@ import scala.language.existentials trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] { def tile: AETile + def node: Node + @Callback(doc = "function():table -- Get a list of tables representing the available CPUs in the network.") def getCpus(context: Context, args: Arguments): Array[AnyRef] = result(tile.getProxy.getCrafting.getCpus.map(cpu => Map( @@ -57,6 +62,27 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi result(tile.getProxy.getStorage.getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).toArray) } + @Callback(doc = "function(filter:table, dbAddress:string[, startSlot:number[, count:number]]): Boolean -- Store items in the network matching the specified filter in the database with the specified address.") + def store(context: Context, args: Arguments): Array[AnyRef] = { + val filter = args.checkTable(0).collect { + case (key: String, value: AnyRef) => (key, value) + } + DatabaseAccess.withDatabase(node, args.checkString(1), database => { + val stacks = tile.getProxy.getStorage.getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).filter(_ != null).toArray + val offset = args.optSlot(database.data, 2, 0) + val count = args.optInteger(3, Int.MaxValue) min (database.size - offset) min stacks.length + var slot = offset + for (i <- 0 until count) { + val stack = Option(stacks(i)).map(_.copy()).orNull + while (database.getStackInSlot(slot) != null && slot < database.size) slot += 1 + if (database.getStackInSlot(slot) == null) { + database.setStackInSlot(slot, stack) + } + } + result(true) + }) + } + @Callback(doc = "function():table -- Get a list of the stored fluids in the network.") def getFluidsInNetwork(context: Context, args: Arguments): Array[AnyRef] = result(tile.getProxy.getStorage.getFluidInventory.getStorageList.map(_.getFluidStack).toArray) diff --git a/src/main/scala/li/cil/oc/server/component/Geolyzer.scala b/src/main/scala/li/cil/oc/server/component/Geolyzer.scala index 15ab61b5d..65b46e88c 100644 --- a/src/main/scala/li/cil/oc/server/component/Geolyzer.scala +++ b/src/main/scala/li/cil/oc/server/component/Geolyzer.scala @@ -93,8 +93,8 @@ class Geolyzer(val host: EnvironmentHost) extends prefab.ManagedEnvironment { val stack = new ItemStack(item, 1, damage) DatabaseAccess.withDatabase(node, args.checkString(1), database => { val toSlot = args.checkSlot(database.data, 2) - val nonEmpty = database.data.getStackInSlot(toSlot) != null - database.data.setInventorySlotContents(toSlot, stack) + val nonEmpty = database.getStackInSlot(toSlot) != null + database.setStackInSlot(toSlot, stack) result(nonEmpty) }) } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala b/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala index 686b4cda2..43712f227 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala @@ -23,6 +23,8 @@ class UpgradeDatabase(val data: IInventory) extends prefab.ManagedEnvironment wi override def getStackInSlot(slot: Int) = Option(data.getStackInSlot(slot)).map(_.copy()).orNull + override def setStackInSlot(slot: Int, stack: ItemStack) = data.setInventorySlotContents(slot, stack) + override def findStackWithHash(needle: String) = indexOf(needle) @Callback(doc = "function(slot:number):table -- Get the representation of the item stack stored in the specified slot.") diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala index ced66d1cc..4fce4873a 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala @@ -23,8 +23,8 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware { val localStack = inventory.getStackInSlot(localSlot) DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 2) - val nonEmpty = database.data.getStackInSlot(dbSlot) != null - database.data.setInventorySlotContents(dbSlot, localStack.copy()) + val nonEmpty = database.getStackInSlot(dbSlot) != null + database.setStackInSlot(dbSlot, localStack.copy()) result(nonEmpty) }) } @@ -36,7 +36,7 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware { val localStack = inventory.getStackInSlot(localSlot) DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 2) - val dbStack = database.data.getStackInSlot(dbSlot) + val dbStack = database.getStackInSlot(dbSlot) result(haveSameItemType(localStack, dbStack)) }) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala index 3b9376ac7..d179b8e4f 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala @@ -57,8 +57,8 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ val dbAddress = args.checkString(2) def store(stack: ItemStack) = DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 3) - val nonEmpty = database.data.getStackInSlot(dbSlot) != null - database.data.setInventorySlotContents(dbSlot, stack.copy()) + val nonEmpty = database.getStackInSlot(dbSlot) != null + database.setStackInSlot(dbSlot, stack.copy()) result(nonEmpty) }) withInventory(facing, inventory => store(inventory.getStackInSlot(args.checkSlot(inventory, 1)))) diff --git a/src/main/scala/li/cil/oc/util/UpdateCheck.scala b/src/main/scala/li/cil/oc/util/UpdateCheck.scala index 251f43d72..c9a8a5609 100644 --- a/src/main/scala/li/cil/oc/util/UpdateCheck.scala +++ b/src/main/scala/li/cil/oc/util/UpdateCheck.scala @@ -22,7 +22,8 @@ object UpdateCheck { } private def initialize(): Option[Release] = { - if (Settings.get.updateCheck && OpenComputers.Version != "@VERSION@") { + // Keep the version template split up so it's not replaced with the actual version... + if (Settings.get.updateCheck && OpenComputers.Version != ("@" + "VERSION" + "@")) { try { OpenComputers.log.info("Starting OpenComputers version check.") val reader = new JsonReader(new InputStreamReader(releasesUrl.openStream()))