diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index e2277992..e1b896c9 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -244,44 +244,44 @@ public class Fawe { this.timer = new FaweTimer(); Fawe.this.IMP.setupVault(); - // Delayed worldedit setup - TaskManager.IMP.later(new Runnable() { - @Override - public void run() { + File jar = MainUtil.getJarFile(); + File extraBlocks = MainUtil.copyFile(jar, "extrablocks.json", null); + if (extraBlocks != null && extraBlocks.exists()) { + TaskManager.IMP.task(() -> { try { - transformParser = new DefaultTransformParser(getWorldEdit()); - visualQueue = new VisualQueue(); - WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers()); - WEManager.IMP.managers.add(new PlotSquaredFeature()); - Fawe.debug("Plugin 'PlotSquared' found. Using it now."); - } catch (Throwable e) { + BundledBlockData.getInstance().loadFromResource(); + BundledBlockData.getInstance().add(extraBlocks.toURI().toURL(), true); + } catch (Throwable ignore) { + ignore.printStackTrace(); + Fawe.debug("Invalid format: extrablocks.json"); } - } + }); + } + + // Delayed worldedit setup + TaskManager.IMP.later(() -> { + try { + transformParser = new DefaultTransformParser(getWorldEdit()); + visualQueue = new VisualQueue(); + WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers()); + WEManager.IMP.managers.add(new PlotSquaredFeature()); + Fawe.debug("Plugin 'PlotSquared' found. Using it now."); + } catch (Throwable e) {} }, 0); TaskManager.IMP.repeat(timer, 1); - if (Settings.IMP.UPDATE) { - // Delayed updating - updater = new Updater(); - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - update(); - } - }); - TaskManager.IMP.repeatAsync(new Runnable() { - @Override - public void run() { - update(); - } - }, 36000); - } +// if (Settings.IMP.UPDATE) { + // Delayed updating + updater = new Updater(); + TaskManager.IMP.async(() -> update()); + TaskManager.IMP.repeatAsync(() -> update(), 36000); +// } } private boolean update() { if (updater != null) { - updater.update(IMP.getPlatform(), getVersion()); + updater.getUpdate(IMP.getPlatform(), getVersion()); return true; } return false; @@ -582,16 +582,6 @@ public class Fawe { // BlockData BlockData.inject(); // Temporary fix for 1.9.4 BundledBlockData.inject(); // Add custom rotation - File jar = MainUtil.getJarFile(); - File extraBlocks = MainUtil.copyFile(jar, "extrablocks.json", null); - if (extraBlocks != null && extraBlocks.exists()) { - try { - BundledBlockData.getInstance().loadFromResource(); - BundledBlockData.getInstance().add(extraBlocks.toURI().toURL(), true); - } catch (Throwable ignore) { - Fawe.debug("Invalid format: extrablocks.json"); - } - } // NBT NBTInputStream.inject(); // Add actual streaming + Optimizations + New methods NBTOutputStream.inject(); // New methods @@ -739,6 +729,7 @@ public class Fawe { public void register(FawePlayer player) { players.put(player.getName(), player); playersUUID.put(player.getUUID(), player); + } public void unregister(String name) { diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index b0fd09bd..c2b1a567 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -26,8 +26,8 @@ public class Settings extends Config { @Comment({"Options: de, ru, tr", "Create a PR to contribute a translation: https://github.com/boy0001/FastAsyncWorldedit/new/master/core/src/main/resources",}) public String LANGUAGE = ""; - @Comment("Allow the plugin to update") - public boolean UPDATE = true; + @Comment("Enable or disable automatic updates") + public boolean UPDATE = false; @Comment("Send anonymous usage statistics") public boolean METRICS = true; @Comment("FAWE will skip chunks when there's not enough memory available") 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 d22a282f..06346627 100644 --- a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java +++ b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java @@ -121,6 +121,10 @@ public abstract class FawePlayer extends Metadatable { if (Settings.IMP.CLIPBOARD.USE_DISK) { loadClipboardFromDisk(); } + Updater updater = Fawe.get().getUpdater(); + if (updater != null && updater.hasPending(this)) { + TaskManager.IMP.async(() -> updater.confirmUpdate(this)); + } } public void checkConfirmation(String command, int times, int limit) throws RegionOperationException { diff --git a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java index 3a0e5742..85cc64db 100644 --- a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java +++ b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java @@ -17,11 +17,12 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { private final double min; private final boolean overlay; private final boolean checkFirst; - private int maxY; + private final int maxY; + private final int distance; private transient MutableBlockVector mutable = new MutableBlockVector(); - public AngleMask(Extent extent, double min, double max, boolean overlay) { + public AngleMask(Extent extent, double min, double max, boolean overlay, int distance) { super(extent); this.mask = new CachedMask(new SolidBlockMask(extent)); this.min = min; @@ -29,6 +30,7 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { this.checkFirst = max >= (Math.tan(90 * (Math.PI / 180))); this.maxY = extent.getMaximumPoint().getBlockY(); this.overlay = overlay; + this.distance = distance; } @Override @@ -93,19 +95,19 @@ public class AngleMask extends SolidBlockMask implements ResettableMask { double slope; boolean aboveMin; lastY = y; - slope = Math.abs(getHeight(x + 1, y, z) - getHeight(x - 1, y, z)) * ADJACENT_MOD; + slope = Math.abs(getHeight(x + distance, y, z) - getHeight(x -distance, y, z)) * ADJACENT_MOD; if (checkFirst) { if (slope >= min) { return lastValue = true; } - slope = Math.max(slope, Math.abs(getHeight(x, y, z + 1) - getHeight(x, y, z - 1)) * ADJACENT_MOD); - slope = Math.max(slope, Math.abs(getHeight(x + 1, y, z + 1) - getHeight(x - 1, y, z - 1)) * DIAGONAL_MOD); - slope = Math.max(slope, Math.abs(getHeight(x - 1, y, z + 1) - getHeight(x + 1, y, z - 1)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x, y, z + distance) - getHeight(x, y, z - distance)) * ADJACENT_MOD); + slope = Math.max(slope, Math.abs(getHeight(x + distance, y, z + distance) - getHeight(x - distance, y, z - distance)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x - distance, y, z + distance) - getHeight(x + distance, y, z - distance)) * DIAGONAL_MOD); return lastValue = (slope >= min); } else { - slope = Math.max(slope, Math.abs(getHeight(x, y, z + 1) - getHeight(x, y, z - 1)) * ADJACENT_MOD); - slope = Math.max(slope, Math.abs(getHeight(x + 1, y, z + 1) - getHeight(x - 1, y, z - 1)) * DIAGONAL_MOD); - slope = Math.max(slope, Math.abs(getHeight(x - 1, y, z + 1) - getHeight(x + 1, y, z - 1)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x, y, z + distance) - getHeight(x, y, z - distance)) * ADJACENT_MOD); + slope = Math.max(slope, Math.abs(getHeight(x + distance, y, z + distance) - getHeight(x - distance, y, z - distance)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(getHeight(x - distance, y, z + distance) - getHeight(x + distance, y, z - distance)) * DIAGONAL_MOD); return lastValue = (slope >= min && slope <= max); } } diff --git a/core/src/main/java/com/boydti/fawe/util/TextureUtil.java b/core/src/main/java/com/boydti/fawe/util/TextureUtil.java index e1b490de..8664a251 100644 --- a/core/src/main/java/com/boydti/fawe/util/TextureUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/TextureUtil.java @@ -14,7 +14,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.longs.LongArrayList; -import java.awt.Color; import java.awt.image.BufferedImage; import java.io.*; import java.lang.reflect.Type; @@ -618,11 +617,6 @@ public class TextureUtil { } idMap.putIfAbsent(combined, texture); } - - - if (block.getId() == 100) { - System.out.println(100 + "Texture " + texture + " | " + id + " | " + block); - } } } { // Calculate the colors for each block diff --git a/core/src/main/java/com/boydti/fawe/util/Updater.java b/core/src/main/java/com/boydti/fawe/util/Updater.java index 4f05cbb1..1f7e8565 100644 --- a/core/src/main/java/com/boydti/fawe/util/Updater.java +++ b/core/src/main/java/com/boydti/fawe/util/Updater.java @@ -2,6 +2,9 @@ package com.boydti.fawe.util; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweVersion; +import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.util.chat.Message; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -14,7 +17,11 @@ public class Updater { private FaweVersion newVersion; private String changes; - public String getChanges() { + private volatile boolean pending; + private File pendingFile, destFile; + private String versionString; + + public synchronized String getChanges() { if (changes == null) { try (Scanner scanner = new Scanner(new URL("https://empcraft.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash)).openStream(), "UTF-8")) { changes = scanner.useDelimiter("\\A").next(); @@ -26,11 +33,43 @@ public class Updater { return changes; } - public boolean isOutdated() { + public synchronized boolean isOutdated() { return newVersion != null; } - public void update(String platform, FaweVersion currentVersion) { + public boolean hasPending(FawePlayer fp) { + return (pending && fp.hasPermission("fawe.admin")); + } + + public synchronized void confirmUpdate(FawePlayer fp) { + if (pending && fp.hasPermission("fawe.admin")) { + Fawe.debug("Updated FAWE to " + versionString + " @ " + pendingFile); + String url = "https://empcraft.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash); + new Message().prefix().text("A FAWE update is available:") + .text("\n&8 - &a/fawe update &8 - &7Update the plugin") + .cmdTip("fawe update") + .text("\n&8 - &a/fawe changelog") + .cmdTip("fawe changelog") + .text("&8 - &7( &9&o" + url + " &7)") + .link(url) + .send(fp); + } + } + + public synchronized boolean installUpdate(FawePlayer fp) { + if (pending && (fp == null || fp.hasPermission("fawe.admin")) && pendingFile.exists()) { + pending = false; + File outFileParent = destFile.getParentFile(); + if (!outFileParent.exists()) { + outFileParent.mkdirs(); + } + pendingFile.renameTo(destFile); + return true; + } + return false; + } + + public synchronized void getUpdate(String platform, FaweVersion currentVersion) { if (currentVersion == null || platform == null) { return; } @@ -39,7 +78,7 @@ public class Updater { String versionUrl = "https://empcraft.com/fawe/version.php?%platform%"; URL url = new URL(versionUrl.replace("%platform%", platform)); try (Scanner reader = new Scanner(url.openStream())) { - String versionString = reader.next(); + this.versionString = reader.next(); FaweVersion version = new FaweVersion(versionString); if (version.isNewer(newVersion != null ? newVersion : currentVersion)) { newVersion = version; @@ -47,8 +86,8 @@ public class Updater { try (ReadableByteChannel rbc = Channels.newChannel(download.openStream())) { File jarFile = MainUtil.getJarFile(); - File finalFile = new File(jarFile.getParent(), "update" + File.separator + jarFile.getName()); - File outFile = new File(jarFile.getParent(), "update" + File.separator + jarFile.getName().replace(".jar", ".part")); + File finalFile = new File(jarFile.getParent(), "update-confirm" + File.separator + jarFile.getName()); + File outFile = new File(jarFile.getParent(), "update-confirm" + File.separator + jarFile.getName().replace(".jar", ".part")); boolean exists = outFile.exists(); if (exists) { outFile.delete(); @@ -62,8 +101,20 @@ public class Updater { fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); } outFile.renameTo(finalFile); - Fawe.debug("Updated FAWE to " + versionString); - MainUtil.sendAdmin("&7Restart to update FAWE with these changes: &c/fawe changelog &7or&c " + "https://empcraft.com/fawe/cl?" + Integer.toHexString(currentVersion.hash)); + + if (Settings.IMP.UPDATE) { + installUpdate(null); + Fawe.debug("Updated FAWE to " + versionString + " @ " + pendingFile); + MainUtil.sendAdmin("&a/restart&7 to update FAWE with these changes: &c/fawe changelog &7or&c " + "https://empcraft.com/fawe/cl?" + Integer.toHexString(currentVersion.hash)); + } else { + pendingFile = finalFile; + destFile = new File(jarFile.getParent(), "update" + File.separator + jarFile.getName()); + pending = true; + + for (final FawePlayer player : Fawe.get().getCachedPlayers()) { + confirmUpdate(player); + } + } } } } diff --git a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java index 40d551b5..f6af4597 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java @@ -268,7 +268,7 @@ public class MaskCommands extends MethodCommands { min = 2, max = 2 ) - public Mask angle(Extent extent, String min, String max, @Switch('o') boolean overlay) throws ExpressionException { + public Mask angle(Extent extent, String min, String max, @Switch('o') boolean overlay, @Optional("1") int distance) throws ExpressionException { double y1, y2; boolean override; if (max.endsWith("d")) { @@ -280,7 +280,7 @@ public class MaskCommands extends MethodCommands { y1 = (Expression.compile(min).evaluate()); y2 = (Expression.compile(max).evaluate()); } - return new AngleMask(extent, y1, y2, overlay); + return new AngleMask(extent, y1, y2, overlay, distance); } @Command( diff --git a/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index 0b2252f6..819a2df0 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -23,7 +23,10 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweVersion; import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.util.HastebinUtility; +import com.boydti.fawe.util.StringMan; +import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.Updater; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; @@ -41,12 +44,7 @@ import java.io.IOException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Map; -import java.util.Scanner; -import java.util.TimeZone; +import java.util.*; @Command(aliases = {"worldedit", "we", "fawe"}, desc = "Updating, informational, debug and help commands") public class WorldEditCommands { @@ -118,6 +116,25 @@ public class WorldEditCommands { actor.print(BBC.getPrefix() + "Reloaded WorldEdit " + we.getVersion() + " and FAWE (" + Fawe.get().getVersion() + ")"); } + @Command( + aliases = {"update"}, + usage = "", + desc = "Update the plugin", + min = 0, + max = 0 + ) + public void update(FawePlayer fp) throws WorldEditException { + if (Fawe.get().getUpdater().installUpdate(fp)) { + TaskManager.IMP.sync(() -> { + fp.executeCommand("restart"); + return null; + }); + fp.sendMessage(BBC.getPrefix() + "Please restart to finish installing the update"); + } else { + fp.sendMessage(BBC.getPrefix() + "No update is pending"); + } + } + @Command( aliases = {"changelog", "cl"}, usage = "", @@ -130,13 +147,36 @@ public class WorldEditCommands { try { Updater updater = Fawe.get().getUpdater(); String changes = updater != null ? updater.getChanges() : null; + + String url = "https://empcraft.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash); if (changes == null) { - try (Scanner scanner = new Scanner(new URL("https://empcraft.com/fawe/cl?" + Integer.toHexString(Fawe.get().getVersion().hash)).openStream(), "UTF-8")) { + try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) { changes = scanner.useDelimiter("\\A").next(); } } changes = changes.replaceAll("#([0-9]+)", "github.com/boy0001/FastAsyncWorldedit/issues/$1"); - actor.print(BBC.getPrefix() + changes); + + String[] split = changes.substring(1).split("[\n](?! )"); + if (changes.length() <= 1) actor.print(BBC.getPrefix() + "No description available"); + else { + StringBuilder msg = new StringBuilder(); + msg.append(BBC.getPrefix() + split.length + " commits:"); + for (String change : split) { + String[] split2 = change.split("\n "); + msg.append("\n&a&l" + split2[0]); + if (split2.length != 0) { + for (int i = 1; i < split2.length; i++) { + msg.append('\n'); + String[] split3 = split2[i].split("\n"); + String subChange = "&8 - &7" + StringMan.join(split3, "\n&7 "); + msg.append(subChange); + } + } + } + msg.append("\n&7More info: &9&o" + url); + msg.append("\n&7Discuss: &9&ohttps://discord.gg/ngZCzbU"); + actor.print(BBC.color(msg.toString())); + } } catch (IOException e) { throw new RuntimeException(e); }