From fd00e0dce63a5a9b9f1c0faab68f4cb366a4e193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 29 Dec 2015 17:15:57 +0100 Subject: [PATCH] Added `oc_profileNetwork` or `oc_pn` command to enable logging packets being sent by the server. --- .../li/cil/oc/common/PacketBuilder.scala | 43 +++++++++++++++---- .../oc/server/command/CommandHandler.scala | 1 + .../command/NetworkProfilingCommand.scala | 28 ++++++++++++ .../cil/oc/server/component/NetworkCard.scala | 4 +- 4 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 src/main/scala/li/cil/oc/server/command/NetworkProfilingCommand.scala diff --git a/src/main/scala/li/cil/oc/common/PacketBuilder.scala b/src/main/scala/li/cil/oc/common/PacketBuilder.scala index fdf758298..b4a803d1e 100644 --- a/src/main/scala/li/cil/oc/common/PacketBuilder.scala +++ b/src/main/scala/li/cil/oc/common/PacketBuilder.scala @@ -18,6 +18,7 @@ import net.minecraft.nbt.NBTTagCompound import net.minecraft.tileentity.TileEntity import net.minecraft.world.World import net.minecraftforge.common.util.ForgeDirection +import org.apache.logging.log4j.LogManager import scala.collection.convert.WrapAsScala._ @@ -80,26 +81,52 @@ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stre } // Necessary to keep track of the GZIP stream. -abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) extends PacketBuilder(stream) +abstract class PacketBuilderBase[T <: OutputStream](protected val stream: T) extends PacketBuilder(stream) { + var tileEntity: Option[TileEntity] = None -class SimplePacketBuilder(packetType: PacketType.Value) extends PacketBuilderBase(PacketBuilder.newData(compressed = false)) { - writeByte(packetType.id) - - override protected def packet = { - new FMLProxyPacket(Unpooled.wrappedBuffer(stream.toByteArray), "OpenComputers") + override def writeTileEntity(t: TileEntity): Unit = { + super.writeTileEntity(t) + if (PacketBuilder.isProfilingEnabled) { + tileEntity = Option(t) + } } } -class CompressedPacketBuilder(packetType: PacketType.Value, private val data: ByteArrayOutputStream = PacketBuilder.newData(compressed = true)) extends PacketBuilderBase(new GZIPOutputStream(data)) { +class SimplePacketBuilder(val packetType: PacketType.Value) extends PacketBuilderBase(PacketBuilder.newData(compressed = false)) { + writeByte(packetType.id) + + override protected def packet = { + val payload = stream.toByteArray + PacketBuilder.logPacket(packetType, payload.length, tileEntity) + new FMLProxyPacket(Unpooled.wrappedBuffer(payload), "OpenComputers") + } +} + +class CompressedPacketBuilder(val packetType: PacketType.Value, private val data: ByteArrayOutputStream = PacketBuilder.newData(compressed = true)) extends PacketBuilderBase(new GZIPOutputStream(data)) { writeByte(packetType.id) override protected def packet = { stream.finish() - new FMLProxyPacket(Unpooled.wrappedBuffer(data.toByteArray), "OpenComputers") + val payload = data.toByteArray + PacketBuilder.logPacket(packetType, payload.length, tileEntity) + new FMLProxyPacket(Unpooled.wrappedBuffer(payload), "OpenComputers") } } object PacketBuilder { + val log = LogManager.getLogger(OpenComputers.Name + "-PacketBuilder") + var isProfilingEnabled = false + + def logPacket(packetType: PacketType.Value, payloadSize: Int, tileEntity: Option[TileEntity]): Unit = { + if (PacketBuilder.isProfilingEnabled) { + tileEntity match { + case Some(t) => PacketBuilder.log.info(s"Sending: $packetType @ $payloadSize bytes from (${t.xCoord}, ${t.yCoord}, ${t.zCoord}).") + case _ => PacketBuilder.log.info(s"Sending: $packetType @ $payloadSize bytes.") + + } + } + } + def newData(compressed: Boolean) = { val data = new ByteArrayOutputStream data.write(if (compressed) 1 else 0) diff --git a/src/main/scala/li/cil/oc/server/command/CommandHandler.scala b/src/main/scala/li/cil/oc/server/command/CommandHandler.scala index b3b1ee27e..0207cc5a1 100644 --- a/src/main/scala/li/cil/oc/server/command/CommandHandler.scala +++ b/src/main/scala/li/cil/oc/server/command/CommandHandler.scala @@ -6,6 +6,7 @@ object CommandHandler { def register(e: FMLServerStartingEvent) { e.registerServerCommand(DebugNanomachinesCommand) e.registerServerCommand(LogNanomachinesCommand) + e.registerServerCommand(NetworkProfilingCommand) e.registerServerCommand(NonDisassemblyAgreementCommand) e.registerServerCommand(WirelessRenderingCommand) e.registerServerCommand(SpawnComputerCommand) diff --git a/src/main/scala/li/cil/oc/server/command/NetworkProfilingCommand.scala b/src/main/scala/li/cil/oc/server/command/NetworkProfilingCommand.scala new file mode 100644 index 000000000..10828a035 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/command/NetworkProfilingCommand.scala @@ -0,0 +1,28 @@ +package li.cil.oc.server.command + +import li.cil.oc.common.PacketBuilder +import li.cil.oc.common.command.SimpleCommand +import net.minecraft.command.CommandBase +import net.minecraft.command.ICommandSender + +object NetworkProfilingCommand extends SimpleCommand("oc_profileNetwork") { + aliases += "oc_pn" + + override def getCommandUsage(source: ICommandSender) = name + " " + + override def processCommand(source: ICommandSender, command: Array[String]) { + PacketBuilder.isProfilingEnabled = + if (command != null && command.length > 0) + CommandBase.parseBoolean(source, command(0)) + else + !PacketBuilder.isProfilingEnabled + } + + // OP levels for reference: + // 1 - Ops can bypass spawn protection. + // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. + // 3 - Ops can use /ban, /deop, /kick, and /op. + // 4 - Ops can use /stop. + + override def getRequiredPermissionLevel = 3 +} diff --git a/src/main/scala/li/cil/oc/server/component/NetworkCard.scala b/src/main/scala/li/cil/oc/server/component/NetworkCard.scala index 591effe42..e0e7a0421 100644 --- a/src/main/scala/li/cil/oc/server/component/NetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/NetworkCard.scala @@ -110,11 +110,13 @@ class NetworkCard(val host: EnvironmentHost) extends prefab.ManagedEnvironment w protected def doSend(packet: Packet) = visibility match { case Visibility.Neighbors => node.sendToNeighbors("network.message", packet) case Visibility.Network => node.sendToReachable("network.message", packet) + case _ => // Ignore. } protected def doBroadcast(packet: Packet) = visibility match { case Visibility.Neighbors => node.sendToNeighbors("network.message", packet) case Visibility.Network => node.sendToReachable("network.message", packet) + case _ => // Ignore. } // ----------------------------------------------------------------------- // @@ -191,7 +193,7 @@ class NetworkCard(val host: EnvironmentHost) extends prefab.ManagedEnvironment w private def networkActivity() { host match { - case (h) => ServerPacketSender.sendNetworkActivity(node, h) + case h: EnvironmentHost => ServerPacketSender.sendNetworkActivity(node, h) case _ => } }