mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 19:56:17 -04:00
Merge branch 'master' of github.com:MightyPirates/OpenComputers into master-MC1.7.10
Conflicts: src/main/scala/li/cil/oc/common/SaveHandler.scala src/main/scala/li/cil/oc/server/PacketHandler.scala
This commit is contained in:
commit
c78405ecf2
@ -2,7 +2,7 @@ package li.cil.oc.client
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent
|
||||
import li.cil.oc.{Localization, Settings}
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.api.component
|
||||
import li.cil.oc.client.renderer.PetRenderer
|
||||
import li.cil.oc.common.tileentity._
|
||||
@ -12,7 +12,6 @@ import li.cil.oc.util.Audio
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiScreen
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.ChatComponentTranslation
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
import org.lwjgl.input.Keyboard
|
||||
|
||||
@ -57,6 +56,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
case PacketType.TextBufferCopy => onTextBufferCopy(p)
|
||||
case PacketType.TextBufferDepthChange => onTextBufferDepthChange(p)
|
||||
case PacketType.TextBufferFill => onTextBufferFill(p)
|
||||
case PacketType.TextBufferInit => onTextBufferInit(p)
|
||||
case PacketType.TextBufferPaletteChange => onTextBufferPaletteChange(p)
|
||||
case PacketType.TextBufferPowerChange => onTextBufferPowerChange(p)
|
||||
case PacketType.TextBufferResolutionChange => onTextBufferResolutionChange(p)
|
||||
@ -333,6 +333,13 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
def onTextBufferInit(p: PacketParser) {
|
||||
ComponentTracker.get(p.readUTF()) match {
|
||||
case Some(buffer: li.cil.oc.common.component.TextBuffer) => buffer.data.load(p.readNBT())
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
|
||||
def onTextBufferPaletteChange(p: PacketParser) {
|
||||
ComponentTracker.get(p.readUTF()) match {
|
||||
case Some(buffer: component.TextBuffer) =>
|
||||
|
@ -167,4 +167,12 @@ object PacketSender {
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendTextBufferInit(address: String) {
|
||||
val pb = new PacketBuilder(PacketType.TextBufferInit)
|
||||
|
||||
pb.writeUTF(address)
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ object PacketType extends Enumeration {
|
||||
TextBufferCopy,
|
||||
TextBufferDepthChange,
|
||||
TextBufferFill,
|
||||
TextBufferInit, // Goes both ways.
|
||||
TextBufferPaletteChange,
|
||||
TextBufferPowerChange,
|
||||
TextBufferResolutionChange,
|
||||
|
@ -1,11 +1,14 @@
|
||||
package li.cil.oc.common
|
||||
|
||||
import java.io
|
||||
import java.io.{File, FileFilter}
|
||||
import java.io._
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import li.cil.oc.api.driver.Container
|
||||
import li.cil.oc.api.machine.Owner
|
||||
import li.cil.oc.{OpenComputers, Settings}
|
||||
import net.minecraft.world.ChunkCoordIntPair
|
||||
import net.minecraft.nbt.{CompressedStreamTools, NBTTagCompound}
|
||||
import net.minecraft.world.{ChunkCoordIntPair, World}
|
||||
import net.minecraftforge.common.DimensionManager
|
||||
import net.minecraftforge.event.world.{ChunkDataEvent, WorldEvent}
|
||||
|
||||
@ -23,6 +26,49 @@ object SaveHandler {
|
||||
|
||||
def statePath = new io.File(savePath, "state")
|
||||
|
||||
def scheduleSave(owner: Owner, nbt: NBTTagCompound, name: String, data: Array[Byte]) {
|
||||
scheduleSave(owner.world, owner.x, owner.z, nbt, name, data)
|
||||
}
|
||||
|
||||
def scheduleSave(container: Container, nbt: NBTTagCompound, name: String, save: NBTTagCompound => Unit) {
|
||||
val tmpNbt = new NBTTagCompound()
|
||||
save(tmpNbt)
|
||||
val baos = new ByteArrayOutputStream()
|
||||
val dos = new DataOutputStream(baos)
|
||||
CompressedStreamTools.write(tmpNbt, dos)
|
||||
scheduleSave(container.world, math.round(container.xPosition - 0.5).toInt, math.round(container.zPosition - 0.5).toInt, nbt, name, baos.toByteArray)
|
||||
}
|
||||
|
||||
def scheduleSave(world: World, x: Int, z: Int, nbt: NBTTagCompound, name: String, data: Array[Byte]) {
|
||||
val dimension = world.provider.dimensionId
|
||||
val chunk = new ChunkCoordIntPair(x >> 4, z >> 4)
|
||||
|
||||
// We have to save the dimension and chunk coordinates, because they are
|
||||
// not available on load / may have changed if the computer was moved.
|
||||
nbt.setInteger("dimension", dimension)
|
||||
nbt.setInteger("chunkX", chunk.chunkXPos)
|
||||
nbt.setInteger("chunkZ", chunk.chunkZPos)
|
||||
|
||||
scheduleSave(dimension, chunk, name, data)
|
||||
}
|
||||
|
||||
def loadNBT(nbt: NBTTagCompound, name: String): NBTTagCompound = {
|
||||
val data = load(nbt, name)
|
||||
val bais = new ByteArrayInputStream(data)
|
||||
val dis = new DataInputStream(bais)
|
||||
CompressedStreamTools.read(dis)
|
||||
}
|
||||
|
||||
def load(nbt: NBTTagCompound, name: String): Array[Byte] = {
|
||||
// Since we have no world yet, we rely on the dimension we were saved in.
|
||||
// Same goes for the chunk. This also works around issues with computers
|
||||
// being moved (e.g. Redstone in Motion).
|
||||
val dimension = nbt.getInteger("dimension")
|
||||
val chunk = new ChunkCoordIntPair(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ"))
|
||||
|
||||
load(dimension, chunk, name)
|
||||
}
|
||||
|
||||
def scheduleSave(dimension: Int, chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized {
|
||||
if (chunk == null) throw new IllegalArgumentException("chunk is null")
|
||||
else {
|
||||
|
@ -8,10 +8,9 @@ import li.cil.oc.api.driver.Container
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.client.renderer.TextBufferRenderCache
|
||||
import li.cil.oc.client.{ComponentTracker => ClientComponentTracker, PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.common.{SaveHandler, tileentity}
|
||||
import li.cil.oc.server.component.Keyboard
|
||||
import li.cil.oc.server.{ComponentTracker => ServerComponentTracker, PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.{PackedColor, SideTracker}
|
||||
import li.cil.oc.{Settings, api, util}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -360,7 +359,10 @@ class TextBuffer(val owner: Container) extends ManagedComponent with api.compone
|
||||
proxy.nodeAddress = nbt.getCompoundTag("node").getString("address")
|
||||
TextBuffer.registerClientBuffer(this)
|
||||
}
|
||||
data.load(nbt.getCompoundTag("buffer"))
|
||||
else {
|
||||
if (nbt.hasKey("buffer")) data.load(nbt.getCompoundTag("buffer"))
|
||||
else data.load(SaveHandler.loadNBT(nbt, node.address + "_buffer"))
|
||||
}
|
||||
|
||||
if (nbt.hasKey(Settings.namespace + "isOn")) {
|
||||
isDisplaying = nbt.getBoolean(Settings.namespace + "isOn")
|
||||
@ -390,7 +392,7 @@ class TextBuffer(val owner: Container) extends ManagedComponent with api.compone
|
||||
}
|
||||
}
|
||||
|
||||
nbt.setNewCompoundTag("buffer", data.save)
|
||||
SaveHandler.scheduleSave(owner, nbt, node.address + "_buffer", data.save _)
|
||||
nbt.setBoolean(Settings.namespace + "isOn", isDisplaying)
|
||||
nbt.setBoolean(Settings.namespace + "hasPower", hasPower)
|
||||
}
|
||||
@ -423,6 +425,7 @@ object TextBuffer {
|
||||
}
|
||||
|
||||
def registerClientBuffer(t: TextBuffer) {
|
||||
ClientPacketSender.sendTextBufferInit(t.proxy.nodeAddress)
|
||||
ClientComponentTracker.add(t.proxy.nodeAddress, t)
|
||||
clientBuffers += t
|
||||
}
|
||||
|
@ -3,12 +3,14 @@ package li.cil.oc.server
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import cpw.mods.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent
|
||||
import li.cil.oc.api.machine.Machine
|
||||
import li.cil.oc.common.component.TextBuffer
|
||||
import li.cil.oc.common.multipart.EventHandler
|
||||
import li.cil.oc.common.tileentity._
|
||||
import li.cil.oc.common.tileentity.traits.{Computer, TileEntity}
|
||||
import li.cil.oc.common.{PacketType, PacketHandler => CommonPacketHandler}
|
||||
import li.cil.oc.{Localization, Settings, api}
|
||||
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.network.NetHandlerPlayServer
|
||||
import net.minecraftforge.common.DimensionManager
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
@ -37,6 +39,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
case PacketType.ServerRange => onServerRange(p)
|
||||
case PacketType.ServerSide => onServerSide(p)
|
||||
case PacketType.ServerSwitchMode => onServerSwitchMode(p)
|
||||
case PacketType.TextBufferInit => onTextBufferInit(p)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
@ -195,4 +198,19 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onTextBufferInit(p: PacketParser) {
|
||||
val address = p.readUTF()
|
||||
p.player match {
|
||||
case entity: EntityPlayerMP =>
|
||||
ComponentTracker.get(address) match {
|
||||
case Some(buffer: TextBuffer) =>
|
||||
val nbt = new NBTTagCompound()
|
||||
buffer.data.save(nbt)
|
||||
PacketSender.sendTextBufferInit(address, nbt, entity)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import li.cil.oc.common.{CompressedPacketBuilder, PacketBuilder, PacketType, til
|
||||
import li.cil.oc.util.PackedColor
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
@ -308,6 +309,15 @@ object PacketSender {
|
||||
pb.sendToNearbyPlayers(container)
|
||||
}
|
||||
|
||||
def sendTextBufferInit(address: String, value: NBTTagCompound, player: EntityPlayerMP) {
|
||||
val pb = new CompressedPacketBuilder(PacketType.TextBufferInit)
|
||||
|
||||
pb.writeUTF(address)
|
||||
pb.writeNBT(value)
|
||||
|
||||
pb.sendToPlayer(player)
|
||||
}
|
||||
|
||||
def sendTextBufferPaletteChange(address: String, index: Int, color: Int, container: Container) {
|
||||
val pb = new PacketBuilder(PacketType.TextBufferPaletteChange)
|
||||
|
||||
|
@ -11,7 +11,6 @@ import li.cil.oc.util.ExtendedLuaState.extendLuaState
|
||||
import li.cil.oc.util.LuaStateFactory
|
||||
import li.cil.oc.{OpenComputers, Settings, api}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.ChunkCoordIntPair
|
||||
|
||||
class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architecture {
|
||||
private[machine] var lua: LuaState = null
|
||||
@ -327,29 +326,14 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
|
||||
// on. First, clear the stack, meaning the current kernel.
|
||||
lua.setTop(0)
|
||||
|
||||
// Since we have no world yet, we rely on the dimension we were saved in.
|
||||
// Same goes for the chunk. This also works around issues with computers
|
||||
// being moved (e.g. Redstone in Motion).
|
||||
val dimension = nbt.getInteger("dimension")
|
||||
val chunk =
|
||||
if (nbt.hasKey("chunkX") && nbt.hasKey("chunkZ"))
|
||||
new ChunkCoordIntPair(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ"))
|
||||
else
|
||||
new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4)
|
||||
val kernel =
|
||||
if (nbt.hasKey("kernel")) nbt.getByteArray("kernel")
|
||||
else SaveHandler.load(dimension, chunk, machine.node.address + "_kernel")
|
||||
persistence.unpersist(kernel)
|
||||
persistence.unpersist(SaveHandler.load(nbt, machine.node.address + "_kernel"))
|
||||
if (!lua.isThread(1)) {
|
||||
// This shouldn't really happen, but there's a chance it does if
|
||||
// the save was corrupt (maybe someone modified the Lua files).
|
||||
throw new LuaRuntimeException("Invalid kernel.")
|
||||
}
|
||||
if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) {
|
||||
val stack =
|
||||
if (nbt.hasKey("stack")) nbt.getByteArray("stack")
|
||||
else SaveHandler.load(dimension, chunk, machine.node.address + "_stack")
|
||||
persistence.unpersist(stack)
|
||||
persistence.unpersist(SaveHandler.load(nbt, machine.node.address + "_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
|
||||
// could for the same reasons.
|
||||
@ -388,19 +372,12 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
|
||||
// Save the kernel state (which is always at stack index one).
|
||||
assert(lua.isThread(1))
|
||||
|
||||
// We have to save the dimension and chunk coordinates, because they are
|
||||
// not available on load / may have changed if the computer was moved.
|
||||
val dimension = machine.owner.world.provider.dimensionId
|
||||
val chunk = new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4)
|
||||
nbt.setInteger("dimension", dimension)
|
||||
nbt.setInteger("chunkX", chunk.chunkXPos)
|
||||
nbt.setInteger("chunkZ", chunk.chunkZPos)
|
||||
SaveHandler.scheduleSave(dimension, chunk, machine.node.address + "_kernel", persistence.persist(1))
|
||||
SaveHandler.scheduleSave(machine.owner, nbt, machine.node.address + "_kernel", persistence.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(dimension, chunk, machine.node.address + "_stack", persistence.persist(2))
|
||||
SaveHandler.scheduleSave(machine.owner, nbt, machine.node.address + "_stack", persistence.persist(2))
|
||||
}
|
||||
|
||||
nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt)
|
||||
|
Loading…
x
Reference in New Issue
Block a user