sending updates from server to client only when the client is nearby (i.e. we can assume the chunks are loaded on the client). this is somewhat experimental, since we cannot say with 100% certainty that the chunk isn't loaded on the client. will probably send "important" packets to all clients all the time (e.g. robot move) in the long run, but for now let's see how it turns out.

This commit is contained in:
Florian Nücke 2013-11-29 14:16:58 +01:00
parent ac0859a109
commit 3ac0d4a895
2 changed files with 58 additions and 18 deletions

View File

@ -1,14 +1,18 @@
package li.cil.oc.common
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.network.PacketDispatcher
import cpw.mods.fml.common.network.Player
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import li.cil.oc.common.tileentity.TileEntity
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.ItemStack
import net.minecraft.nbt.{NBTTagCompound, NBTBase}
import net.minecraft.network.packet.Packet250CustomPayload
import net.minecraft.world.World
import net.minecraftforge.common.ForgeDirection
import scala.collection.convert.WrapAsScala._
/** Utility class for packet creation. */
class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayOutputStream = new ByteArrayOutputStream) extends DataOutputStream(stream) {
@ -35,7 +39,19 @@ class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayO
def sendToAllPlayers() = PacketDispatcher.sendPacketToAllPlayers(packet)
def sendToNearbyPlayers(t: TileEntity, range: Double = 64) = PacketDispatcher.sendPacketToAllAround(t.x, t.y, t.z, range, t.world.provider.dimensionId, packet)
def sendToNearbyPlayers(t: TileEntity, range: Double = 64): Unit = sendToNearbyPlayers(t.world, t.x + 0.5, t.y + 0.5, t.z + 0.5, range)
def sendToNearbyPlayers(world: World, x: Double, y: Double, z: Double, range: Double) {
val dimension = world.provider.dimensionId
val server = FMLCommonHandler.instance.getMinecraftServerInstance
val manager = server.getConfigurationManager
for (player <- manager.playerEntityList.map(_.asInstanceOf[EntityPlayerMP]) if player.dimension == dimension) {
val playerSpecificRange = range min ((manager.getViewDistance min PacketBuilder.tryGetPlayerRenderDistance(player)) * 16)
if (player.getDistanceSq(x, y, z) < playerSpecificRange * playerSpecificRange) {
player.playerNetServerHandler.sendPacketToPlayer(packet)
}
}
}
def sendToPlayer(player: Player) = PacketDispatcher.sendPacketToPlayer(packet, player)
@ -48,4 +64,28 @@ class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayO
p.length = stream.size
p
}
}
object PacketBuilder {
private val renderDistanceField = try {
val field = classOf[EntityPlayerMP].getDeclaredField("renderDistance")
field.setAccessible(true)
Some(field)
}
catch {
case _: Throwable => None
}
private def tryGetPlayerRenderDistance(player: EntityPlayerMP): Int = {
try {
renderDistanceField match {
case Some(field) => return field.get(player).asInstanceOf[Integer]
case _ =>
}
}
catch {
case _: Throwable =>
}
Int.MaxValue
}
}

View File

@ -30,7 +30,7 @@ object PacketSender {
player match {
case Some(p) => pb.sendToPlayer(p)
case _ => pb.sendToAllPlayers()
case _ => pb.sendToNearbyPlayers(t)
}
}
@ -42,7 +42,7 @@ object PacketSender {
player match {
case Some(p) => pb.sendToPlayer(p)
case _ => pb.sendToAllPlayers()
case _ => pb.sendToNearbyPlayers(t)
}
}
@ -67,7 +67,7 @@ object PacketSender {
player match {
case Some(p) => pb.sendToPlayer(p)
case _ => pb.sendToAllPlayers()
case _ => pb.sendToNearbyPlayers(t)
}
}
@ -82,7 +82,7 @@ object PacketSender {
player match {
case Some(p) => pb.sendToPlayer(p)
case _ => pb.sendToAllPlayers()
case _ => pb.sendToNearbyPlayers(t)
}
}
@ -96,7 +96,7 @@ object PacketSender {
pb.writeInt(oz)
pb.writeDirection(direction)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendRobotAnimateSwing(t: Robot) {
@ -105,7 +105,7 @@ object PacketSender {
pb.writeTileEntity(t.proxy)
pb.writeInt(t.animationTicksTotal)
pb.sendToNearbyPlayers(t.proxy)
pb.sendToNearbyPlayers(t)
}
def sendRobotAnimateTurn(t: Robot) {
@ -115,7 +115,7 @@ object PacketSender {
pb.writeByte(t.turnAxis)
pb.writeInt(t.animationTicksTotal)
pb.sendToNearbyPlayers(t.proxy)
pb.sendToNearbyPlayers(t)
}
def sendRobotEquippedItemChange(t: Robot, stack: ItemStack) {
@ -124,7 +124,7 @@ object PacketSender {
pb.writeTileEntity(t.proxy)
pb.writeItemStack(stack)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendRobotSelectedSlotChange(t: Robot) {
@ -133,7 +133,7 @@ object PacketSender {
pb.writeTileEntity(t.proxy)
pb.writeInt(t.selectedSlot)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendRotatableState(t: Rotatable, player: Option[Player] = None) {
@ -145,7 +145,7 @@ object PacketSender {
player match {
case Some(p) => pb.sendToPlayer(p)
case _ => pb.sendToAllPlayers()
case _ => pb.sendToNearbyPlayers(t)
}
}
@ -156,7 +156,7 @@ object PacketSender {
pb.writeInt(foreground)
pb.writeInt(background)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenCopy(t: Buffer, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
@ -170,7 +170,7 @@ object PacketSender {
pb.writeInt(tx)
pb.writeInt(ty)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenDepthChange(t: Buffer, value: PackedColor.Depth.Value) {
@ -179,7 +179,7 @@ object PacketSender {
pb.writeTileEntity(t)
pb.writeInt(value.id)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenFill(t: Buffer, col: Int, row: Int, w: Int, h: Int, c: Char) {
@ -192,7 +192,7 @@ object PacketSender {
pb.writeInt(h)
pb.writeChar(c)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenPowerChange(t: Buffer, hasPower: Boolean) {
@ -201,7 +201,7 @@ object PacketSender {
pb.writeTileEntity(t)
pb.writeBoolean(hasPower)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenResolutionChange(t: Buffer, w: Int, h: Int) {
@ -211,7 +211,7 @@ object PacketSender {
pb.writeInt(w)
pb.writeInt(h)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
def sendScreenSet(t: Buffer, col: Int, row: Int, s: String) {
@ -222,6 +222,6 @@ object PacketSender {
pb.writeInt(row)
pb.writeUTF(s)
pb.sendToAllPlayers()
pb.sendToNearbyPlayers(t)
}
}