More improvements to Timings, RCON now is no longer blocking!
Finally made timings accept "Callback style" reports, so plugins can listen for when the report is done. Added new Util interfaces, MessageCommandSender and BufferedCommandSender This restores and improves using RCON to generate timings reports
This commit is contained in:
parent
f938ae30fd
commit
d033b57b47
2 changed files with 199 additions and 143 deletions
|
@ -1,4 +1,4 @@
|
|||
From 54d8f0c3b52d8bd1d3e4afee2c6c3489da1c3577 Mon Sep 17 00:00:00 2001
|
||||
From 134c514dd418485e6f07d20930dc0c4398dc76fd Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 18:48:17 -0600
|
||||
Subject: [PATCH] Timings v2
|
||||
|
@ -1184,10 +1184,10 @@ index 00000000..623dda49
|
|||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
|
||||
new file mode 100644
|
||||
index 00000000..483e3669
|
||||
index 00000000..0571c9e7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/Timings.java
|
||||
@@ -0,0 +1,274 @@
|
||||
@@ -0,0 +1,284 @@
|
||||
+/*
|
||||
+ * This file is licensed under the MIT License (MIT).
|
||||
+ *
|
||||
|
@ -1215,6 +1215,7 @@ index 00000000..483e3669
|
|||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import com.google.common.collect.EvictingQueue;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
|
@ -1431,7 +1432,16 @@ index 00000000..483e3669
|
|||
+ if (sender == null) {
|
||||
+ sender = Bukkit.getConsoleSender();
|
||||
+ }
|
||||
+ // Schedule report for end of tick
|
||||
+ TimingsExport.requestingReport.add(sender);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Generates a report and sends it to the specified listener.
|
||||
+ * Use with {@link org.bukkit.command.BufferedCommandSender} to get full response when done!
|
||||
+ * @param sender The listener to send responses too.
|
||||
+ */
|
||||
+ public static void generateReport(TimingsReportListener sender) {
|
||||
+ Validate.notNull(sender);
|
||||
+ TimingsExport.requestingReport.add(sender);
|
||||
+ }
|
||||
+
|
||||
|
@ -1589,10 +1599,10 @@ index 00000000..56b10e89
|
|||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
|
||||
new file mode 100644
|
||||
index 00000000..9dd36419
|
||||
index 00000000..23a3daa8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
|
||||
@@ -0,0 +1,394 @@
|
||||
@@ -0,0 +1,341 @@
|
||||
+/*
|
||||
+ * This file is licensed under the MIT License (MIT).
|
||||
+ *
|
||||
|
@ -1618,7 +1628,6 @@ index 00000000..9dd36419
|
|||
+ */
|
||||
+package co.aikar.timings;
|
||||
+
|
||||
+import com.google.common.base.Function;
|
||||
+import com.google.common.collect.Lists;
|
||||
+import com.google.common.collect.Sets;
|
||||
+import org.apache.commons.lang.StringUtils;
|
||||
|
@ -1626,13 +1635,9 @@ index 00000000..9dd36419
|
|||
+import org.bukkit.ChatColor;
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.command.ConsoleCommandSender;
|
||||
+import org.bukkit.command.MultiMessageCommandSender;
|
||||
+import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
+import org.bukkit.configuration.ConfigurationSection;
|
||||
+import org.bukkit.configuration.MemorySection;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.json.simple.JSONObject;
|
||||
+import org.json.simple.JSONValue;
|
||||
+
|
||||
|
@ -1640,7 +1645,6 @@ index 00000000..9dd36419
|
|||
+import java.io.IOException;
|
||||
+import java.io.InputStream;
|
||||
+import java.io.OutputStream;
|
||||
+import java.lang.management.GarbageCollectorMXBean;
|
||||
+import java.lang.management.ManagementFactory;
|
||||
+import java.lang.management.RuntimeMXBean;
|
||||
+import java.net.HttpURLConnection;
|
||||
|
@ -1653,20 +1657,25 @@ index 00000000..9dd36419
|
|||
+import java.util.zip.GZIPOutputStream;
|
||||
+
|
||||
+import static co.aikar.timings.TimingsManager.HISTORY;
|
||||
+import static co.aikar.util.JSONUtil.*;
|
||||
+import static co.aikar.util.JSONUtil.appendObjectData;
|
||||
+import static co.aikar.util.JSONUtil.createObject;
|
||||
+import static co.aikar.util.JSONUtil.pair;
|
||||
+import static co.aikar.util.JSONUtil.toArray;
|
||||
+import static co.aikar.util.JSONUtil.toArrayMapper;
|
||||
+import static co.aikar.util.JSONUtil.toObjectMapper;
|
||||
+
|
||||
+@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
|
||||
+class TimingsExport extends Thread {
|
||||
+
|
||||
+ private final CommandSender sender;
|
||||
+ private final TimingsReportListener listeners;
|
||||
+ private final Map out;
|
||||
+ private final TimingHistory[] history;
|
||||
+ private static long lastReport = 0;
|
||||
+ final static List<CommandSender> requestingReport = Lists.newArrayList();
|
||||
+
|
||||
+ private TimingsExport(CommandSender sender, Map out, TimingHistory[] history) {
|
||||
+ private TimingsExport(TimingsReportListener listeners, Map out, TimingHistory[] history) {
|
||||
+ super("Timings paste thread");
|
||||
+ this.sender = sender;
|
||||
+ this.listeners = listeners;
|
||||
+ this.out = out;
|
||||
+ this.history = history;
|
||||
+ }
|
||||
|
@ -1678,19 +1687,24 @@ index 00000000..9dd36419
|
|||
+ if (requestingReport.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ CommandSender sender = new MultiMessageCommandSender(requestingReport);
|
||||
+ TimingsReportListener listeners = new TimingsReportListener(requestingReport);
|
||||
+ listeners.addConsoleIfNeeded();
|
||||
+
|
||||
+ requestingReport.clear();
|
||||
+ long now = System.currentTimeMillis();
|
||||
+ final long lastReportDiff = now - lastReport;
|
||||
+ if (lastReportDiff < 60000) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)");
|
||||
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)");
|
||||
+ listeners.done();
|
||||
+ return;
|
||||
+ }
|
||||
+ final long lastStartDiff = now - TimingsManager.timingStart;
|
||||
+ if (lastStartDiff < 180000) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)");
|
||||
+ listeners.sendMessage(ChatColor.RED + "Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)");
|
||||
+ listeners.done();
|
||||
+ return;
|
||||
+ }
|
||||
+ listeners.sendMessage(ChatColor.GREEN + "Preparing Timings Report...");
|
||||
+ lastReport = now;
|
||||
+ Map parent = createObject(
|
||||
+ // Get some basic system details about the server
|
||||
|
@ -1722,12 +1736,7 @@ index 00000000..9dd36419
|
|||
+ pair("cpu", runtime.availableProcessors()),
|
||||
+ pair("runtime", ManagementFactory.getRuntimeMXBean().getUptime()),
|
||||
+ pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")),
|
||||
+ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), new Function<GarbageCollectorMXBean, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(GarbageCollectorMXBean input) {
|
||||
+ return pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime()));
|
||||
+ }
|
||||
+ }))
|
||||
+ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), input -> pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime()))))
|
||||
+ )
|
||||
+ );
|
||||
+
|
||||
|
@ -1763,49 +1772,24 @@ index 00000000..9dd36419
|
|||
+
|
||||
+ parent.put("idmap", createObject(
|
||||
+ pair("groups", toObjectMapper(
|
||||
+ TimingIdentifier.GROUP_MAP.values(), new Function<TimingIdentifier.TimingGroup, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(TimingIdentifier.TimingGroup group) {
|
||||
+ return pair(group.id, group.name);
|
||||
+ }
|
||||
+ })),
|
||||
+ TimingIdentifier.GROUP_MAP.values(), group -> pair(group.id, group.name))),
|
||||
+ pair("handlers", handlers),
|
||||
+ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), new Function<Map.Entry<String, Integer>, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(Map.Entry<String, Integer> input) {
|
||||
+ return pair(input.getValue(), input.getKey());
|
||||
+ }
|
||||
+ })),
|
||||
+ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), input -> pair(input.getValue(), input.getKey()))),
|
||||
+ pair("tileentity",
|
||||
+ toObjectMapper(tileEntityTypeSet, new Function<Material, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(Material input) {
|
||||
+ return pair(input.getId(), input.name());
|
||||
+ }
|
||||
+ })),
|
||||
+ toObjectMapper(tileEntityTypeSet, input -> pair(input.getId(), input.name()))),
|
||||
+ pair("entity",
|
||||
+ toObjectMapper(entityTypeSet, new Function<EntityType, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(EntityType input) {
|
||||
+ return pair(input.getTypeId(), input.name());
|
||||
+ }
|
||||
+ }))
|
||||
+ toObjectMapper(entityTypeSet, input -> pair(input.getTypeId(), input.name())))
|
||||
+ ));
|
||||
+
|
||||
+ // Information about loaded plugins
|
||||
+
|
||||
+ parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(),
|
||||
+ new Function<Plugin, JSONPair>() {
|
||||
+ @Override
|
||||
+ public JSONPair apply(Plugin plugin) {
|
||||
+ return pair(plugin.getName(), createObject(
|
||||
+ pair("version", plugin.getDescription().getVersion()),
|
||||
+ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()),
|
||||
+ pair("website", plugin.getDescription().getWebsite()),
|
||||
+ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", "))
|
||||
+ ));
|
||||
+ }
|
||||
+ }));
|
||||
+ plugin -> pair(plugin.getName(), createObject(
|
||||
+ pair("version", plugin.getDescription().getVersion()),
|
||||
+ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()),
|
||||
+ pair("website", plugin.getDescription().getWebsite()),
|
||||
+ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", "))
|
||||
+ ))));
|
||||
+
|
||||
+
|
||||
+
|
||||
|
@ -1817,7 +1801,7 @@ index 00000000..9dd36419
|
|||
+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null))
|
||||
+ ));
|
||||
+
|
||||
+ new TimingsExport(sender, parent, history).start();
|
||||
+ new TimingsExport(listeners, parent, history).start();
|
||||
+ }
|
||||
+
|
||||
+ static long getCost() {
|
||||
|
@ -1874,12 +1858,7 @@ index 00000000..9dd36419
|
|||
+ if (!(val instanceof MemorySection)) {
|
||||
+ if (val instanceof List) {
|
||||
+ Iterable<Object> v = (Iterable<Object>) val;
|
||||
+ return toArrayMapper(v, new Function<Object, Object>() {
|
||||
+ @Override
|
||||
+ public Object apply(Object input) {
|
||||
+ return valAsJSON(input, parentKey);
|
||||
+ }
|
||||
+ });
|
||||
+ return toArrayMapper(v, input -> valAsJSON(input, parentKey));
|
||||
+ } else {
|
||||
+ return val.toString();
|
||||
+ }
|
||||
|
@ -1888,30 +1867,9 @@ index 00000000..9dd36419
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("CallToThreadRun")
|
||||
+ @Override
|
||||
+ public synchronized void start() {
|
||||
+ if (sender instanceof RemoteConsoleCommandSender) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Warning: Timings report done over RCON will cause lag spikes.");
|
||||
+ sender.sendMessage(ChatColor.RED + "You should use " + ChatColor.YELLOW +
|
||||
+ "/timings report" + ChatColor.RED + " in game or console.");
|
||||
+ run();
|
||||
+ } else {
|
||||
+ super.start();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ sender.sendMessage(ChatColor.GREEN + "Preparing Timings Report...");
|
||||
+
|
||||
+
|
||||
+ out.put("data", toArrayMapper(history, new Function<TimingHistory, Object>() {
|
||||
+ @Override
|
||||
+ public Object apply(TimingHistory input) {
|
||||
+ return input.export();
|
||||
+ }
|
||||
+ }));
|
||||
+ out.put("data", toArrayMapper(history, TimingHistory::export));
|
||||
+
|
||||
+
|
||||
+ String response = null;
|
||||
|
@ -1936,9 +1894,9 @@ index 00000000..9dd36419
|
|||
+ response = getResponse(con);
|
||||
+
|
||||
+ if (con.getResponseCode() != 302) {
|
||||
+ sender.sendMessage(
|
||||
+ listeners.sendMessage(
|
||||
+ ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage());
|
||||
+ sender.sendMessage(ChatColor.RED + "Check your logs for more information");
|
||||
+ listeners.sendMessage(ChatColor.RED + "Check your logs for more information");
|
||||
+ if (response != null) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, response);
|
||||
+ }
|
||||
|
@ -1946,20 +1904,19 @@ index 00000000..9dd36419
|
|||
+ }
|
||||
+
|
||||
+ String location = con.getHeaderField("Location");
|
||||
+ sender.sendMessage(ChatColor.GREEN + "View Timings Report: " + location);
|
||||
+ if (!(sender instanceof ConsoleCommandSender)) {
|
||||
+ Bukkit.getLogger().log(Level.INFO, "View Timings Report: " + location);
|
||||
+ }
|
||||
+ listeners.sendMessage(ChatColor.GREEN + "View Timings Report: " + location);
|
||||
+
|
||||
+ if (response != null && !response.isEmpty()) {
|
||||
+ Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response);
|
||||
+ }
|
||||
+ } catch (IOException ex) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
+ if (response != null) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, response);
|
||||
+ }
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex);
|
||||
+ } finally {
|
||||
+ this.listeners.done();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
@ -1977,7 +1934,7 @@ index 00000000..9dd36419
|
|||
+ return bos.toString();
|
||||
+
|
||||
+ } catch (IOException ex) {
|
||||
+ sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
+ listeners.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
+ Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex);
|
||||
+ return null;
|
||||
+ } finally {
|
||||
|
@ -2189,6 +2146,74 @@ index 00000000..58ed35e0
|
|||
+ return null;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingsReportListener.java b/src/main/java/co/aikar/timings/TimingsReportListener.java
|
||||
new file mode 100644
|
||||
index 00000000..4d492d4b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/TimingsReportListener.java
|
||||
@@ -0,0 +1,62 @@
|
||||
+package co.aikar.timings;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.command.ConsoleCommandSender;
|
||||
+import org.bukkit.command.MessageCommandSender;
|
||||
+import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+@SuppressWarnings("WeakerAccess")
|
||||
+public class TimingsReportListener implements MessageCommandSender {
|
||||
+ private final List<CommandSender> senders;
|
||||
+ private final Runnable onDone;
|
||||
+
|
||||
+ public TimingsReportListener(CommandSender senders) {
|
||||
+ this(senders, null);
|
||||
+ }
|
||||
+ public TimingsReportListener(CommandSender sender, Runnable onDone) {
|
||||
+ this(Lists.newArrayList(sender), onDone);
|
||||
+ }
|
||||
+ public TimingsReportListener(List<CommandSender> senders) {
|
||||
+ this(senders, null);
|
||||
+ }
|
||||
+ public TimingsReportListener(List<CommandSender> senders, Runnable onDone) {
|
||||
+ Validate.notNull(senders);
|
||||
+ Validate.notEmpty(senders);
|
||||
+
|
||||
+ this.senders = Lists.newArrayList(senders);
|
||||
+ this.onDone = onDone;
|
||||
+ }
|
||||
+
|
||||
+ public void done() {
|
||||
+ if (onDone != null) {
|
||||
+ onDone.run();
|
||||
+ }
|
||||
+ for (CommandSender sender : senders) {
|
||||
+ if (sender instanceof TimingsReportListener) {
|
||||
+ ((TimingsReportListener) sender).done();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(String message) {
|
||||
+ senders.forEach((sender) -> sender.sendMessage(message));
|
||||
+ }
|
||||
+
|
||||
+ public void addConsoleIfNeeded() {
|
||||
+ boolean hasConsole = false;
|
||||
+ for (CommandSender sender : this.senders) {
|
||||
+ if (sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) {
|
||||
+ hasConsole = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!hasConsole) {
|
||||
+ this.senders.add(Bukkit.getConsoleSender());
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/UnsafeTimingHandler.java b/src/main/java/co/aikar/timings/UnsafeTimingHandler.java
|
||||
new file mode 100644
|
||||
index 00000000..5edaba12
|
||||
|
@ -2940,6 +2965,30 @@ index 120dba25..77cfe561 100644
|
|||
/**
|
||||
* Sends the component to the player
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java
|
||||
new file mode 100644
|
||||
index 00000000..fd452bce
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/command/BufferedCommandSender.java
|
||||
@@ -0,0 +1,18 @@
|
||||
+package org.bukkit.command;
|
||||
+
|
||||
+public class BufferedCommandSender implements MessageCommandSender {
|
||||
+ private final StringBuffer buffer = new StringBuffer();
|
||||
+ @Override
|
||||
+ public void sendMessage(String message) {
|
||||
+ buffer.append(message);
|
||||
+ buffer.append("\n");
|
||||
+ }
|
||||
+
|
||||
+ public String getBuffer() {
|
||||
+ return buffer.toString();
|
||||
+ }
|
||||
+
|
||||
+ public void reset() {
|
||||
+ this.buffer.setLength(0);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
|
||||
index 08a9739f..347d2189 100644
|
||||
--- a/src/main/java/org/bukkit/command/Command.java
|
||||
|
@ -2992,17 +3041,15 @@ index 3f07d7f4..f89ad075 100644
|
|||
private static boolean inRange(int i, int j, int k) {
|
||||
return i >= j && i <= k;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/MultiMessageCommandSender.java b/src/main/java/org/bukkit/command/MultiMessageCommandSender.java
|
||||
diff --git a/src/main/java/org/bukkit/command/MessageCommandSender.java b/src/main/java/org/bukkit/command/MessageCommandSender.java
|
||||
new file mode 100644
|
||||
index 00000000..7b512fd4
|
||||
index 00000000..66232339
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/command/MultiMessageCommandSender.java
|
||||
@@ -0,0 +1,114 @@
|
||||
+++ b/src/main/java/org/bukkit/command/MessageCommandSender.java
|
||||
@@ -0,0 +1,99 @@
|
||||
+package org.bukkit.command;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import org.apache.commons.lang.NotImplementedException;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.Server;
|
||||
+import org.bukkit.permissions.Permission;
|
||||
|
@ -3010,105 +3057,92 @@ index 00000000..7b512fd4
|
|||
+import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import java.util.List;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+/**
|
||||
+ * Used for proxying messages to multiple senders.
|
||||
+ * Do not use this for anything else but messages.
|
||||
+ * For when all you care about is just messaging
|
||||
+ */
|
||||
+public class MultiMessageCommandSender implements CommandSender {
|
||||
+ private final List<CommandSender> senders;
|
||||
+public interface MessageCommandSender extends CommandSender {
|
||||
+
|
||||
+ public MultiMessageCommandSender(List<CommandSender> senders) {
|
||||
+ Validate.notNull(senders);
|
||||
+ Validate.notEmpty(senders);
|
||||
+
|
||||
+ this.senders = Lists.newArrayList(senders);
|
||||
+ @Override
|
||||
+ default void sendMessage(String[] messages) {
|
||||
+ for (String message : messages) {
|
||||
+ sendMessage(message);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(String message) {
|
||||
+ senders.forEach((sender) -> sender.sendMessage(message));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(String[] messages) {
|
||||
+ senders.forEach((sender) -> sender.sendMessage(messages));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Server getServer() {
|
||||
+ default Server getServer() {
|
||||
+ return Bukkit.getServer();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getName() {
|
||||
+ default String getName() {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOp() {
|
||||
+ default boolean isOp() {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setOp(boolean value) {
|
||||
+ default void setOp(boolean value) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isPermissionSet(String name) {
|
||||
+ default boolean isPermissionSet(String name) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isPermissionSet(Permission perm) {
|
||||
+ default boolean isPermissionSet(Permission perm) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasPermission(String name) {
|
||||
+ default boolean hasPermission(String name) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasPermission(Permission perm) {
|
||||
+ default boolean hasPermission(Permission perm) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
|
||||
+ default PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PermissionAttachment addAttachment(Plugin plugin) {
|
||||
+ default PermissionAttachment addAttachment(Plugin plugin) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
|
||||
+ default PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
|
||||
+ default PermissionAttachment addAttachment(Plugin plugin, int ticks) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeAttachment(PermissionAttachment attachment) {
|
||||
+ default void removeAttachment(PermissionAttachment attachment) {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void recalculatePermissions() {
|
||||
+ default void recalculatePermissions() {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
+ default Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
+ throw new NotImplementedException();
|
||||
+ }
|
||||
+}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
From fab6746b634e849bb0effc92deb503dc84e72eac Mon Sep 17 00:00:00 2001
|
||||
From f6a0b22a39ad826143911fdb4e4127297e1cf862 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 04:00:11 -0600
|
||||
Subject: [PATCH] Timings v2
|
||||
|
||||
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
index 0e88ae2a7..31b8401aa 100644
|
||||
index 8b96966d8..8d1e8680b 100644
|
||||
--- a/pom.xml
|
||||
+++ b/pom.xml
|
||||
@@ -66,6 +66,12 @@
|
||||
|
@ -493,7 +493,7 @@ index 81fc04ed3..bd3b16025 100644
|
|||
|
||||
private void z() {
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 87c07f2be..e18fb875f 100644
|
||||
index daf2c0a67..3ba489d4f 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -195,7 +195,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
||||
|
@ -555,7 +555,7 @@ index a97e7d3c2..4890023d7 100644
|
|||
// return chunk; // CraftBukkit
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
index cb83e4f56..4dab9e962 100644
|
||||
index cb83e4f56..e6819139f 100644
|
||||
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
|
||||
@@ -23,7 +23,7 @@ import java.io.PrintStream;
|
||||
|
@ -585,6 +585,28 @@ index cb83e4f56..4dab9e962 100644
|
|||
}
|
||||
|
||||
public boolean aa() {
|
||||
@@ -692,7 +692,20 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
|
||||
return remoteControlCommandListener.getMessages();
|
||||
}
|
||||
};
|
||||
- processQueue.add(waitable);
|
||||
+ // Paper start
|
||||
+ if (s.toLowerCase().startsWith("timings") && s.toLowerCase().matches("timings (report|paste|get|merged|seperate)")) {
|
||||
+ org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender();
|
||||
+ waitable = new Waitable<String>() {
|
||||
+ @Override
|
||||
+ protected String evaluate() {
|
||||
+ return sender.getBuffer();
|
||||
+ }
|
||||
+ };
|
||||
+ co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable));
|
||||
+ } else {
|
||||
+ processQueue.add(waitable);
|
||||
+ }
|
||||
+ // Paper end
|
||||
try {
|
||||
return waitable.get();
|
||||
} catch (java.util.concurrent.ExecutionException e) {
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index e7b1ebbe3..05312c6ac 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
|
@ -1832,5 +1854,5 @@ index c32d44df0..5c2fb0058 100644
|
|||
}
|
||||
}
|
||||
--
|
||||
2.11.0.windows.3
|
||||
2.11.0
|
||||
|
||||
|
|
Loading…
Reference in a new issue