diff --git a/li/cil/oc/common/PacketBuilder.scala b/li/cil/oc/common/PacketBuilder.scala index cc1b9054c..243147f5c 100644 --- a/li/cil/oc/common/PacketBuilder.scala +++ b/li/cil/oc/common/PacketBuilder.scala @@ -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 + } } \ No newline at end of file diff --git a/li/cil/oc/server/PacketSender.scala b/li/cil/oc/server/PacketSender.scala index ebf8d6e2c..2624dbf11 100644 --- a/li/cil/oc/server/PacketSender.scala +++ b/li/cil/oc/server/PacketSender.scala @@ -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) } } \ No newline at end of file