diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index bf4eee9da..49984a4e7 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -50,6 +50,7 @@ class 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) @@ -326,6 +327,13 @@ class 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) => diff --git a/src/main/scala/li/cil/oc/client/PacketSender.scala b/src/main/scala/li/cil/oc/client/PacketSender.scala index a6153667a..fcb00dcbe 100644 --- a/src/main/scala/li/cil/oc/client/PacketSender.scala +++ b/src/main/scala/li/cil/oc/client/PacketSender.scala @@ -163,4 +163,12 @@ object PacketSender { pb.sendToServer() } + + def sendTextBufferInit(address: String) { + val pb = new PacketBuilder(PacketType.TextBufferInit) + + pb.writeUTF(address) + + pb.sendToServer() + } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index 7e4589d57..c849ca8ca 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -31,6 +31,7 @@ object PacketType extends Enumeration { TextBufferCopy, TextBufferDepthChange, TextBufferFill, + TextBufferInit, // Goes both ways. TextBufferPaletteChange, TextBufferPowerChange, TextBufferResolutionChange, diff --git a/src/main/scala/li/cil/oc/common/SaveHandler.scala b/src/main/scala/li/cil/oc/common/SaveHandler.scala index c48b8aad6..ddf3426bd 100644 --- a/src/main/scala/li/cil/oc/common/SaveHandler.scala +++ b/src/main/scala/li/cil/oc/common/SaveHandler.scala @@ -1,13 +1,13 @@ package li.cil.oc.common import java.io -import java.io.{File, FileFilter} +import java.io._ import java.util.logging.Level import li.cil.oc.api.driver.Container import li.cil.oc.api.machine.Owner import li.cil.oc.{OpenComputers, Settings} -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.{CompressedStreamTools, NBTTagCompound} import net.minecraft.world.{ChunkCoordIntPair, World} import net.minecraftforge.common.DimensionManager import net.minecraftforge.event.ForgeSubscribe @@ -31,8 +31,13 @@ object SaveHandler { scheduleSave(owner.world, owner.x, owner.z, nbt, name, data) } - def scheduleSave(container: Container, nbt: NBTTagCompound, name: String, data: Array[Byte]) { - scheduleSave(container.world, math.round(container.xPosition - 0.5).toInt, math.round(container.zPosition - 0.5).toInt, 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]) { @@ -48,6 +53,13 @@ object SaveHandler { 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 diff --git a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala index 2cacdefaa..ba2f41c3b 100644 --- a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala @@ -7,7 +7,7 @@ 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._ @@ -360,7 +360,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 +393,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 +426,7 @@ object TextBuffer { } def registerClientBuffer(t: TextBuffer) { + ClientPacketSender.sendTextBufferInit(t.proxy.nodeAddress) ClientComponentTracker.add(t.proxy.nodeAddress, t) clientBuffers ++= mutable.LinkedList(t) } diff --git a/src/main/scala/li/cil/oc/server/PacketHandler.scala b/src/main/scala/li/cil/oc/server/PacketHandler.scala index 9029d3172..bc75ce19e 100644 --- a/src/main/scala/li/cil/oc/server/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/server/PacketHandler.scala @@ -2,12 +2,14 @@ package li.cil.oc.server import cpw.mods.fml.common.network.Player 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.{Settings, api} import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP} +import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.ChatMessageComponent import net.minecraftforge.common.{DimensionManager, ForgeDirection} @@ -31,6 +33,7 @@ class 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. } @@ -188,4 +191,19 @@ class 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. + } + } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index b4a8ec38e..c613ab38d 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -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.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)