From a8af93a7cd63310ced88cb77da2927f6932f844a Mon Sep 17 00:00:00 2001 From: Sauilitired Date: Sun, 13 Jan 2019 09:05:19 +0100 Subject: [PATCH] Add Incendo debug pasting to legacy PlotSquared, because I like being happy and tend to dislike being unhappy. --- .../com/plotsquared/bukkit/BukkitMain.java | 94 ++------- .../intellectualcrafters/plot/IPlotMain.java | 7 + .../plot/commands/DebugPaste.java | 123 +++++++++--- .../plot/util/HastebinUtility.java | 63 ------ .../plot/util/IncendoPaster.java | 189 ++++++++++++++++++ .../com/plotsquared/nukkit/NukkitMain.java | 11 +- .../com/plotsquared/sponge/SpongeMain.java | 40 +--- 7 files changed, 331 insertions(+), 196 deletions(-) delete mode 100644 Core/src/main/java/com/intellectualcrafters/plot/util/HastebinUtility.java create mode 100644 Core/src/main/java/com/intellectualcrafters/plot/util/IncendoPaster.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java index 059d65d46..1657a8a47 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java @@ -1,7 +1,5 @@ package com.plotsquared.bukkit; -import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; - import com.intellectualcrafters.configuration.ConfigurationSection; import com.intellectualcrafters.plot.IPlotMain; import com.intellectualcrafters.plot.PS; @@ -12,89 +10,27 @@ import com.intellectualcrafters.plot.generator.GeneratorWrapper; import com.intellectualcrafters.plot.generator.HybridGen; import com.intellectualcrafters.plot.generator.HybridUtils; import com.intellectualcrafters.plot.generator.IndependentPlotGenerator; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotArea; -import com.intellectualcrafters.plot.object.PlotId; -import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.object.RunnableVal; -import com.intellectualcrafters.plot.object.SetupObject; +import com.intellectualcrafters.plot.object.*; import com.intellectualcrafters.plot.object.chat.PlainChatManager; import com.intellectualcrafters.plot.object.worlds.PlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SinglePlotArea; import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SingleWorldGenerator; -import com.intellectualcrafters.plot.util.AbstractTitle; -import com.intellectualcrafters.plot.util.ChatManager; -import com.intellectualcrafters.plot.util.ChunkManager; -import com.intellectualcrafters.plot.util.ConsoleColors; -import com.intellectualcrafters.plot.util.EconHandler; -import com.intellectualcrafters.plot.util.EventUtil; -import com.intellectualcrafters.plot.util.InventoryUtil; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.ReflectionUtils; -import com.intellectualcrafters.plot.util.SchematicHandler; -import com.intellectualcrafters.plot.util.SetupUtils; -import com.intellectualcrafters.plot.util.StringMan; -import com.intellectualcrafters.plot.util.TaskManager; -import com.intellectualcrafters.plot.util.UUIDHandler; -import com.intellectualcrafters.plot.util.UUIDHandlerImplementation; -import com.intellectualcrafters.plot.util.WorldUtil; +import com.intellectualcrafters.plot.util.*; import com.intellectualcrafters.plot.util.block.QueueProvider; import com.intellectualcrafters.plot.uuid.UUIDWrapper; import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector; import com.plotsquared.bukkit.database.plotme.LikePlotMeConverter; import com.plotsquared.bukkit.database.plotme.PlotMeConnector_017; import com.plotsquared.bukkit.generator.BukkitPlotGenerator; -import com.plotsquared.bukkit.listeners.ChunkListener; -import com.plotsquared.bukkit.listeners.EntityPortal_1_7_9; -import com.plotsquared.bukkit.listeners.EntitySpawnListener; -import com.plotsquared.bukkit.listeners.PlayerEvents; -import com.plotsquared.bukkit.listeners.PlayerEvents183; -import com.plotsquared.bukkit.listeners.PlayerEvents_1_8; -import com.plotsquared.bukkit.listeners.PlayerEvents_1_9; -import com.plotsquared.bukkit.listeners.PlotPlusListener; -import com.plotsquared.bukkit.listeners.PlotPlusListener_1_12; -import com.plotsquared.bukkit.listeners.PlotPlusListener_Legacy; -import com.plotsquared.bukkit.listeners.SingleWorldListener; -import com.plotsquared.bukkit.listeners.WorldEvents; +import com.plotsquared.bukkit.listeners.*; import com.plotsquared.bukkit.titles.DefaultTitle_111; -import com.plotsquared.bukkit.util.BukkitChatManager; -import com.plotsquared.bukkit.util.BukkitChunkManager; -import com.plotsquared.bukkit.util.BukkitCommand; -import com.plotsquared.bukkit.util.BukkitEconHandler; -import com.plotsquared.bukkit.util.BukkitEventUtil; -import com.plotsquared.bukkit.util.BukkitHybridUtils; -import com.plotsquared.bukkit.util.BukkitInventoryUtil; -import com.plotsquared.bukkit.util.BukkitSchematicHandler; -import com.plotsquared.bukkit.util.BukkitSetupUtils; -import com.plotsquared.bukkit.util.BukkitTaskManager; -import com.plotsquared.bukkit.util.BukkitUtil; -import com.plotsquared.bukkit.util.BukkitVersion; -import com.plotsquared.bukkit.util.Metrics; -import com.plotsquared.bukkit.util.SendChunk; -import com.plotsquared.bukkit.util.SetGenCB; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_7; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_8; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_8_3; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_9; -import com.plotsquared.bukkit.uuid.DefaultUUIDWrapper; -import com.plotsquared.bukkit.uuid.FileUUIDHandler; -import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper; -import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper; -import com.plotsquared.bukkit.uuid.SQLUUIDHandler; +import com.plotsquared.bukkit.util.*; +import com.plotsquared.bukkit.util.block.*; +import com.plotsquared.bukkit.uuid.*; import com.sk89q.worldedit.WorldEdit; -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; import org.bukkit.Location; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; +import org.bukkit.*; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -107,6 +43,15 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import javax.annotation.Nonnull; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; + public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain { private static ConcurrentHashMap pluginMap; @@ -183,6 +128,11 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain return this.version; } + @Nonnull @Override + public String getServerImplementation() { + return Bukkit.getVersion(); + } + @Override public void onEnable() { if (pluginMap != null) { @@ -921,4 +871,4 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain } return names; } -} \ No newline at end of file +} diff --git a/Core/src/main/java/com/intellectualcrafters/plot/IPlotMain.java b/Core/src/main/java/com/intellectualcrafters/plot/IPlotMain.java index 5ce7beb64..f00ac0f1b 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/IPlotMain.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/IPlotMain.java @@ -18,6 +18,7 @@ import com.intellectualcrafters.plot.util.UUIDHandlerImplementation; import com.intellectualcrafters.plot.util.WorldUtil; import com.intellectualcrafters.plot.util.block.QueueProvider; +import javax.annotation.Nonnull; import java.io.File; import java.util.List; @@ -81,6 +82,12 @@ public interface IPlotMain extends ILogger { */ int[] getServerVersion(); + /** + * Get the server implementation string + */ + @Nonnull + String getServerImplementation(); + /** * Get the NMS package prefix. * @return The NMS package prefix diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/DebugPaste.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/DebugPaste.java index 083ae256b..311e05aa2 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/DebugPaste.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/DebugPaste.java @@ -1,17 +1,24 @@ package com.intellectualcrafters.plot.commands; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.util.HastebinUtility; +import com.intellectualcrafters.plot.util.IncendoPaster; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.UUIDHandler; import com.plotsquared.general.commands.CommandDeclaration; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; @CommandDeclaration(command = "debugpaste", aliases = "dp", usage = "/plot debugpaste", @@ -26,28 +33,16 @@ public class DebugPaste extends SubCommand { @Override public void run() { try { - String settingsYML = HastebinUtility.upload(PS.get().configFile); - String worldsYML = HastebinUtility.upload(PS.get().worldsFile); - String commandsYML = HastebinUtility.upload(PS.get().commandsFile); - String latestLOG; - try { - latestLOG = HastebinUtility.upload(new File(PS.get().IMP.getDirectory(), "../../logs/latest.log")); - } catch (IOException ignored) { - MainUtil.sendMessage(player, "&clatest.log is too big to be pasted, will ignore"); - latestLOG = "too big :("; - } + final IncendoPaster incendoPaster = new IncendoPaster("plotsquared"); + StringBuilder b = new StringBuilder(); b.append( - "# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your " - + "problem\n\n# We will start with some informational files\n"); - b.append("links.settings_yml: ").append(settingsYML).append('\n'); - b.append("links.worlds_yml: ").append(worldsYML).append('\n'); - b.append("links.commands_yml: ").append(commandsYML).append('\n'); - b.append("links.latest_log: ").append(latestLOG).append('\n'); - b.append("\n# Server Information\n"); - int[] sVersion = PS.get().IMP.getServerVersion(); - b.append("version.server: ").append(sVersion[0]).append('.').append(sVersion[1]).append('.').append(sVersion[2]).append('\n'); - b.append("online_mode: ").append(UUIDHandler.getUUIDWrapper()).append(';').append(!Settings.UUID.OFFLINE).append('\n'); + "# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your " + + "problem\n\n"); + b.append("# Server Information\n"); + b.append("server.version: ").append(PS.imp().getServerImplementation()).append("\n"); + b.append("online_mode: ").append(UUIDHandler.getUUIDWrapper()).append(';') + .append(!Settings.UUID.OFFLINE).append('\n'); b.append("plugins:"); for (String id : PS.get().IMP.getPluginIds()) { String[] split = id.split(":"); @@ -55,24 +50,76 @@ public class DebugPaste extends SubCommand { String enabled = split.length == 2 ? split[1] : "unknown"; String name = split2[0]; String version = split2.length == 2 ? split2[1] : "unknown"; - b.append("\n ").append(name).append(":\n ").append("version: '").append(version).append('\'').append("\n enabled: ") - .append(enabled); + b.append("\n ").append(name).append(":\n ").append("version: '") + .append(version).append('\'').append("\n enabled: ").append(enabled); } b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n"); Runtime runtime = Runtime.getRuntime(); b.append("memory.free: ").append(runtime.freeMemory()).append('\n'); b.append("memory.max: ").append(runtime.maxMemory()).append('\n'); - b.append("java.specification.version: '").append(System.getProperty("java.specification.version")).append("'\n"); - b.append("java.vendor: '").append(System.getProperty("java.vendor")).append("'\n"); - b.append("java.version: '").append(System.getProperty("java.version")).append("'\n"); + b.append("java.specification.version: '") + .append(System.getProperty("java.specification.version")).append("'\n"); + b.append("java.vendor: '").append(System.getProperty("java.vendor")) + .append("'\n"); + b.append("java.version: '").append(System.getProperty("java.version")) + .append("'\n"); b.append("os.arch: '").append(System.getProperty("os.arch")).append("'\n"); b.append("os.name: '").append(System.getProperty("os.name")).append("'\n"); - b.append("os.version: '").append(System.getProperty("os.version")).append("'\n\n"); + b.append("os.version: '").append(System.getProperty("os.version")) + .append("'\n\n"); b.append("# Okay :D Great. You are now ready to create your bug report!"); - b.append("\n# You can do so at https://github.com/IntellectualSites/PlotSquared/issues"); + b.append( + "\n# You can do so at https://github.com/IntellectualSites/PlotSquared/issues"); + b.append("\n# or via our Discord at https://discord.gg/ngZCzbU"); - String link = HastebinUtility.upload(b.toString()); - player.sendMessage(C.DEBUG_REPORT_CREATED.s().replace("%url%", link)); + incendoPaster.addFile(new IncendoPaster.PasteFile("information", b.toString())); + + try { + final File logFile = new File(PS.get().IMP.getDirectory(), + "../../logs/latest.log"); + if (Files.size(logFile.toPath()) > 14_000_000) { + throw new IOException("Too big..."); + } + incendoPaster.addFile(new IncendoPaster.PasteFile("latest.log", readFile(logFile))); + } catch (IOException ignored) { + MainUtil.sendMessage(player, + "&clatest.log is too big to be pasted, will ignore"); + } + + try { + incendoPaster.addFile(new IncendoPaster.PasteFile("settings.yml", readFile(PS.get().configFile))); + } catch (final IllegalArgumentException ignored) { + MainUtil.sendMessage(player, "&cSkipping settings.yml because it's empty"); + } + try { + incendoPaster.addFile(new IncendoPaster.PasteFile("worlds.yml", readFile(PS.get().worldsFile))); + } catch (final IllegalArgumentException ignored) { + MainUtil.sendMessage(player, "&cSkipping worlds.yml because it's empty"); + } + try { + incendoPaster.addFile(new IncendoPaster.PasteFile("PlotSquared.use_THIS.yml", + readFile(PS.get().translationFile))); + } catch (final IllegalArgumentException ignored) { + MainUtil.sendMessage(player, "&cSkipping PlotSquared.use_THIS.yml because it's empty"); + } + + try { + final String rawResponse = incendoPaster.upload(); + final JsonObject jsonObject = new JsonParser().parse(rawResponse).getAsJsonObject(); + + if (jsonObject.has("created")) { + final String pasteId = jsonObject.get("paste_id").getAsString(); + final String link = String.format("https://incendo.org/paste/view/%s", pasteId); + player.sendMessage( + C.DEBUG_REPORT_CREATED.s().replace("%url%", link)); + } else { + final String responseMessage = jsonObject.get("response").getAsString(); + MainUtil.sendMessage(player, String.format("&cFailed to create the debug paste: %s", responseMessage)); + } + } catch (final Throwable throwable) { + throwable.printStackTrace(); + MainUtil.sendMessage(player, "&cFailed to create the debug paste: " + throwable.getMessage()); + } } catch (IOException e) { e.printStackTrace(); } @@ -80,4 +127,20 @@ public class DebugPaste extends SubCommand { }); return true; } + + private static String readFile(final File file) throws IOException { + final StringBuilder content = new StringBuilder(); + final List lines = new ArrayList<>(); + try (final BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + lines.add(line); + } + } + for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) { + content.append(lines.get(i)).append("\n"); + } + return content.toString(); + } + } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/util/HastebinUtility.java b/Core/src/main/java/com/intellectualcrafters/plot/util/HastebinUtility.java deleted file mode 100644 index 8f83b8928..000000000 --- a/Core/src/main/java/com/intellectualcrafters/plot/util/HastebinUtility.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.intellectualcrafters.plot.util; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class HastebinUtility { - - public static final String BIN_URL = "https://hastebin.com/documents", USER_AGENT = "Mozilla/5.0"; - public static final Pattern PATTERN = Pattern.compile("\\{\"key\":\"([\\S\\s]*)\"\\}"); - - public static String upload(final String string) throws IOException { - final URL url = new URL(BIN_URL); - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - connection.setRequestMethod("POST"); - connection.setRequestProperty("User-Agent", USER_AGENT); - connection.setDoOutput(true); - - try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { - outputStream.write(string.getBytes()); - outputStream.flush(); - } - - StringBuilder response; - try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - response = new StringBuilder(); - - String inputLine; - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - } - - Matcher matcher = PATTERN.matcher(response.toString()); - if (matcher.matches()) { - return "https://hastebin.com/" + matcher.group(1); - } else { - throw new RuntimeException("Couldn't read response!"); - } - } - - public static String upload(final File file) throws IOException { - final StringBuilder content = new StringBuilder(); - List lines = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - int i = 0; - while ((line = reader.readLine()) != null) { - lines.add(line); - } - } - for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) { - content.append(lines.get(i)).append("\n"); - } - return upload(content.toString()); - } - -} diff --git a/Core/src/main/java/com/intellectualcrafters/plot/util/IncendoPaster.java b/Core/src/main/java/com/intellectualcrafters/plot/util/IncendoPaster.java new file mode 100644 index 000000000..51999a22c --- /dev/null +++ b/Core/src/main/java/com/intellectualcrafters/plot/util/IncendoPaster.java @@ -0,0 +1,189 @@ +package com.intellectualcrafters.plot.util; + +import com.google.common.base.Charsets; +import com.intellectualcrafters.plot.PS; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.*; + +/** + * Single class paster for the Incendo paste service + */ +@SuppressWarnings({"unused", "WeakerAccess"}) +public final class IncendoPaster { + + /** + * Upload service URL + */ + public static final String UPLOAD_PATH = "https://incendo.org/paste/upload"; + /** + * Valid paste applications + */ + public static final Collection + VALID_APPLICATIONS = Arrays + .asList("plotsquared", "fastasyncworldedit", "incendopermissions", "kvantum"); + + private final Collection files = new ArrayList<>(); + private final String pasteApplication; + + /** + * Construct a new paster + * + * @param pasteApplication The application that is sending the paste + */ + public IncendoPaster(final String pasteApplication) { + if (pasteApplication == null || pasteApplication.isEmpty()) { + throw new IllegalArgumentException("paste application cannot be null, nor empty"); + } + if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ENGLISH))) { + throw new IllegalArgumentException(String.format("Unknown application name: %s", pasteApplication)); + } + this.pasteApplication = pasteApplication; + } + + /** + * Get an immutable collection containing all the files that have been added to this paster + * + * @return Unmodifiable collection + */ + public final Collection getFiles() { + return Collections.unmodifiableCollection(this.files); + } + + /** + * Add a file to the paster + * + * @param file File to paste + */ + public void addFile(final PasteFile file) { + if (file == null) { + throw new IllegalArgumentException("File cannot be null"); + } + // Check to see that no duplicate files are submitted + for (final PasteFile pasteFile : this.files) { + if (pasteFile.fileName.equalsIgnoreCase(file.getFileName())) { + throw new IllegalArgumentException(String.format("Found duplicate file with name %s", + file.getFileName())); + } + } + this.files.add(file); + } + + /** + * Create a JSON string from the submitted information + * + * @return compiled JSON string + */ + private String toJsonString() { + final StringBuilder builder = new StringBuilder("{\n"); + builder.append("\"paste_application\": \"").append(this.pasteApplication).append("\",\n\"files\": \""); + Iterator fileIterator = this.files.iterator(); + while (fileIterator.hasNext()) { + final PasteFile file = fileIterator.next(); + builder.append(file.getFileName()); + if (fileIterator.hasNext()) { + builder.append(","); + } + } + builder.append("\",\n"); + fileIterator = this.files.iterator(); + while (fileIterator.hasNext()) { + final PasteFile file = fileIterator.next(); + builder.append("\"file-").append(file.getFileName()).append("\": \"") + .append(file.getContent().replaceAll("\"", "\\\\\"")).append("\""); + if (fileIterator.hasNext()) { + builder.append(",\n"); + } + } + builder.append("\n}"); + return builder.toString(); + } + + /** + * Upload the paste and return the status message + * + * @return Status message + * @throws Throwable any and all exceptions + */ + public final String upload() throws Throwable { + final URL url = new URL(UPLOAD_PATH); + final URLConnection connection = url.openConnection(); + final HttpURLConnection httpURLConnection = (HttpURLConnection) connection; + httpURLConnection.setRequestMethod("POST"); + httpURLConnection.setDoOutput(true); + final byte[] content = toJsonString().getBytes(Charsets.UTF_8); + httpURLConnection.setFixedLengthStreamingMode(content.length); + httpURLConnection.setRequestProperty("Content-Type", "application/json"); + httpURLConnection.setRequestProperty("Accept", "*/*"); + httpURLConnection.connect(); + try (final OutputStream stream = httpURLConnection.getOutputStream()) { + stream.write(content); + } + if (!httpURLConnection.getResponseMessage().contains("OK")) { + if (httpURLConnection.getResponseCode() == 413) { + final long size = content.length; + PS.debug(String.format("Paste Too Big > Size: %dMB", size / 1_000_000)); + } + throw new IllegalStateException(String.format("Server returned status: %d %s", + httpURLConnection.getResponseCode(), httpURLConnection.getResponseMessage())); + } + final StringBuilder input = new StringBuilder(); + try (final BufferedReader inputStream = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()))) { + String line; + while ((line = inputStream.readLine()) != null) { + input.append(line).append("\n"); + } + } + return input.toString(); + } + + /** + * Simple class that represents a paste file + */ + public static class PasteFile { + + private final String fileName; + private final String content; + + /** + * Construct a new paste file + * + * @param fileName File name, cannot be empty, nor null + * @param content File content, cannot be empty, nor null + */ + public PasteFile(final String fileName, final String content) { + if (fileName == null || fileName.isEmpty()) { + throw new IllegalArgumentException("file name cannot be null, nor empty"); + } + if (content == null || content.isEmpty()) { + throw new IllegalArgumentException("content cannot be null, nor empty"); + } + this.fileName = fileName; + this.content = content; + } + + /** + * Get the file name + * + * @return File name + */ + public String getFileName() { + return this.fileName; + } + + /** + * Get the file content as a single string + * + * @return File content + */ + public String getContent() { + return this.content; + } + } + +} diff --git a/Nukkit/src/main/java/com/plotsquared/nukkit/NukkitMain.java b/Nukkit/src/main/java/com/plotsquared/nukkit/NukkitMain.java index 1f0423100..438e792bd 100644 --- a/Nukkit/src/main/java/com/plotsquared/nukkit/NukkitMain.java +++ b/Nukkit/src/main/java/com/plotsquared/nukkit/NukkitMain.java @@ -8,7 +8,6 @@ import cn.nukkit.event.Listener; import cn.nukkit.level.Level; import cn.nukkit.level.format.FullChunk; import cn.nukkit.level.generator.Generator; -import cn.nukkit.level.generator.Normal; import cn.nukkit.metadata.MetadataValue; import cn.nukkit.plugin.Plugin; import cn.nukkit.plugin.PluginBase; @@ -35,9 +34,10 @@ import com.plotsquared.nukkit.util.block.NukkitLocalQueue; import com.plotsquared.nukkit.uuid.FileUUIDHandler; import com.plotsquared.nukkit.uuid.LowerOfflineUUIDWrapper; import com.sk89q.worldedit.WorldEdit; + +import javax.annotation.Nonnull; import java.io.File; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.util.*; public final class NukkitMain extends PluginBase implements Listener, IPlotMain { @@ -65,6 +65,13 @@ public final class NukkitMain extends PluginBase implements Listener, IPlotMain return this.version; } + + @Override + @Nonnull + public String getServerImplementation() { + return this.getServer().getVersion(); + } + @Override public void onEnable() { try { diff --git a/Sponge/src/main/java/com/plotsquared/sponge/SpongeMain.java b/Sponge/src/main/java/com/plotsquared/sponge/SpongeMain.java index 314f1fe97..db60a9288 100644 --- a/Sponge/src/main/java/com/plotsquared/sponge/SpongeMain.java +++ b/Sponge/src/main/java/com/plotsquared/sponge/SpongeMain.java @@ -19,44 +19,18 @@ import com.intellectualcrafters.plot.object.worlds.PlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SinglePlotArea; import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SingleWorldGenerator; -import com.intellectualcrafters.plot.util.AbstractTitle; -import com.intellectualcrafters.plot.util.ChatManager; -import com.intellectualcrafters.plot.util.ChunkManager; -import com.intellectualcrafters.plot.util.EconHandler; -import com.intellectualcrafters.plot.util.EventUtil; -import com.intellectualcrafters.plot.util.InventoryUtil; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.SchematicHandler; -import com.intellectualcrafters.plot.util.SetupUtils; -import com.intellectualcrafters.plot.util.StringMan; -import com.intellectualcrafters.plot.util.TaskManager; -import com.intellectualcrafters.plot.util.UUIDHandler; -import com.intellectualcrafters.plot.util.UUIDHandlerImplementation; -import com.intellectualcrafters.plot.util.WorldUtil; +import com.intellectualcrafters.plot.util.*; import com.intellectualcrafters.plot.util.block.QueueProvider; import com.intellectualcrafters.plot.uuid.UUIDWrapper; import com.plotsquared.sponge.generator.SpongePlotGenerator; import com.plotsquared.sponge.listener.ChunkProcessor; import com.plotsquared.sponge.listener.MainListener; import com.plotsquared.sponge.listener.WorldEvents; -import com.plotsquared.sponge.util.KillRoadMobs; -import com.plotsquared.sponge.util.SpongeChatManager; -import com.plotsquared.sponge.util.SpongeChunkManager; -import com.plotsquared.sponge.util.SpongeCommand; -import com.plotsquared.sponge.util.SpongeEconHandler; -import com.plotsquared.sponge.util.SpongeEventUtil; -import com.plotsquared.sponge.util.SpongeHybridUtils; -import com.plotsquared.sponge.util.SpongeInventoryUtil; -import com.plotsquared.sponge.util.SpongeSchematicHandler; -import com.plotsquared.sponge.util.SpongeSetupUtils; -import com.plotsquared.sponge.util.SpongeTaskManager; -import com.plotsquared.sponge.util.SpongeTitleManager; -import com.plotsquared.sponge.util.SpongeUtil; +import com.plotsquared.sponge.util.*; import com.plotsquared.sponge.util.block.SpongeLocalQueue; import com.plotsquared.sponge.uuid.SpongeLowerOfflineUUIDWrapper; import com.plotsquared.sponge.uuid.SpongeOnlineUUIDWrapper; import com.plotsquared.sponge.uuid.SpongeUUIDHandler; -import java.io.IOException; import net.minecrell.mcstats.SpongeStatsLite; import org.slf4j.Logger; import org.spongepowered.api.Game; @@ -76,7 +50,9 @@ import org.spongepowered.api.world.gen.GenerationPopulator; import org.spongepowered.api.world.gen.WorldGenerator; import org.spongepowered.api.world.gen.WorldGeneratorModifier; +import javax.annotation.Nonnull; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; @@ -243,6 +219,12 @@ public class SpongeMain implements IPlotMain { return new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), split.length == 3 ? Integer.parseInt(split[2]) : 0}; } + @Override + @Nonnull + public String getServerImplementation() { + return String.format("Sponge (MC %s)", this.game.getPlatform().getMinecraftVersion().getName()); + } + @Override public InventoryUtil initInventoryUtil() { return new SpongeInventoryUtil(); @@ -456,7 +438,7 @@ public class SpongeMain implements IPlotMain { @Override public List getPluginIds() { - return this.game.getPluginManager().getPlugins().stream().map(plugin1 -> plugin1.getName() + ';' + plugin1.getVersion() + ':' + true) + return this.game.getPluginManager().getPlugins().stream().map(plugin1 -> plugin1.getName() + ';' + plugin1.getVersion().orElse("unknown") + ':' + true) .collect(Collectors.toCollection(ArrayList::new)); }