diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index 70d5d1a9..d3343212 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -116,6 +116,21 @@ public class FaweBukkit implements IFawe, Listener { }); } + @Override + public int getPlayerCount() { + return plugin.getServer().getOnlinePlayers().size(); + } + + @Override + public boolean isOnlineMode() { + return Bukkit.getOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return Bukkit.getVersion(); + } + public void setupInjector() { Fawe.setupInjector(); // Inject diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index a972a1fe..36263e36 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -19,6 +19,7 @@ import com.boydti.fawe.util.Updater; import com.boydti.fawe.util.WEManager; import com.boydti.fawe.util.chat.ChatManager; import com.boydti.fawe.util.chat.PlainChatManager; +import com.boydti.fawe.util.metrics.BStats; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.worldedit.BlockVector; @@ -287,7 +288,18 @@ public class Fawe { TaskManager.IMP = this.IMP.getTaskManager(); if (Settings.IMP.METRICS) { - this.IMP.startMetrics(); + try { + this.IMP.startMetrics(); + TaskManager.IMP.task(new Runnable() { + @Override + public void run() { + // Run it when the plugin loads + BStats stats = new BStats(); + } + }); + } catch (Throwable ignore) { + ignore.printStackTrace(); + } } this.setupCommands(); /* diff --git a/core/src/main/java/com/boydti/fawe/IFawe.java b/core/src/main/java/com/boydti/fawe/IFawe.java index f1e3c839..f3eff835 100644 --- a/core/src/main/java/com/boydti/fawe/IFawe.java +++ b/core/src/main/java/com/boydti/fawe/IFawe.java @@ -33,6 +33,16 @@ public interface IFawe { public void startMetrics(); + + default int getPlayerCount() { + return Fawe.get().getCachedPlayers().size(); + } + + public String getPlatformVersion(); + + public boolean isOnlineMode(); + + public String getPlatform(); public UUID getUUID(String name); diff --git a/core/src/main/java/com/boydti/fawe/object/DataAngleMask.java b/core/src/main/java/com/boydti/fawe/object/DataAnglePattern.java similarity index 91% rename from core/src/main/java/com/boydti/fawe/object/DataAngleMask.java rename to core/src/main/java/com/boydti/fawe/object/DataAnglePattern.java index 4e30fe83..9003744b 100644 --- a/core/src/main/java/com/boydti/fawe/object/DataAngleMask.java +++ b/core/src/main/java/com/boydti/fawe/object/DataAnglePattern.java @@ -1,19 +1,20 @@ package com.boydti.fawe.object; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.extent.ExtentHeightCacher; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.pattern.AbstractPattern; -public class DataAngleMask extends AbstractPattern { +public class DataAnglePattern extends AbstractPattern { public final Extent extent; public final int maxY; public final double factor = 1d / 255; - public DataAngleMask(Extent extent) { - this.extent = extent; + public DataAnglePattern(Extent extent) { + this.extent = new ExtentHeightCacher(extent); this.maxY = extent.getMaximumPoint().getBlockY(); } diff --git a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java index 5b879ed7..c1f13f01 100644 --- a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java +++ b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java @@ -21,6 +21,8 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.extension.platform.Actor; @@ -542,6 +544,12 @@ public abstract class FawePlayer extends Metadatable { WorldEdit.getInstance().removeSession(toWorldEditPlayer()); session.setClipboard(null); session.clearHistory(); + for (Map.Entry entry : session.getTools().entrySet()) { + Tool tool = entry.getValue(); + if (tool instanceof BrushTool) { + ((BrushTool) tool).clear(getPlayer()); + } + } } Fawe.get().unregister(getName()); } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/SpikeBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/SpikeBrush.java new file mode 100644 index 00000000..00d7de6c --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/SpikeBrush.java @@ -0,0 +1,14 @@ +package com.boydti.fawe.object.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.command.tool.brush.Brush; +import com.sk89q.worldedit.function.pattern.Pattern; + +public class SpikeBrush implements Brush { + @Override + public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/extent/ExtentHeightCacher.java b/core/src/main/java/com/boydti/fawe/object/extent/ExtentHeightCacher.java new file mode 100644 index 00000000..4230773f --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/extent/ExtentHeightCacher.java @@ -0,0 +1,57 @@ +package com.boydti.fawe.object.extent; + +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.Extent; +import java.util.Arrays; + +public class ExtentHeightCacher extends AbstractDelegateExtent { + + public ExtentHeightCacher(Extent extent) { + super(extent); + } + + public void reset() { + cacheBotX = Integer.MIN_VALUE; + cacheBotZ = Integer.MIN_VALUE; + if (cacheHeights != null) { + Arrays.fill(cacheHeights, (byte) 0); + } + } + + private transient int cacheCenX; + private transient int cacheCenZ; + private transient int cacheBotX = Integer.MIN_VALUE; + private transient int cacheBotZ = Integer.MIN_VALUE; + private transient int cacheCenterZ; + private transient byte[] cacheHeights; + private transient int lastY; + private transient boolean foundY; + private transient boolean lastValue; + + @Override + public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) { + int rx = x - cacheBotX + 16; + int rz = z - cacheBotZ + 16; + int index; + if (((rx & 0xFF) != rx || (rz & 0xFF) != rz)) { + cacheBotX = x - 16; + cacheBotZ = z - 16; + lastY = y; + rx = x - cacheBotX + 16; + rz = z - cacheBotZ + 16; + index = rx + (rz << 8); + if (cacheHeights == null) { + cacheHeights = new byte[65536]; + } else { + Arrays.fill(cacheHeights, (byte) 0); + } + } else { + index = rx + (rz << 8); + } + int result = cacheHeights[index] & 0xFF; + if (result == 0) { + cacheHeights[index] = (byte) (result = lastY = super.getNearestSurfaceTerrainBlock(x, z, lastY, minY, maxY)); + } + return result; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java index 6d7933b4..49e7d2c9 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java @@ -2,7 +2,7 @@ package com.boydti.fawe.object.pattern; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.DataAngleMask; +import com.boydti.fawe.object.DataAnglePattern; import com.boydti.fawe.util.TextureUtil; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -10,7 +10,7 @@ import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.extent.Extent; import java.io.IOException; -public class AngleColorPattern extends DataAngleMask { +public class AngleColorPattern extends DataAnglePattern { private static final double FACTOR = 1d / 256; private transient TextureUtil util; @@ -51,7 +51,7 @@ public class AngleColorPattern extends DataAngleMask { int x = vector.getBlockX(); int y = vector.getBlockY(); int z = vector.getBlockZ(); - int height = extent.getNearestSurfaceTerrainBlock(x, y, z, 0, maxY); + int height = extent.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY); if (height > 0) { BaseBlock below = extent.getLazyBlock(x, height - 1, z); if (FaweCache.canPassThrough(block.getId(), block.getData())) { diff --git a/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java b/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java new file mode 100644 index 00000000..280fe5cb --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/util/metrics/BStats.java @@ -0,0 +1,380 @@ +package com.boydti.fawe.util.metrics; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.configuration.file.YamlConfiguration; +import com.boydti.fawe.object.io.PGZIPOutputStream; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.HttpsURLConnection; + +/** + * bStats collects some data for plugin authors. + * + * Check out https://bStats.org/ to learn more about bStats! + */ +public class BStats implements Closeable { + + // The version of this bStats class + public static final int B_STATS_VERSION = 1; + + // The url to which the data is sent + private final String url; + + // The plugin + private final String plugin; + private final String platform; + private final boolean online; + private final String serverVersion; + private final String pluginVersion; + private Thread task; + + // Is bStats enabled on this server? + private boolean enabled; + + // The uuid of the server + private UUID serverUUID; + + // Should failed requests be logged? + private boolean logFailedRequests = false; + + // A list with all known metrics class objects including this one + private static final List knownMetricsInstances = new ArrayList<>(); + + public BStats() { + this("FastAsyncWorldEdit", Fawe.get().getVersion().toString(), Fawe.imp().getPlatformVersion(), Fawe.imp().getPlatform(), Fawe.imp().isOnlineMode()); + } + + private BStats(String plugin, String pluginVersion, String serverVersion, String platform, boolean online) { + this.url = "https://bStats.org/submitData/" + platform; + this.plugin = plugin; + this.pluginVersion = pluginVersion; + this.serverVersion = serverVersion; + this.platform = platform; + this.online = online; + + StringBuilder data = new StringBuilder(); + + File configFile = new File(getJarFile().getParentFile(), "bStats" + File.separator + "config.yml"); + + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + + // Inform the server owners about bStats + config.options().header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" + ).copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { } + } + + // Load the data + serverUUID = UUID.fromString(config.getString("serverUuid")); + + Class usedMetricsClass = getFirstBStatsClass(); + if (usedMetricsClass == null) { + // Failed to get first metrics class + return; + } + if (usedMetricsClass == getClass()) { + // We are the first! :) + linkMetrics(this); + enabled = true; + startSubmitting(); + } else { + // We aren't the first so we link to the first metrics class + try { + usedMetricsClass.getMethod("linkMetrics", Object.class).invoke(null,this); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + if (logFailedRequests) { + System.out.println("Failed to link to first metrics class " + usedMetricsClass.getName() + "!"); + } + } + } + } + + /** + * Links an other metrics class with this class. + * This method is called using Reflection. + * + * @param metrics An object of the metrics class to link. + */ + public static void linkMetrics(Object metrics) { + knownMetricsInstances.add(metrics); + } + + /** + * Gets the plugin specific data. + * This method is called using Reflection. + * + * @return The plugin specific data. + */ + public JsonObject getPluginData() { + JsonObject data = new JsonObject(); + + data.addProperty("pluginName", plugin); + data.addProperty("pluginVersion", pluginVersion); + + JsonArray customCharts = new JsonArray(); + data.add("customCharts", customCharts); + + return data; + } + + private void startSubmitting() { + // No delay, as this class is only instantiated after the server is loaded + this.task = new Thread(new Runnable() { + @Override + public void run() { + while (enabled) { + submitData(); + try { + if (enabled) Thread.sleep(TimeUnit.MINUTES.toMillis(30)); + } catch (InterruptedException e) { + return; + } + } + } + }); + this.task.start(); + } + + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + @Override + public void close() { + enabled = false; + } + + /** + * Gets the server specific data. + * + * @return The server specific data. + */ + private JsonObject getServerData() { + int playerAmount = Fawe.imp() != null ? Fawe.imp().getPlayerCount() : 1; + int onlineMode = online ? 1 : 0; + + int managedServers = 1; + + // OS/Java specific data + String javaVersion = System.getProperty("java.version"); + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + JsonObject data = new JsonObject(); + + data.addProperty("serverUUID", serverUUID.toString()); + + data.addProperty("playerAmount", playerAmount); + data.addProperty("managedServers", managedServers); + data.addProperty("onlineMode", onlineMode); + data.addProperty(platform + "Version", serverVersion); + + data.addProperty("javaVersion", javaVersion); + data.addProperty("osName", osName); + data.addProperty("osArch", osArch); + data.addProperty("osVersion", osVersion); + data.addProperty("coreCount", coreCount); + + return data; + } + + /** + * Collects the data and sends it afterwards. + */ + private void submitData() { + final JsonObject data = getServerData(); + + final JsonArray pluginData = new JsonArray(); + // Search for all other bStats Metrics classes to get their plugin data + for (Object metrics : knownMetricsInstances) { + try { + Object plugin = metrics.getClass().getMethod("getPluginData").invoke(metrics); + if (plugin instanceof JsonObject) { + pluginData.add((JsonObject) plugin); + } + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } + } + + data.add("plugins", pluginData); + + try { + // Send the data + sendData(data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + System.err.println("Could not submit plugin stats!"); + } + } + } + + /** + * Gets the first bStat Metrics class. + * + * @return The first bStats metrics class. + */ + private Class getFirstBStatsClass() { + Path configPath = getJarFile().toPath().getParent().resolve("bStats"); + configPath.toFile().mkdirs(); + File tempFile = new File(configPath.toFile(), "temp.txt"); + + try { + String className = readFile(tempFile); + if (className != null) { + try { + // Let's check if a class with the given name exists. + return Class.forName(className); + } catch (ClassNotFoundException ignored) { } + } + writeFile(tempFile, getClass().getName()); + return getClass(); + } catch (IOException e) { + if (logFailedRequests) { + System.err.println("Failed to get first bStats class!"); + } + return null; + } + } + + private File getJarFile() { + try { + URL url = BStats.class.getProtectionDomain().getCodeSource().getLocation(); + return new File(new URL(url.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")).toURI().getPath()); + } catch (MalformedURLException | URISyntaxException | SecurityException e) { + return new File(".", "plugins"); + } + } + + /** + * Reads the first line of the file. + * + * @param file The file to read. Cannot be null. + * @return The first line of the file or null if the file does not exist or is empty. + * @throws IOException If something did not work :( + */ + private String readFile(File file) throws IOException { + if (!file.exists()) { + return null; + } + try ( + FileReader fileReader = new FileReader(file); + BufferedReader bufferedReader = new BufferedReader(fileReader); + ) { + return bufferedReader.readLine(); + } + } + + /** + * Writes a String to a file. It also adds a note for the user, + * + * @param file The file to write to. Cannot be null. + * @param lines The lines to write. + * @throws IOException If something did not work :( + */ + private void writeFile(File file, String... lines) throws IOException { + if (!file.exists()) { + file.createNewFile(); + } + try ( + FileWriter fileWriter = new FileWriter(file); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter) + ) { + for (String line : lines) { + bufferedWriter.write(line); + bufferedWriter.newLine(); + } + } + } + + /** + * Sends the data to the bStats server. + * + * @param data The data to send. + * @throws Exception If the request failed. + */ + private void sendData(JsonObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null"); + } + + HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); + outputStream.write(compressedData); + outputStream.flush(); + outputStream.close(); + + connection.getInputStream().close(); // We don't care about the response - Just send our data :) + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * @return The gzipped String. + * @throws IOException If the compression failed. + */ + private byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PGZIPOutputStream gzip = new PGZIPOutputStream(outputStream); + gzip.write(str.getBytes("UTF-8")); + gzip.close(); + return outputStream.toByteArray(); + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 20c6114c..1f6b446c 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -577,6 +577,10 @@ public class LocalSession { return null; } + public Map getTools() { + return Collections.unmodifiableMap(tools); + } + public int getSize() { return history.size(); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java index 827c9948..ce9a2881 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java @@ -1,7 +1,7 @@ package com.sk89q.worldedit.command; import com.boydti.fawe.Fawe; -import com.boydti.fawe.object.DataAngleMask; +import com.boydti.fawe.object.DataAnglePattern; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.collection.RandomCollection; import com.boydti.fawe.object.pattern.AngleColorPattern; @@ -135,7 +135,7 @@ public class PatternCommands extends MethodCommands { desc = "Block data based on the existing terrain angle" ) public Pattern angledata(Extent extent) { - return new DataAngleMask(extent); + return new DataAnglePattern(extent); } @Command( diff --git a/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java index 436edf76..4f16d888 100644 --- a/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -61,6 +61,21 @@ public class FaweForge implements IFawe { logger.debug(s); } + @Override + public boolean isOnlineMode() { + return FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java index 7b50b168..05504267 100644 --- a/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -61,6 +61,21 @@ public class FaweForge implements IFawe { logger.debug(s); } + @Override + public boolean isOnlineMode() { + return FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/forge112/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge112/src/main/java/com/boydti/fawe/forge/FaweForge.java index 17373345..12c5f268 100644 --- a/forge112/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge112/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -61,6 +61,21 @@ public class FaweForge implements IFawe { logger.debug(s); } + @Override + public boolean isOnlineMode() { + return FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java index f6919768..4d9d22f3 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -65,6 +65,21 @@ public class FaweForge implements IFawe { logger.error(s); } + @Override + public boolean isOnlineMode() { + return MinecraftServer.getServer().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return MinecraftServer.getServer().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return MinecraftServer.getServer().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java index 1e8911f8..7843329a 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -65,6 +65,21 @@ public class FaweForge implements IFawe { logger.debug(s); } + @Override + public boolean isOnlineMode() { + return MinecraftServer.getServer().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return MinecraftServer.getServer().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return MinecraftServer.getServer().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java index 745a8e2b..f8e09450 100644 --- a/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -63,6 +63,21 @@ public class FaweForge implements IFawe { logger.debug(s); } + @Override + public boolean isOnlineMode() { + return FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion(); + } + + @Override + public int getPlayerCount() { + return FMLCommonHandler.instance().getMinecraftServerInstance().getCurrentPlayerCount(); + } + @Override public File getDirectory() { return directory; diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/FaweNukkit.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/FaweNukkit.java index feeb9a97..da5b6db9 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/FaweNukkit.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/FaweNukkit.java @@ -1,5 +1,6 @@ package com.boydti.fawe.nukkit.optimization; +import cn.nukkit.Nukkit; import cn.nukkit.Player; import cn.nukkit.event.EventHandler; import cn.nukkit.event.Listener; @@ -43,6 +44,21 @@ public class FaweNukkit implements IFawe, Listener { } } + @Override + public int getPlayerCount() { + return plugin.getServer().getOnlinePlayers().size(); + } + + @Override + public boolean isOnlineMode() { + return false; + } + + @Override + public String getPlatformVersion() { + return Nukkit.VERSION; + } + @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java index 6882dca9..a8ba5318 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java @@ -50,6 +50,21 @@ public class FaweSponge implements IFawe { Sponge.getServer().getConsole().sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(message))); } + @Override + public boolean isOnlineMode() { + return Sponge.getServer().getOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return Sponge.getPlatform().getMinecraftVersion().getName(); + } + + @Override + public int getPlayerCount() { + return Sponge.getServer().getOnlinePlayers().size(); + } + @Override public File getDirectory() { return new File("config/FastAsyncWorldEdit"); diff --git a/sponge111/src/main/java/com/boydti/fawe/sponge/FaweSponge.java b/sponge111/src/main/java/com/boydti/fawe/sponge/FaweSponge.java index 161bfe5c..1a14f191 100644 --- a/sponge111/src/main/java/com/boydti/fawe/sponge/FaweSponge.java +++ b/sponge111/src/main/java/com/boydti/fawe/sponge/FaweSponge.java @@ -50,6 +50,21 @@ public class FaweSponge implements IFawe { Sponge.getServer().getConsole().sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(message))); } + @Override + public boolean isOnlineMode() { + return Sponge.getServer().getOnlineMode(); + } + + @Override + public String getPlatformVersion() { + return Sponge.getPlatform().getMinecraftVersion().getName(); + } + + @Override + public int getPlayerCount() { + return Sponge.getServer().getOnlinePlayers().size(); + } + @Override public File getDirectory() { return new File("config/FastAsyncWorldEdit");