diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java b/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java index 455513ae..4b64d140 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/PacketType.java @@ -16,6 +16,7 @@ import com.comphenix.protocol.utility.MinecraftVersion; import com.google.common.base.Objects; import com.google.common.base.Preconditions; +import com.google.common.collect.ComparisonChain; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; @@ -27,7 +28,7 @@ import com.google.common.util.concurrent.Futures; * rely on IDs alone. * @author Kristian */ -public class PacketType implements Serializable { +public class PacketType implements Serializable, Comparable { // Increment whenever the type changes private static final long serialVersionUID = 1L; @@ -902,6 +903,16 @@ public class PacketType implements Serializable { return false; } + @Override + public int compareTo(PacketType other) { + return ComparisonChain.start(). + compare(protocol, other.getProtocol()). + compare(sender, other.getSender()). + compare(currentId, other.getCurrentId()). + compare(legacyId, other.getLegacyId()). + result(); + } + @Override public String toString() { Class clazz = getPacketClass();; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java index e92a8d51..840cffc1 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java @@ -594,7 +594,7 @@ public class AsyncListenerHandler { listener.onPacketReceiving(packet); // And we're done - tracker.endTracking(token, packet.getPacketID()); + tracker.endTracking(token, packet.getPacketType()); } else { if (packet.isServerPacket()) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java index a9fc1741..5c1bd1e6 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java @@ -60,7 +60,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu // Measure and record the execution time invokeReceivingListener(reporter, event, element); - tracker.endTracking(token, event.getPacketID()); + tracker.endTracking(token, event.getPacketType()); } } else { for (PrioritizedListener element : list) { @@ -90,7 +90,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu // Measure and record the execution time invokeReceivingListener(reporter, event, element); - tracker.endTracking(token, event.getPacketID()); + tracker.endTracking(token, event.getPacketType()); } } } else { @@ -142,7 +142,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu // Measure and record the execution time invokeSendingListener(reporter, event, element); - tracker.endTracking(token, event.getPacketID()); + tracker.endTracking(token, event.getPacketType()); } } else { for (PrioritizedListener element : list) { @@ -171,7 +171,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu // Measure and record the execution time invokeSendingListener(reporter, event, element); - tracker.endTracking(token, event.getPacketID()); + tracker.endTracking(token, event.getPacketType()); } } } else { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimedTracker.java b/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimedTracker.java index ff6349af..20121caf 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimedTracker.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimedTracker.java @@ -1,6 +1,10 @@ package com.comphenix.protocol.timing; -import com.comphenix.protocol.Packets; +import java.util.Map; +import java.util.Map.Entry; + +import com.comphenix.protocol.PacketType; +import com.google.common.collect.Maps; /** * Tracks the invocation time for a particular plugin against a list of packets. @@ -8,7 +12,7 @@ import com.comphenix.protocol.Packets; */ public class TimedTracker { // Table of packets and invocations - private StatisticsStream[] packets; + private Map packets = Maps.newHashMap(); private int observations; /** @@ -24,15 +28,15 @@ public class TimedTracker { * @param trackingToken - the tracking token. * @param packetId - the packet ID. */ - public synchronized void endTracking(long trackingToken, int packetId) { - // Lazy initialization - if (packets == null) - packets = new StatisticsStream[Packets.PACKET_COUNT]; - if (packets[packetId] == null) - packets[packetId] = new StatisticsStream(); + public synchronized void endTracking(long trackingToken, PacketType type) { + StatisticsStream stream = packets.get(type); + // Lazily create a stream + if (stream == null) { + packets.put(type, stream = new StatisticsStream()); + } // Store this observation - packets[packetId].observe(System.nanoTime() - trackingToken); + stream.observe(System.nanoTime() - trackingToken); observations++; } @@ -45,18 +49,17 @@ public class TimedTracker { } /** - * Retrieve an array (indexed by packet ID) of all relevant statistics. - * @return The array of statistics. + * Retrieve an map (indexed by packet type) of all relevant statistics. + * @return The map of statistics. */ - public synchronized StatisticsStream[] getStatistics() { - StatisticsStream[] clone = new StatisticsStream[Packets.PACKET_COUNT]; + public synchronized Map getStatistics() { + Map clone = Maps.newHashMap(); - if (packets != null) { - for (int i = 0; i < clone.length; i++) { - if (packets[i] != null) { - clone[i] = new StatisticsStream(packets[i]); - } - } + for (Entry entry : packets.entrySet()) { + clone.put( + entry.getKey(), + new StatisticsStream(entry.getValue()) + ); } return clone; } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimingReportGenerator.java b/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimingReportGenerator.java index b0a3b622..5a0f6821 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimingReportGenerator.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/timing/TimingReportGenerator.java @@ -5,10 +5,12 @@ import java.io.File; import java.io.IOException; import java.io.Writer; import java.util.Date; - -import com.comphenix.protocol.Packets; +import java.util.Map; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.timing.TimedListenerManager.ListenerType; import com.google.common.base.Charsets; +import com.google.common.base.Strings; +import com.google.common.collect.Sets; import com.google.common.io.Closeables; import com.google.common.io.Files; @@ -18,9 +20,11 @@ public class TimingReportGenerator { private static final String META_STOPPED = "Stopped: %s (after %s seconds)" + NEWLINE; private static final String PLUGIN_HEADER = "=== PLUGIN %s ===" + NEWLINE; private static final String LISTENER_HEADER = " TYPE: %s " + NEWLINE; - private static final String SEPERATION_LINE = " ------------------------------- " + NEWLINE; - private static final String STATISTICS_HEADER = " Packet: Count: Min (ms): Max (ms): Mean (ms): Std (ms): " + NEWLINE; - private static final String STATISTICS_ROW = " %-12s %-12d %-15.6f %-15.6f %-15.6f %.6f " + NEWLINE; + private static final String SEPERATION_LINE = " " + Strings.repeat("-", 139) + NEWLINE; + private static final String STATISTICS_HEADER = + " Protocol: Name: ID: Count: Min (ms): " + + "Max (ms): Mean (ms): Std (ms): " + NEWLINE; + private static final String STATISTICS_ROW = " %-15s %-29s %-19s %-12d %-15.6f %-15.6f %-15.6f %.6f " + NEWLINE; private static final String SUM_MAIN_THREAD = " => Time on main thread: %.6f ms" + NEWLINE; public void saveTo(File destination, TimedListenerManager manager) throws IOException { @@ -66,7 +70,7 @@ public class TimingReportGenerator { } private void saveStatistics(Writer destination, TimedTracker tracker, ListenerType type) throws IOException { - StatisticsStream[] streams = tracker.getStatistics(); + Map streams = tracker.getStatistics(); StatisticsStream sum = new StatisticsStream(); int count = 0; @@ -74,11 +78,11 @@ public class TimingReportGenerator { destination.write(SEPERATION_LINE); // Write every packet ID that we care about - for (int i = 0; i < Packets.PACKET_COUNT; i++) { - final StatisticsStream stream = streams[i]; + for (PacketType key : Sets.newTreeSet(streams.keySet())) { + final StatisticsStream stream = streams.get(key); if (stream != null && stream.getCount() > 0) { - printStatistic(destination, Integer.toString(i), stream); + printStatistic(destination, key, stream); // Add it count++; @@ -88,7 +92,7 @@ public class TimingReportGenerator { // Write the sum - if its useful if (count > 1) { - printStatistic(destination, "SUM", sum); + printStatistic(destination, null, sum); } // These are executed on the main thread if (type == ListenerType.SYNC_SERVER_SIDE) { @@ -98,9 +102,12 @@ public class TimingReportGenerator { } } - private void printStatistic(Writer destination, String key, final StatisticsStream stream) throws IOException { + private void printStatistic(Writer destination, PacketType key, final StatisticsStream stream) throws IOException { destination.write(String.format(STATISTICS_ROW, - key, stream.getCount(), + key != null ? key.getProtocol() : "SUM", + key != null ? key.name() : "-", + key != null ? getPacketId(key) : "-", + stream.getCount(), toMilli(stream.getMinimum()), toMilli(stream.getMaximum()), toMilli(stream.getMean()), @@ -108,6 +115,10 @@ public class TimingReportGenerator { )); } + private String getPacketId(PacketType type) { + return Strings.padStart(Integer.toString(type.getCurrentId()), 2, '0') + " (Legacy: " + type.getLegacyId() + ")"; + } + /** * Convert a value in nanoseconds to milliseconds. * @param value - the value.