Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8

Conflicts:
	src/main/scala/li/cil/oc/server/component/DebugCard.scala
	src/main/scala/li/cil/oc/util/ExtendedNBT.scala
This commit is contained in:
Florian Nücke 2015-07-26 22:08:04 +02:00
commit ab444987d8
2 changed files with 150 additions and 4 deletions

View File

@ -17,6 +17,7 @@ import li.cil.oc.api.prefab.AbstractValue
import li.cil.oc.server.component.DebugCard.CommandSender
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedArguments._
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ExtendedWorld._
import li.cil.oc.util.InventoryUtils
import net.minecraft.block.Block
@ -24,10 +25,10 @@ import net.minecraft.command.CommandResultStats.Type
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.nbt.JsonToNBT
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.nbt._
import net.minecraft.server.MinecraftServer
import net.minecraft.server.management.UserListOpsEntry
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.BlockPos
import net.minecraft.util.EnumFacing
import net.minecraft.util.IChatComponent
@ -417,6 +418,34 @@ object DebugCard {
result(state.getBlock.hasTileEntity(state))
}
@Callback(doc = """function(x:number, y:number, z:number):table -- Get the NBT of the block at the specified coordinates.""")
def getTileNBT(context: Context, args: Arguments): Array[AnyRef] = {
checkEnabled()
val blockPos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))
world.getTileEntity(blockPos) match {
case tileEntity: TileEntity => result(toNbt(tileEntity).toTypedMap)
case _ => null
}
}
@Callback(doc = """function(x:number, y:number, z:number, nbt:table):boolean -- Set the NBT of the block at the specified coordinates.""")
def setTileNBT(context: Context, args: Arguments): Array[AnyRef] = {
checkEnabled()
val blockPos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))
world.getTileEntity(blockPos) match {
case tileEntity: TileEntity =>
typedMapToNbt(mapAsScalaMap(args.checkTable(3)).toMap) match {
case nbt: NBTTagCompound =>
tileEntity.readFromNBT(nbt)
tileEntity.markDirty()
world.markBlockForUpdate(blockPos)
result(true)
case nbt => result(null, s"nbt tag compound expected, got '${NBTBase.NBT_TYPES(nbt.getId)}'")
}
case _ => result(null, "no tile entity")
}
}
@Callback(doc = """function(x:number, y:number, z:number):number -- Get the light opacity of the block at the specified coordinates.""")
def getLightOpacity(context: Context, args: Arguments): Array[AnyRef] = {
checkEnabled()

View File

@ -1,10 +1,13 @@
package li.cil.oc.util
import com.google.common.base.Charsets
import net.minecraft.item.ItemStack
import net.minecraft.nbt._
import net.minecraft.util.EnumFacing
import net.minecraftforge.common.util.Constants.NBT
import scala.collection.mutable.ArrayBuffer
import scala.collection.convert.WrapAsScala._
import scala.collection.mutable
import scala.language.implicitConversions
import scala.language.reflectiveCalls
import scala.reflect.ClassTag
@ -66,6 +69,99 @@ object ExtendedNBT {
nbt
}
def typedMapToNbt(map: Map[_, _]): NBTBase = {
def mapToList(value: Array[(_, _)]) = value.collect {
// Ignore, can be stuff like the 'n' introduced by Lua's `pack`.
case (k: Number, v) => k -> v
}.sortBy(_._1.intValue()).map(_._2)
def asList(value: Option[Any]): IndexedSeq[_] = value match {
case Some(v: Array[_]) => v
case Some(v: Map[_, _]) => mapToList(v.toArray)
case Some(v: mutable.Map[_, _]) => mapToList(v.toArray)
case Some(v: java.util.Map[_, _]) => mapToList(mapAsScalaMap(v).toArray)
case Some(v: String) => v.getBytes(Charsets.UTF_8)
case _ => throw new IllegalArgumentException("Illegal or missing value.")
}
def asMap[K](value: Option[Any]): Map[K, _] = value match {
case Some(v: Map[K, _]@unchecked) => v
case Some(v: mutable.Map[K, _]@unchecked) => v.toMap
case Some(v: java.util.Map[K, _]@unchecked) => mapAsScalaMap(v).toMap
case _ => throw new IllegalArgumentException("Illegal value.")
}
val typeAndValue = asMap[String](Option(map))
val nbtType = typeAndValue.get("type")
val nbtValue = typeAndValue.get("value")
nbtType match {
case Some(n: Number) => n.intValue() match {
case NBT.TAG_BYTE => new NBTTagByte(nbtValue match {
case Some(v: Number) => v.byteValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_SHORT => new NBTTagShort(nbtValue match {
case Some(v: Number) => v.shortValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_INT => new NBTTagInt(nbtValue match {
case Some(v: Number) => v.intValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_LONG => new NBTTagLong(nbtValue match {
case Some(v: Number) => v.longValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_FLOAT => new NBTTagFloat(nbtValue match {
case Some(v: Number) => v.floatValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_DOUBLE => new NBTTagDouble(nbtValue match {
case Some(v: Number) => v.doubleValue()
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_BYTE_ARRAY => new NBTTagByteArray(asList(nbtValue).map {
case n: Number => n.byteValue()
case _ => throw new IllegalArgumentException("Illegal value.")
}.toArray)
case NBT.TAG_STRING => new NBTTagString(nbtValue match {
case Some(v: String) => v
case Some(v: Array[Byte]) => new String(v, Charsets.UTF_8)
case _ => throw new IllegalArgumentException("Illegal or missing value.")
})
case NBT.TAG_LIST =>
val list = new NBTTagList()
asList(nbtValue).map(v => asMap(Option(v))).foreach(v => list.appendTag(typedMapToNbt(v)))
list
case NBT.TAG_COMPOUND =>
val nbt = new NBTTagCompound()
val values = asMap[String](nbtValue)
for ((name, entry) <- values) {
try nbt.setTag(name, typedMapToNbt(asMap[Any](Option(entry)))) catch {
case t: Throwable => throw new IllegalArgumentException(s"Error converting entry '$name': ${t.getMessage}")
}
}
nbt
case NBT.TAG_INT_ARRAY =>
new NBTTagIntArray(asList(nbtValue).map {
case n: Number => n.intValue()
case _ => throw new IllegalArgumentException()
}.toArray)
case _ => throw new IllegalArgumentException(s"Unsupported NBT type '$n'.")
}
case Some(t) => throw new IllegalArgumentException(s"Illegal NBT type '$t'.")
case _ => throw new IllegalArgumentException(s"Missing NBT type.")
}
}
implicit def booleanIterableToNbt(value: Iterable[Boolean]): Iterable[NBTTagByte] = value.map(toNbt)
implicit def byteIterableToNbt(value: Iterable[Byte]): Iterable[NBTTagByte] = value.map(toNbt)
@ -90,10 +186,31 @@ object ExtendedNBT {
implicit def itemStackIterableToNbt(value: Iterable[ItemStack]): Iterable[NBTTagCompound] = value.map(toNbt)
implicit def extendNBTBase(nbt: NBTBase): ExtendedNBTBase = new ExtendedNBTBase(nbt)
implicit def extendNBTTagCompound(nbt: NBTTagCompound): ExtendedNBTTagCompound = new ExtendedNBTTagCompound(nbt)
implicit def extendNBTTagList(nbt: NBTTagList): ExtendedNBTTagList = new ExtendedNBTTagList(nbt)
class ExtendedNBTBase(val nbt: NBTBase) {
def toTypedMap: Map[String, _] = Map("type" -> nbt.getId, "value" -> (nbt match {
case tag: NBTTagByte => tag.getByte
case tag: NBTTagShort => tag.getShort
case tag: NBTTagInt => tag.getInt
case tag: NBTTagLong => tag.getLong
case tag: NBTTagFloat => tag.getFloat
case tag: NBTTagDouble => tag.getDouble
case tag: NBTTagByteArray => tag.getByteArray
case tag: NBTTagString => tag.getString
case tag: NBTTagList => tag.map((entry: NBTBase) => entry.toTypedMap)
case tag: NBTTagCompound => tag.getKeySet.collect {
case key: String => key -> tag.getTag(key).toTypedMap
}.toMap
case tag: NBTTagIntArray => tag.getIntArray
case _ => throw new IllegalArgumentException()
}))
}
class ExtendedNBTTagCompound(val nbt: NBTTagCompound) {
def setNewCompoundTag(name: String, f: (NBTTagCompound) => Any) = {
val t = new NBTTagCompound()
@ -154,7 +271,7 @@ object ExtendedNBT {
def map[Tag <: NBTBase, Value](f: Tag => Value): IndexedSeq[Value] = {
val iterable = nbt.copy.asInstanceOf[NBTTagList]
val buffer = ArrayBuffer.empty[Value]
val buffer = mutable.ArrayBuffer.empty[Value]
while (iterable.tagCount > 0) {
buffer += f(iterable.removeTag(0).asInstanceOf[Tag])
}