add sync calls for tablet state on client

only adding fix for 1.12 thanks to player inventory change count

closes #2696
This commit is contained in:
payonel 2018-11-14 18:04:06 -08:00
parent 71f54dd631
commit acf244034e
6 changed files with 103 additions and 11 deletions

View File

@ -12,6 +12,7 @@ import li.cil.oc.client.renderer.PetRenderer
import li.cil.oc.common.Loot
import li.cil.oc.common.PacketType
import li.cil.oc.common.container
import li.cil.oc.common.item.{Tablet, TabletWrapper}
import li.cil.oc.common.nanomachines.ControllerImpl
import li.cil.oc.common.tileentity._
import li.cil.oc.common.tileentity.traits._
@ -58,6 +59,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.ClientLog => onClientLog(p)
case PacketType.Clipboard => onClipboard(p)
case PacketType.ColorChange => onColorChange(p)
case PacketType.MachineItemStateResponse => onMachineItemStateResponse(p)
case PacketType.ComputerState => onComputerState(p)
case PacketType.ComputerUserList => onComputerUserList(p)
case PacketType.ContainerUpdate => onContainerUpdate(p)
@ -152,6 +154,15 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onMachineItemStateResponse(p: PacketParser) : Unit = {
val stack = p.readItemStack()
val running = p.readBoolean()
val wrapper = Tablet.Client.get(stack, p.player)
wrapper.data.isRunning = running
wrapper.isDirty = false
}
def onComputerState(p: PacketParser): Unit =
p.readTileEntity[Computer]() match {
case Some(t) =>

View File

@ -9,10 +9,14 @@ import li.cil.oc.common.tileentity._
import li.cil.oc.common.tileentity.traits.Computer
import net.minecraft.client.Minecraft
import net.minecraft.client.audio.PositionedSoundRecord
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.init.SoundEvents
import net.minecraft.item.ItemStack
import net.minecraft.util.EnumFacing
import net.minecraft.util.SoundCategory
import scala.tools.nsc.doc.model.Entity
object PacketSender {
// Timestamp after which the next clipboard message may be sent. Used to
// avoid spamming large packets on key repeat.
@ -91,6 +95,14 @@ object PacketSender {
}
}
def sendMachineItemStateRequest(stack: ItemStack): Unit = {
val pb = new SimplePacketBuilder(PacketType.MachineItemStateRequest)
pb.writeItemStack(stack)
pb.sendToServer()
}
def sendMouseClick(address: String, x: Double, y: Double, drag: Boolean, button: Int) {
val pb = new SimplePacketBuilder(PacketType.MouseClickOrDrag)

View File

@ -79,6 +79,8 @@ object PacketType extends Enumeration {
KeyDown,
KeyUp,
Clipboard,
MachineItemStateRequest,
MachineItemStateResponse,
MouseClickOrDrag,
MouseScroll,
MouseUp,

View File

@ -21,6 +21,7 @@ import li.cil.oc.api.machine.MachineHost
import li.cil.oc.api.network.Connector
import li.cil.oc.api.network.Message
import li.cil.oc.api.network.Node
import li.cil.oc.{client, server}
import li.cil.oc.client.KeyBindings
import li.cil.oc.common.GuiType
import li.cil.oc.common.Slot
@ -28,7 +29,7 @@ import li.cil.oc.common.Tier
import li.cil.oc.common.inventory.ComponentInventory
import li.cil.oc.common.item.data.TabletData
import li.cil.oc.integration.opencomputers.DriverScreen
import li.cil.oc.server.component
import li.cil.oc.server.{PacketSender, component}
import li.cil.oc.util.Audio
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedNBT._
@ -40,7 +41,7 @@ import net.minecraft.client.renderer.block.model.ModelBakery
import net.minecraft.client.renderer.block.model.ModelResourceLocation
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
import net.minecraft.item.EnumRarity
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@ -91,8 +92,10 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit
override def durability(stack: ItemStack): Double = {
if (stack.hasTagCompound) {
val data = new TabletData()
data.load(stack.getTagCompound)
val data = Tablet.Client.getWeak(stack) match {
case Some(wrapper) => wrapper.data
case _ => new TabletData(stack)
}
1 - data.energy / data.maxEnergy
}
else 1.0
@ -111,10 +114,10 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit
@SideOnly(Side.CLIENT)
override def getModelLocation(stack: ItemStack): ModelResourceLocation = {
if (stack.hasTagCompound)
modelLocationFromState(Some(new TabletData(stack).isRunning))
else
modelLocationFromState(None)
modelLocationFromState(Tablet.Client.getWeak(stack) match {
case Some(tablet: TabletWrapper) => Some(tablet.data.isRunning)
case _ => None
})
}
@SideOnly(Side.CLIENT)
@ -242,12 +245,20 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp
val tablet: component.Tablet = if (world.isRemote) null else new component.Tablet(this)
var autoSave = true
//// Client side only
private var isInitialized = !world.isRemote
var timesChanged: Int = 0
var isDirty: Boolean = true
////
// Server side only
private var lastRunning = false
var autoSave = true
////
def isCreative: Boolean = data.tier == Tier.Four
def items: Array[ItemStack] = data.items
@ -414,6 +425,8 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp
buffer.setMaximumColorDepth(api.internal.TextBuffer.ColorDepth.FourBit)
buffer.setMaximumResolution(80, 25)
}
client.PacketSender.sendMachineItemStateRequest(stack)
}
if (!world.isRemote) {
if (isCreative && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
@ -429,6 +442,11 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp
lastRunning = machine.isRunning
markDirty()
player match {
case mp: EntityPlayerMP => server.PacketSender.sendMachineItemState(mp, stack, machine.isRunning)
case _ =>
}
if (machine.isRunning) {
components collect {
case Some(buffer: api.internal.TextBuffer) =>
@ -520,6 +538,23 @@ object Tablet {
cache.synchronized {
currentStack = stack
currentHolder = holder
// if the item is still cached, we can detect if it is dirty (client side only)
if (holder.world.isRemote) {
Client.getWeak(stack) match {
case Some(weak) =>
val timesChanged = holder.inventory.getTimesChanged
if (timesChanged != weak.timesChanged) {
if (!weak.isDirty) {
weak.isDirty = true
client.PacketSender.sendMachineItemStateRequest(stack)
}
weak.timesChanged = timesChanged
}
case _ =>
}
}
var wrapper = cache.get(id, this)
// Force re-load on world change, in case some components store a
@ -532,6 +567,9 @@ object Tablet {
wrapper = cache.get(id, this)
}
currentStack = null
currentHolder = null
wrapper.stack = stack
wrapper.player = holder
wrapper
@ -552,6 +590,7 @@ object Tablet {
node.remove()
}
if (tablet.autoSave) tablet.writeToNBT()
tablet.markDirty()
}
}
@ -576,6 +615,15 @@ object Tablet {
object Client extends Cache {
override protected def timeout = 5
def getWeak(stack: ItemStack): Option[TabletWrapper] = {
val key = getId(stack)
val map = cache.asMap
if (map.containsKey(key))
Some(map.entrySet.find(entry => entry.getKey == key).get.getValue)
else
None
}
def get(stack: ItemStack): Option[TabletWrapper] = {
if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "tablet")) {
val id = stack.getTagCompound.getString(Settings.namespace + "tablet")

View File

@ -4,11 +4,12 @@ import li.cil.oc.Localization
import li.cil.oc.api
import li.cil.oc.api.internal.Server
import li.cil.oc.api.machine.Machine
import li.cil.oc.api.network.Connector
import li.cil.oc.common.Achievement
import li.cil.oc.common.PacketType
import li.cil.oc.common.component.TextBuffer
import li.cil.oc.common.entity.Drone
import li.cil.oc.common.item.Delegator
import li.cil.oc.common.item.{Delegator, Tablet, TabletWrapper}
import li.cil.oc.common.item.data.DriveData
import li.cil.oc.common.item.traits.FileSystemLike
import li.cil.oc.common.tileentity._
@ -41,6 +42,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.KeyDown => onKeyDown(p)
case PacketType.KeyUp => onKeyUp(p)
case PacketType.Clipboard => onClipboard(p)
case PacketType.MachineItemStateRequest => onMachineItemStateRequest(p)
case PacketType.MouseClickOrDrag => onMouseClick(p)
case PacketType.MouseScroll => onMouseScroll(p)
case PacketType.MouseUp => onMouseUp(p)
@ -265,6 +267,14 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onMachineItemStateRequest(p: PacketParser): Unit = p.player match {
case player: EntityPlayerMP => {
val stack = p.readItemStack()
PacketSender.sendMachineItemState(player, stack, Tablet.get(stack, p.player).machine.isRunning)
}
case _ => // ignore
}
def onTextBufferInit(p: PacketParser) {
val address = p.readUTF()
p.player match {

View File

@ -90,6 +90,15 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t)
}
def sendMachineItemState(player: EntityPlayerMP, stack: ItemStack, isRunning: Boolean): Unit = {
val pb = new SimplePacketBuilder(PacketType.MachineItemStateResponse)
pb.writeItemStack(stack)
pb.writeBoolean(isRunning)
pb.sendToPlayer(player)
}
def sendComputerUserList(t: Computer, list: Array[String]) {
val pb = new SimplePacketBuilder(PacketType.ComputerUserList)