Accumulating screen updates per tick and sending them as a batch packet, reducing overall net traffic quite a bit due to the reduced overhead (target info only has to be sent once).

Also compressing the multi-packet, since the data is usually written in the worker threads the additional CPU overhead is negligible.
Doing some basic testing, the potential danger of packets getting too big seems irrelevant.
Some simple testing shows bandwidth reduction down to ~50% when spamming random simple `set()`s, and even down to ~15% for well compressible updates (`while true do print(string.rep(os.date(), 4)) end` for example).
This commit is contained in:
Florian Nücke 2014-08-23 22:26:03 +02:00
parent 9f92698254
commit a36a0b525c
7 changed files with 147 additions and 122 deletions

View File

@ -1,8 +1,11 @@
package li.cil.oc.client
import java.io.EOFException
import cpw.mods.fml.common.network.Player
import li.cil.oc.Localization
import li.cil.oc.{OpenComputers, Localization}
import li.cil.oc.api.component
import li.cil.oc.api.network.ManagedEnvironment
import li.cil.oc.client.renderer.PetRenderer
import li.cil.oc.common.tileentity._
import li.cil.oc.common.tileentity.traits._
@ -53,6 +56,7 @@ class PacketHandler extends CommonPacketHandler {
case PacketType.TextBufferInit => onTextBufferInit(p)
case PacketType.TextBufferPaletteChange => onTextBufferPaletteChange(p)
case PacketType.TextBufferPowerChange => onTextBufferPowerChange(p)
case PacketType.TextBufferMulti => onTextBufferMulti(p)
case PacketType.TextBufferResolutionChange => onTextBufferResolutionChange(p)
case PacketType.TextBufferSet => onTextBufferSet(p)
case PacketType.ScreenTouchMode => onScreenTouchMode(p)
@ -280,8 +284,8 @@ class PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onTextBufferColorChange(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferColorChange(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val foreground = p.readInt()
val foregroundIsPalette = p.readBoolean()
@ -293,8 +297,8 @@ class PacketHandler extends CommonPacketHandler {
}
}
def onTextBufferCopy(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferCopy(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val col = p.readInt()
val row = p.readInt()
@ -307,16 +311,16 @@ class PacketHandler extends CommonPacketHandler {
}
}
def onTextBufferDepthChange(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferDepthChange(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
buffer.setColorDepth(component.TextBuffer.ColorDepth.values.apply(p.readInt()))
case _ => // Invalid packet.
}
}
def onTextBufferFill(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferFill(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val col = p.readInt()
val row = p.readInt()
@ -335,8 +339,8 @@ class PacketHandler extends CommonPacketHandler {
}
}
def onTextBufferPaletteChange(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferPaletteChange(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val index = p.readInt()
val color = p.readInt()
@ -352,8 +356,29 @@ class PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
def onTextBufferResolutionChange(p: PacketParser) {
def onTextBufferMulti(p: PacketParser) =
ComponentTracker.get(p.readUTF()) match {
case Some(buffer: component.TextBuffer) =>
try while (true) {
p.readPacketType() match {
case PacketType.TextBufferColorChange => onTextBufferColorChange(p, Some(buffer))
case PacketType.TextBufferCopy => onTextBufferCopy(p, Some(buffer))
case PacketType.TextBufferDepthChange => onTextBufferDepthChange(p, Some(buffer))
case PacketType.TextBufferFill => onTextBufferFill(p, Some(buffer))
case PacketType.TextBufferPaletteChange => onTextBufferPaletteChange(p, Some(buffer))
case PacketType.TextBufferResolutionChange => onTextBufferResolutionChange(p, Some(buffer))
case PacketType.TextBufferSet => onTextBufferSet(p, Some(buffer))
case _ => // Invalid packet.
}
}
catch {
case ignored: EOFException => // No more commands.
}
case _ => // Invalid packet.
}
def onTextBufferResolutionChange(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val w = p.readInt()
val h = p.readInt()
@ -362,8 +387,8 @@ class PacketHandler extends CommonPacketHandler {
}
}
def onTextBufferSet(p: PacketParser) {
ComponentTracker.get(p.readUTF()) match {
def onTextBufferSet(p: PacketParser, env: Option[ManagedEnvironment] = None) {
env.orElse(ComponentTracker.get(p.readUTF())) match {
case Some(buffer: component.TextBuffer) =>
val col = p.readInt()
val row = p.readInt()

View File

@ -3,7 +3,7 @@ package li.cil.oc.client
import li.cil.oc.Settings
import li.cil.oc.common.tileentity._
import li.cil.oc.common.tileentity.traits.Computer
import li.cil.oc.common.{CompressedPacketBuilder, PacketBuilder, PacketType}
import li.cil.oc.common.{CompressedPacketBuilder, SimplePacketBuilder, PacketType}
import net.minecraft.client.Minecraft
import net.minecraftforge.common.ForgeDirection
@ -13,7 +13,7 @@ object PacketSender {
protected var clipboardCooldown = 0L
def sendComputerPower(t: Computer, power: Boolean) {
val pb = new PacketBuilder(PacketType.ComputerPower)
val pb = new SimplePacketBuilder(PacketType.ComputerPower)
pb.writeTileEntity(t)
pb.writeBoolean(power)
@ -22,7 +22,7 @@ object PacketSender {
}
def sendKeyDown(address: String, char: Char, code: Int) {
val pb = new PacketBuilder(PacketType.KeyDown)
val pb = new SimplePacketBuilder(PacketType.KeyDown)
pb.writeUTF(address)
pb.writeChar(char)
@ -32,7 +32,7 @@ object PacketSender {
}
def sendKeyUp(address: String, char: Char, code: Int) {
val pb = new PacketBuilder(PacketType.KeyUp)
val pb = new SimplePacketBuilder(PacketType.KeyUp)
pb.writeUTF(address)
pb.writeChar(char)
@ -61,7 +61,7 @@ object PacketSender {
}
def sendMouseClick(address: String, x: Int, y: Int, drag: Boolean, button: Int) {
val pb = new PacketBuilder(PacketType.MouseClickOrDrag)
val pb = new SimplePacketBuilder(PacketType.MouseClickOrDrag)
pb.writeUTF(address)
pb.writeShort(x)
@ -73,7 +73,7 @@ object PacketSender {
}
def sendMouseScroll(address: String, x: Int, y: Int, scroll: Int) {
val pb = new PacketBuilder(PacketType.MouseScroll)
val pb = new SimplePacketBuilder(PacketType.MouseScroll)
pb.writeUTF(address)
pb.writeShort(x)
@ -84,7 +84,7 @@ object PacketSender {
}
def sendMouseUp(address: String, x: Int, y: Int, button: Int) {
val pb = new PacketBuilder(PacketType.MouseUp)
val pb = new SimplePacketBuilder(PacketType.MouseUp)
pb.writeUTF(address)
pb.writeShort(x)
@ -95,12 +95,12 @@ object PacketSender {
}
def sendMultiPlace() {
val pb = new PacketBuilder(PacketType.MultiPartPlace)
val pb = new SimplePacketBuilder(PacketType.MultiPartPlace)
pb.sendToServer()
}
def sendPetVisibility() {
val pb = new PacketBuilder(PacketType.PetVisibility)
val pb = new SimplePacketBuilder(PacketType.PetVisibility)
pb.writeBoolean(!Settings.get.hideOwnPet)
@ -108,7 +108,7 @@ object PacketSender {
}
def sendRobotAssemblerStart(t: RobotAssembler) {
val pb = new PacketBuilder(PacketType.RobotAssemblerStart)
val pb = new SimplePacketBuilder(PacketType.RobotAssemblerStart)
pb.writeTileEntity(t)
@ -116,7 +116,7 @@ object PacketSender {
}
def sendRobotStateRequest(dimension: Int, x: Int, y: Int, z: Int) {
val pb = new PacketBuilder(PacketType.RobotStateRequest)
val pb = new SimplePacketBuilder(PacketType.RobotStateRequest)
pb.writeInt(dimension)
pb.writeInt(x)
@ -127,7 +127,7 @@ object PacketSender {
}
def sendServerPower(t: ServerRack, number: Int, power: Boolean) {
val pb = new PacketBuilder(PacketType.ComputerPower)
val pb = new SimplePacketBuilder(PacketType.ComputerPower)
pb.writeTileEntity(t)
pb.writeInt(number)
@ -137,7 +137,7 @@ object PacketSender {
}
def sendServerRange(t: ServerRack, range: Int) {
val pb = new PacketBuilder(PacketType.ServerRange)
val pb = new SimplePacketBuilder(PacketType.ServerRange)
pb.writeTileEntity(t)
pb.writeInt(range)
@ -146,7 +146,7 @@ object PacketSender {
}
def sendServerSide(t: ServerRack, number: Int, side: ForgeDirection) {
val pb = new PacketBuilder(PacketType.ServerSide)
val pb = new SimplePacketBuilder(PacketType.ServerSide)
pb.writeTileEntity(t)
pb.writeInt(number)
@ -156,7 +156,7 @@ object PacketSender {
}
def sendServerSwitchMode(t: ServerRack, internal: Boolean) {
val pb = new PacketBuilder(PacketType.ServerSwitchMode)
val pb = new SimplePacketBuilder(PacketType.ServerSwitchMode)
pb.writeTileEntity(t)
pb.writeBoolean(internal)
@ -165,7 +165,7 @@ object PacketSender {
}
def sendTextBufferInit(address: String) {
val pb = new PacketBuilder(PacketType.TextBufferInit)
val pb = new SimplePacketBuilder(PacketType.TextBufferInit)
pb.writeUTF(address)

View File

@ -16,8 +16,7 @@ import net.minecraftforge.common.ForgeDirection
import scala.collection.convert.WrapAsScala._
// Necessary to keep track of the GZIP stream.
abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) extends DataOutputStream(stream) {
abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stream) {
def writeTileEntity(t: TileEntity) = {
writeInt(t.getWorldObj.provider.dimensionId)
writeInt(t.xCoord)
@ -37,6 +36,8 @@ abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) ext
def writeNBT(nbt: NBTTagCompound) = CompressedStreamTools.writeCompressed(nbt, this)
def writePacketType(pt: PacketType.Value) = writeByte(pt.id)
def sendToAllPlayers() = PacketDispatcher.sendPacketToAllPlayers(packet)
def sendToNearbyPlayers(t: TileEntity, range: Double = 1024): Unit = sendToNearbyPlayers(t.getWorldObj, t.xCoord + 0.5, t.yCoord + 0.5, t.zCoord + 0.5, range)
@ -63,7 +64,10 @@ abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) ext
protected def packet: Packet250CustomPayload
}
class PacketBuilder(packetType: PacketType.Value) extends PacketBuilderBase(PacketBuilder.newData(compressed = false)) {
// Necessary to keep track of the GZIP stream.
abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) extends PacketBuilder(stream)
class SimplePacketBuilder(packetType: PacketType.Value) extends PacketBuilderBase(PacketBuilder.newData(compressed = false)) {
writeByte(packetType.id)
override protected def packet = {

View File

@ -84,6 +84,8 @@ abstract class PacketHandler extends IPacketHandler {
}
def readNBT() = CompressedStreamTools.readCompressed(this)
def readPacketType() = PacketType(readByte())
}
}

View File

@ -32,6 +32,7 @@ object PacketType extends Enumeration {
TextBufferDepthChange,
TextBufferFill,
TextBufferInit, // Goes both ways.
TextBufferMulti,
TextBufferPaletteChange,
TextBufferPowerChange,
TextBufferResolutionChange,

View File

@ -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.{SaveHandler, tileentity}
import li.cil.oc.common._
import li.cil.oc.server.component.Keyboard
import li.cil.oc.server.{ComponentTracker => ServerComponentTracker, PacketSender => ServerPacketSender}
import li.cil.oc.util.{PackedColor, SideTracker}
@ -43,6 +43,15 @@ class TextBuffer(val owner: Container) extends ManagedComponent with api.compone
private var relativeLitArea = -1.0
private var _pendingCommands: Option[PacketBuilder] = None
private def pendingCommands = _pendingCommands.getOrElse {
val pb = new CompressedPacketBuilder(PacketType.TextBufferMulti)
pb.writeUTF(node.address)
_pendingCommands = Some(pb)
pb
}
var fullyLitCost = computeFullyLitCost()
// This computes the energy cost (per tick) to keep the screen running if
@ -96,6 +105,11 @@ class TextBuffer(val owner: Container) extends ManagedComponent with api.compone
}
}
}
this.synchronized {
_pendingCommands.foreach(_.sendToNearbyPlayers(owner))
_pendingCommands = None
}
}
// ----------------------------------------------------------------------- //
@ -550,41 +564,41 @@ object TextBuffer {
class ServerProxy(val owner: TextBuffer) extends Proxy {
override def onScreenColorChange() {
owner.owner.markChanged()
ServerPacketSender.sendTextBufferColorChange(owner.node.address, owner.data.foreground, owner.data.background, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferColorChange(owner.pendingCommands, owner.data.foreground, owner.data.background))
}
override def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
super.onScreenCopy(col, row, w, h, tx, ty)
owner.owner.markChanged()
ServerPacketSender.sendTextBufferCopy(owner.node.address, col, row, w, h, tx, ty, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferCopy(owner.pendingCommands, col, row, w, h, tx, ty))
}
override def onScreenDepthChange(depth: ColorDepth) {
owner.owner.markChanged()
ServerPacketSender.sendTextBufferDepthChange(owner.node.address, depth, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferDepthChange(owner.pendingCommands, depth))
}
override def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
super.onScreenFill(col, row, w, h, c)
owner.owner.markChanged()
ServerPacketSender.sendTextBufferFill(owner.node.address, col, row, w, h, c, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferFill(owner.pendingCommands, col, row, w, h, c))
}
override def onScreenPaletteChange(index: Int) {
owner.owner.markChanged()
ServerPacketSender.sendTextBufferPaletteChange(owner.node.address, index, owner.getPaletteColor(index), owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferPaletteChange(owner.pendingCommands, index, owner.getPaletteColor(index)))
}
override def onScreenResolutionChange(w: Int, h: Int) {
super.onScreenResolutionChange(w, h)
owner.owner.markChanged()
ServerPacketSender.sendTextBufferResolutionChange(owner.node.address, w, h, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferResolutionChange(owner.pendingCommands, w, h))
}
override def onScreenSet(col: Int, row: Int, s: String, vertical: Boolean) {
super.onScreenSet(col, row, s, vertical)
owner.owner.markChanged()
ServerPacketSender.sendTextBufferSet(owner.node.address, col, row, s, vertical, owner.owner)
owner.synchronized(ServerPacketSender.appendTextBufferSet(owner.pendingCommands, col, row, s, vertical))
}
override def keyDown(character: Char, code: Int, player: EntityPlayer) {

View File

@ -2,8 +2,8 @@ package li.cil.oc.server
import li.cil.oc.api.component.TextBuffer.ColorDepth
import li.cil.oc.api.driver.Container
import li.cil.oc.common._
import li.cil.oc.common.tileentity.traits._
import li.cil.oc.common.{CompressedPacketBuilder, PacketBuilder, PacketType, tileentity}
import li.cil.oc.util.PackedColor
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.ItemStack
@ -13,7 +13,7 @@ import net.minecraftforge.common.ForgeDirection
object PacketSender {
def sendAbstractBusState(t: AbstractBusAware) {
val pb = new PacketBuilder(PacketType.AbstractBusState)
val pb = new SimplePacketBuilder(PacketType.AbstractBusState)
pb.writeTileEntity(t)
pb.writeBoolean(t.isAbstractBusAvailable)
@ -22,7 +22,7 @@ object PacketSender {
}
def sendAnalyze(address: String, player: EntityPlayerMP) {
val pb = new PacketBuilder(PacketType.Analyze)
val pb = new SimplePacketBuilder(PacketType.Analyze)
pb.writeUTF(address)
@ -30,7 +30,7 @@ object PacketSender {
}
def sendChargerState(t: tileentity.Charger) {
val pb = new PacketBuilder(PacketType.ChargerState)
val pb = new SimplePacketBuilder(PacketType.ChargerState)
pb.writeTileEntity(t)
pb.writeDouble(t.chargeSpeed)
@ -40,7 +40,7 @@ object PacketSender {
}
def sendColorChange(t: Colored) {
val pb = new PacketBuilder(PacketType.ColorChange)
val pb = new SimplePacketBuilder(PacketType.ColorChange)
pb.writeTileEntity(t)
pb.writeInt(t.color)
@ -49,7 +49,7 @@ object PacketSender {
}
def sendComputerState(t: Computer) {
val pb = new PacketBuilder(PacketType.ComputerState)
val pb = new SimplePacketBuilder(PacketType.ComputerState)
pb.writeTileEntity(t)
pb.writeBoolean(t.isRunning)
@ -58,7 +58,7 @@ object PacketSender {
}
def sendComputerUserList(t: Computer, list: Array[String]) {
val pb = new PacketBuilder(PacketType.ComputerUserList)
val pb = new SimplePacketBuilder(PacketType.ComputerUserList)
pb.writeTileEntity(t)
pb.writeInt(list.length)
@ -68,7 +68,7 @@ object PacketSender {
}
def sendDisassemblerActive(t: tileentity.Disassembler, active: Boolean) {
val pb = new PacketBuilder(PacketType.DisassemblerActiveChange)
val pb = new SimplePacketBuilder(PacketType.DisassemblerActiveChange)
pb.writeTileEntity(t)
pb.writeBoolean(active)
@ -77,7 +77,7 @@ object PacketSender {
}
def sendFloppyChange(t: tileentity.DiskDrive, stack: ItemStack = null) {
val pb = new PacketBuilder(PacketType.FloppyChange)
val pb = new SimplePacketBuilder(PacketType.FloppyChange)
pb.writeTileEntity(t)
pb.writeItemStack(stack)
@ -86,7 +86,7 @@ object PacketSender {
}
def sendHologramClear(t: tileentity.Hologram) {
val pb = new PacketBuilder(PacketType.HologramClear)
val pb = new SimplePacketBuilder(PacketType.HologramClear)
pb.writeTileEntity(t)
@ -94,7 +94,7 @@ object PacketSender {
}
def sendHologramColor(t: tileentity.Hologram, index: Int, value: Int) {
val pb = new PacketBuilder(PacketType.HologramColor)
val pb = new SimplePacketBuilder(PacketType.HologramColor)
pb.writeTileEntity(t)
pb.writeInt(index)
@ -104,7 +104,7 @@ object PacketSender {
}
def sendHologramPowerChange(t: tileentity.Hologram) {
val pb = new PacketBuilder(PacketType.HologramPowerChange)
val pb = new SimplePacketBuilder(PacketType.HologramPowerChange)
pb.writeTileEntity(t)
pb.writeBoolean(t.hasPower)
@ -113,7 +113,7 @@ object PacketSender {
}
def sendHologramScale(t: tileentity.Hologram) {
val pb = new PacketBuilder(PacketType.HologramScale)
val pb = new SimplePacketBuilder(PacketType.HologramScale)
pb.writeTileEntity(t)
pb.writeDouble(t.scale)
@ -140,7 +140,7 @@ object PacketSender {
}
def sendPetVisibility(name: Option[String] = None, player: Option[EntityPlayerMP] = None) {
val pb = new PacketBuilder(PacketType.PetVisibility)
val pb = new SimplePacketBuilder(PacketType.PetVisibility)
name match {
case Some(n) =>
@ -162,7 +162,7 @@ object PacketSender {
}
def sendPowerState(t: PowerInformation) {
val pb = new PacketBuilder(PacketType.PowerState)
val pb = new SimplePacketBuilder(PacketType.PowerState)
pb.writeTileEntity(t)
pb.writeDouble(t.globalBuffer)
@ -172,7 +172,7 @@ object PacketSender {
}
def sendRedstoneState(t: RedstoneAware) {
val pb = new PacketBuilder(PacketType.RedstoneState)
val pb = new SimplePacketBuilder(PacketType.RedstoneState)
pb.writeTileEntity(t)
pb.writeBoolean(t.isOutputEnabled)
@ -184,7 +184,7 @@ object PacketSender {
}
def sendRobotAssembling(t: tileentity.RobotAssembler, assembling: Boolean) {
val pb = new PacketBuilder(PacketType.RobotAssemblingState)
val pb = new SimplePacketBuilder(PacketType.RobotAssemblingState)
pb.writeTileEntity(t)
pb.writeBoolean(assembling)
@ -193,7 +193,7 @@ object PacketSender {
}
def sendRobotMove(t: tileentity.Robot, ox: Int, oy: Int, oz: Int, direction: ForgeDirection) {
val pb = new PacketBuilder(PacketType.RobotMove)
val pb = new SimplePacketBuilder(PacketType.RobotMove)
// Custom pb.writeTileEntity() with fake coordinates (valid for the client).
pb.writeInt(t.proxy.world.provider.dimensionId)
@ -206,7 +206,7 @@ object PacketSender {
}
def sendRobotAnimateSwing(t: tileentity.Robot) {
val pb = new PacketBuilder(PacketType.RobotAnimateSwing)
val pb = new SimplePacketBuilder(PacketType.RobotAnimateSwing)
pb.writeTileEntity(t.proxy)
pb.writeInt(t.animationTicksTotal)
@ -215,7 +215,7 @@ object PacketSender {
}
def sendRobotAnimateTurn(t: tileentity.Robot) {
val pb = new PacketBuilder(PacketType.RobotAnimateTurn)
val pb = new SimplePacketBuilder(PacketType.RobotAnimateTurn)
pb.writeTileEntity(t.proxy)
pb.writeByte(t.turnAxis)
@ -225,7 +225,7 @@ object PacketSender {
}
def sendRobotInventory(t: tileentity.Robot, slot: Int, stack: ItemStack) {
val pb = new PacketBuilder(PacketType.RobotInventoryChange)
val pb = new SimplePacketBuilder(PacketType.RobotInventoryChange)
pb.writeTileEntity(t.proxy)
pb.writeInt(slot)
@ -235,7 +235,7 @@ object PacketSender {
}
def sendRobotSelectedSlotChange(t: tileentity.Robot) {
val pb = new PacketBuilder(PacketType.RobotSelectedSlotChange)
val pb = new SimplePacketBuilder(PacketType.RobotSelectedSlotChange)
pb.writeTileEntity(t.proxy)
pb.writeInt(t.selectedSlot)
@ -244,7 +244,7 @@ object PacketSender {
}
def sendRotatableState(t: Rotatable) {
val pb = new PacketBuilder(PacketType.RotatableState)
val pb = new SimplePacketBuilder(PacketType.RotatableState)
pb.writeTileEntity(t)
pb.writeDirection(t.pitch)
@ -254,59 +254,70 @@ object PacketSender {
}
def sendSwitchActivity(t: tileentity.Switch) {
val pb = new PacketBuilder(PacketType.SwitchActivity)
val pb = new SimplePacketBuilder(PacketType.SwitchActivity)
pb.writeTileEntity(t)
pb.sendToNearbyPlayers(t, 64)
}
def sendTextBufferColorChange(address: String, foreground: PackedColor.Color, background: PackedColor.Color, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferColorChange)
def appendTextBufferColorChange(pb: PacketBuilder, foreground: PackedColor.Color, background: PackedColor.Color) {
pb.writePacketType(PacketType.TextBufferColorChange)
pb.writeUTF(address)
pb.writeInt(foreground.value)
pb.writeBoolean(foreground.isPalette)
pb.writeInt(background.value)
pb.writeBoolean(background.isPalette)
pb.sendToNearbyPlayers(container)
}
def sendTextBufferCopy(address: String, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferCopy)
def appendTextBufferCopy(pb: PacketBuilder, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
pb.writePacketType(PacketType.TextBufferCopy)
pb.writeUTF(address)
pb.writeInt(col)
pb.writeInt(row)
pb.writeInt(w)
pb.writeInt(h)
pb.writeInt(tx)
pb.writeInt(ty)
pb.sendToNearbyPlayers(container)
}
def sendTextBufferDepthChange(address: String, value: ColorDepth, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferDepthChange)
def appendTextBufferDepthChange(pb: PacketBuilder, value: ColorDepth) {
pb.writePacketType(PacketType.TextBufferDepthChange)
pb.writeUTF(address)
pb.writeInt(value.ordinal)
pb.sendToNearbyPlayers(container)
}
def sendTextBufferFill(address: String, col: Int, row: Int, w: Int, h: Int, c: Char, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferFill)
def appendTextBufferFill(pb: PacketBuilder, col: Int, row: Int, w: Int, h: Int, c: Char) {
pb.writePacketType(PacketType.TextBufferFill)
pb.writeUTF(address)
pb.writeInt(col)
pb.writeInt(row)
pb.writeInt(w)
pb.writeInt(h)
pb.writeChar(c)
}
pb.sendToNearbyPlayers(container)
def appendTextBufferPaletteChange(pb: PacketBuilder, index: Int, color: Int) {
pb.writePacketType(PacketType.TextBufferPaletteChange)
pb.writeInt(index)
pb.writeInt(color)
}
def appendTextBufferResolutionChange(pb: PacketBuilder, w: Int, h: Int) {
pb.writePacketType(PacketType.TextBufferResolutionChange)
pb.writeInt(w)
pb.writeInt(h)
}
def appendTextBufferSet(pb: PacketBuilder, col: Int, row: Int, s: String, vertical: Boolean) {
pb.writePacketType(PacketType.TextBufferSet)
pb.writeInt(col)
pb.writeInt(row)
pb.writeUTF(s)
pb.writeBoolean(vertical)
}
def sendTextBufferInit(address: String, value: NBTTagCompound, player: EntityPlayerMP) {
@ -318,18 +329,8 @@ object PacketSender {
pb.sendToPlayer(player)
}
def sendTextBufferPaletteChange(address: String, index: Int, color: Int, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferPaletteChange)
pb.writeUTF(address)
pb.writeInt(index)
pb.writeInt(color)
pb.sendToNearbyPlayers(container)
}
def sendTextBufferPowerChange(address: String, hasPower: Boolean, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferPowerChange)
val pb = new SimplePacketBuilder(PacketType.TextBufferPowerChange)
pb.writeUTF(address)
pb.writeBoolean(hasPower)
@ -337,30 +338,8 @@ object PacketSender {
pb.sendToNearbyPlayers(container)
}
def sendTextBufferResolutionChange(address: String, w: Int, h: Int, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferResolutionChange)
pb.writeUTF(address)
pb.writeInt(w)
pb.writeInt(h)
pb.sendToNearbyPlayers(container)
}
def sendTextBufferSet(address: String, col: Int, row: Int, s: String, vertical: Boolean, container: Container) {
val pb = new PacketBuilder(PacketType.TextBufferSet)
pb.writeUTF(address)
pb.writeInt(col)
pb.writeInt(row)
pb.writeUTF(s)
pb.writeBoolean(vertical)
pb.sendToNearbyPlayers(container)
}
def sendScreenTouchMode(t: tileentity.Screen, value: Boolean) {
val pb = new PacketBuilder(PacketType.ScreenTouchMode)
val pb = new SimplePacketBuilder(PacketType.ScreenTouchMode)
pb.writeTileEntity(t)
pb.writeBoolean(value)
@ -369,7 +348,7 @@ object PacketSender {
}
def sendServerPresence(t: tileentity.ServerRack) {
val pb = new PacketBuilder(PacketType.ServerPresence)
val pb = new SimplePacketBuilder(PacketType.ServerPresence)
pb.writeTileEntity(t)
t.servers.foreach {
@ -384,7 +363,7 @@ object PacketSender {
}
def sendServerState(t: tileentity.ServerRack) {
val pb = new PacketBuilder(PacketType.ComputerState)
val pb = new SimplePacketBuilder(PacketType.ComputerState)
pb.writeTileEntity(t)
pb.writeInt(-1)
@ -394,7 +373,7 @@ object PacketSender {
}
def sendServerState(t: tileentity.ServerRack, number: Int, player: Option[EntityPlayerMP] = None) {
val pb = new PacketBuilder(PacketType.ComputerState)
val pb = new SimplePacketBuilder(PacketType.ComputerState)
pb.writeTileEntity(t)
pb.writeInt(number)
@ -413,7 +392,7 @@ object PacketSender {
}
def sendSound(world: World, x: Int, y: Int, z: Int, frequency: Int, duration: Int) {
val pb = new PacketBuilder(PacketType.Sound)
val pb = new SimplePacketBuilder(PacketType.Sound)
pb.writeInt(world.provider.dimensionId)
pb.writeInt(x)