Skip to content

Commit

Permalink
Merge pull request MightyPirates#21 from repo-alt/master-MC1.7.10
Browse files Browse the repository at this point in the history
Network items iterator
  • Loading branch information
repo-alt authored Nov 17, 2020
2 parents f3c861b + 2dc597d commit 8d81073
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 41 deletions.
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
minecraft.version=1.7.10
forge.version=10.13.4.1614-1.7.10

oc.version=1.7.5.5
oc.version=1.7.5.6

ae2.version=rv2-beta-26
bc.version=7.0.9
Expand Down
135 changes: 95 additions & 40 deletions src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import appeng.api.networking.crafting.ICraftingLink
import appeng.api.networking.crafting.ICraftingRequester
import appeng.api.networking.security.IActionHost
import appeng.api.networking.security.MachineSource
import appeng.api.storage.data.IAEItemStack
import appeng.api.storage.data.{IAEItemStack, IItemList}
import appeng.me.helpers.IGridProxyable
import appeng.util.item.AEItemStack
import com.google.common.collect.ImmutableSet
Expand All @@ -18,6 +18,7 @@ import li.cil.oc.api.network.Node
import li.cil.oc.api.prefab.AbstractValue
import li.cil.oc.common.EventHandler
import li.cil.oc.integration.Mods
import li.cil.oc.integration.appeng.NetworkControl._
import li.cil.oc.integration.ec.ECUtil
import li.cil.oc.server.driver.Registry
import li.cil.oc.util.DatabaseAccess
Expand All @@ -44,43 +45,8 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi

def node: Node

private def aeCraftItem(aeItem: IAEItemStack): IAEItemStack = {
val patterns = tile.getProxy.getCrafting.getCraftingFor(aeItem, null, 0, tile.getWorldObj)
patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match {
case Some(pattern) => pattern.getOutputs.find(_.isSameType(aeItem)).get
case _ => aeItem.copy.setStackSize(0) // Should not be possible, but hey...
}
}

private def aePotentialItem(aeItem: IAEItemStack): IAEItemStack = {
if (aeItem.getStackSize > 0 || !aeItem.isCraftable)
aeItem
else
aeCraftItem(aeItem)
}

private def allItems: Iterable[IAEItemStack] = tile.getProxy.getStorage.getItemInventory.getStorageList
private def allCraftables: Iterable[IAEItemStack] = allItems.collect{ case aeItem if aeItem.isCraftable => aeCraftItem(aeItem) }

private def convert(aeItem: IAEItemStack): java.util.HashMap[String, AnyRef] = {
def hashConvert(value: java.util.HashMap[_, _]) = {
val hash = new java.util.HashMap[String, AnyRef]
value.collect{ case (k:String, v:AnyRef) => hash += k -> v }
hash
}
val potentialItem = aePotentialItem(aeItem)
val result = Registry.convert(Array[AnyRef](potentialItem.getItemStack))
.collect { case hash: java.util.HashMap[_,_] => hashConvert(hash) }
if (result.length > 0) {
val hash = result(0)
// it would have been nice to put these fields in a registry convert
// but the potential ae item needs the tile and position data
hash.update("size", Int.box(aeItem.getStackSize.toInt))
hash.update("isCraftable", Boolean.box(aeItem.isCraftable))
return hash
}
null
}
private def allCraftables: Iterable[IAEItemStack] = allItems.collect{ case aeItem if aeItem.isCraftable => aeCraftItem(aeItem, tile) }

@Callback(doc = "function():table -- Get a list of tables representing the available CPUs in the network.")
def getCpus(context: Context, args: Arguments): Array[AnyRef] = {
Expand All @@ -101,7 +67,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
case (key: String, value: AnyRef) => (key, value)
}
result(allCraftables
.collect{ case aeCraftItem if filter.isEmpty || matches(convert(aeCraftItem), filter) => new NetworkControl.Craftable(tile, aeCraftItem) }
.collect{ case aeCraftItem if filter.isEmpty || matches(convert(aeCraftItem, tile), filter) => new NetworkControl.Craftable(tile, aeCraftItem) }
.toArray)
}

Expand All @@ -111,19 +77,24 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
case (key: String, value: AnyRef) => (key, value)
}
result(allItems
.map(convert)
.map(item => convert(item, tile))
.filter(hash => matches(hash, filter))
.toArray)
}

@Callback(doc = "function():userdata -- Get an iterator object for the list of the items in the network.")
def allItems(context: Context, args: Arguments): Array[AnyRef] = {
result(new NetworkContents(tile))
}

@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 items = allItems
.collect{ case aeItem if matches(convert(aeItem), filter) => aePotentialItem(aeItem)}.toArray
.collect{ case aeItem if matches(convert(aeItem, tile), filter) => aePotentialItem(aeItem, tile)}.toArray
val offset = args.optSlot(database.data, 2, 0)
val count = args.optInteger(3, Int.MaxValue) min (database.size - offset) min items.length
var slot = offset
Expand Down Expand Up @@ -344,4 +315,88 @@ object NetworkControl {
}
}

class NetworkContents(var controller: TileEntity with IGridProxyable) extends AbstractValue
{
def this() = this(null)
var items : IItemList[IAEItemStack] = null
var i : java.util.Iterator[IAEItemStack] = null
var index = 0

override def call(context: Context, arguments: Arguments): Array[AnyRef] = {
if (controller == null) return null
if (items == null) {
items = controller.getProxy.getStorage.getItemInventory.getStorageList
if (items != null)
i = items.iterator
if (i != null)
for (_ <- 1 to index) {
if (i.hasNext)
i.next
}
}
if (this.i == null && this.items != null)
this.i = items.iterator
if (!this.i.hasNext()) return null
index += 1
Array[AnyRef](convert(i.next(), controller))
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
if (nbt.hasKey("dimension")) {
val dimension = nbt.getInteger("dimension")
val x = nbt.getInteger("x")
val y = nbt.getInteger("y")
val z = nbt.getInteger("z")
index = nbt.getInteger("index")
EventHandler.scheduleServer(() => {
val tileEntity = DimensionManager.getWorld(dimension).getTileEntity(x, y, z)
if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IGridProxyable])
controller = tileEntity.asInstanceOf[TileEntity with IGridProxyable]
})
}
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setInteger("index", index)
if (controller != null && !controller.isInvalid) {
nbt.setInteger("dimension", controller.getWorldObj.provider.dimensionId)
nbt.setInteger("x", controller.xCoord)
nbt.setInteger("y", controller.yCoord)
nbt.setInteger("z", controller.zCoord)
}
}
}
def aeCraftItem(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): IAEItemStack = {
val patterns = tile.getProxy.getCrafting.getCraftingFor(aeItem, null, 0, tile.getWorldObj)
patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match {
case Some(pattern) => pattern.getOutputs.find(_.isSameType(aeItem)).get
case _ => aeItem.copy.setStackSize(0) // Should not be possible, but hey...
}
}

def aePotentialItem(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): IAEItemStack = {
if (aeItem.getStackSize > 0 || !aeItem.isCraftable)
aeItem
else
aeCraftItem(aeItem, tile)
}
def convert(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): java.util.HashMap[String, AnyRef] = {
def hashConvert(value: java.util.HashMap[_, _]) = {
val hash = new java.util.HashMap[String, AnyRef]
value.collect{ case (k:String, v:AnyRef) => hash += k -> v }
hash
}
val potentialItem = aePotentialItem(aeItem, tile)
val result = Registry.convert(Array[AnyRef](potentialItem.getItemStack))
.collect { case hash: java.util.HashMap[_,_] => hashConvert(hash) }
if (result.length > 0) {
val hash = result(0)
// it would have been nice to put these fields in a registry convert
// but the potential ae item needs the tile and position data
hash.update("size", Int.box(aeItem.getStackSize.toInt))
hash.update("isCraftable", Boolean.box(aeItem.isCraftable))
return hash
}
null
}
}

0 comments on commit 8d81073

Please sign in to comment.