diff --git a/.gitignore b/.gitignore index 3dcdaadb..87562d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ gradle.log /forge1710/build /sponge/build /sponge111/build +/nukkit/out +/sponge112/build +/core/out /bukkit/build /bukkit0/build /bukkit19/build @@ -30,4 +33,5 @@ spigot-1.10 wiki_permissions.md /textures *.iml -/obj \ No newline at end of file +/obj +*.jar \ No newline at end of file diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 5fa673b0..992cd1d5 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -3,6 +3,7 @@ repositories { } dependencies { compile project(':core') + compile 'com.sk89q:worldguard:6.0.0-SNAPSHOT' compile('com.destroystokyo.paper:paper-api:1.12-R0.1-SNAPSHOT') { exclude group: 'net.md-5' } @@ -30,6 +31,7 @@ dependencies { compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8' compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT' compile 'com.wasteofplastic:askyblock:3.0.8.2' + compile 'org.inventivetalent:mapmanager:1.4.0-SNAPSHOT' } processResources { 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 7c6ec503..598286a1 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -17,6 +17,7 @@ import com.boydti.fawe.bukkit.regions.PreciousStonesFeature; import com.boydti.fawe.bukkit.regions.ResidenceFeature; import com.boydti.fawe.bukkit.regions.TownyFeature; import com.boydti.fawe.bukkit.regions.Worldguard; +import com.boydti.fawe.bukkit.util.BukkitReflectionUtils; import com.boydti.fawe.bukkit.util.BukkitTaskMan; import com.boydti.fawe.bukkit.util.ItemUtil; import com.boydti.fawe.bukkit.util.VaultUtil; @@ -374,7 +375,7 @@ public class FaweBukkit implements IFawe, Listener { public FaweQueue getNewQueue(String world, boolean fast) { if (playerChunk != (playerChunk = true)) { try { - Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField(); + Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField(); fieldDirtyCount.setAccessible(true); int mod = fieldDirtyCount.getModifiers(); if ((mod & Modifier.VOLATILE) == 0) { @@ -427,7 +428,7 @@ public class FaweBukkit implements IFawe, Listener { if (fast) { if (playerChunk != (playerChunk = true)) { try { - Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField(); + Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField(); fieldDirtyCount.setAccessible(true); int mod = fieldDirtyCount.getModifiers(); if ((mod & Modifier.VOLATILE) == 0) { diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/util/BukkitReflectionUtils.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/util/BukkitReflectionUtils.java new file mode 100644 index 00000000..1079f8c2 --- /dev/null +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/util/BukkitReflectionUtils.java @@ -0,0 +1,109 @@ +package com.boydti.fawe.bukkit.util; + +import com.boydti.fawe.util.MainUtil; +import com.boydti.fawe.util.ReflectionUtils; +import java.lang.reflect.Method; +import org.bukkit.Bukkit; +import org.bukkit.Server; + +public class BukkitReflectionUtils { + /** + * prefix of bukkit classes + */ + private static volatile String preClassB = null; + /** + * prefix of minecraft classes + */ + private static volatile String preClassM = null; + /** + * boolean value, TRUE if server uses forge or MCPC+ + */ + private static boolean forge = false; + + /** + * check server version and class names + */ + public static void init() { + if (Bukkit.getServer() != null) { + if (Bukkit.getVersion().contains("MCPC") || Bukkit.getVersion().contains("Forge")) { + forge = true; + } + final Server server = Bukkit.getServer(); + final Class bukkitServerClass = server.getClass(); + String[] pas = bukkitServerClass.getName().split("\\."); + if (pas.length == 5) { + final String verB = pas[3]; + preClassB = "org.bukkit.craftbukkit." + verB; + } + try { + final Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle"); + final Object handle = getHandle.invoke(server); + final Class handleServerClass = handle.getClass(); + pas = handleServerClass.getName().split("\\."); + if (pas.length == 5) { + final String verM = pas[3]; + preClassM = "net.minecraft.server." + verM; + } + } catch (final Exception ignored) { + MainUtil.handleError(ignored); + } + } + } + + + /** + * @return true if server has forge classes + */ + public static boolean isForge() { + return forge; + } + + /** + * Get class for name. Replace {nms} to net.minecraft.server.V*. Replace {cb} to org.bukkit.craftbukkit.V*. Replace + * {nm} to net.minecraft + * + * @param classes possible class paths + * @return RefClass object + * @throws RuntimeException if no class found + */ + public static ReflectionUtils.RefClass getRefClass(final String... classes) throws RuntimeException { + if (preClassM == null) { + init(); + } + for (String className : classes) { + try { + className = className.replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft"); + return ReflectionUtils.getRefClass(Class.forName(className)); + } catch (final ClassNotFoundException ignored) { + } + } + throw new RuntimeException("no class found: " + classes[0].replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft")); + } + + public static Class getNmsClass(final String name) { + final String className = "net.minecraft.server." + getVersion() + "." + name; + return ReflectionUtils.getClass(className); + } + + public static Class getCbClass(final String name) { + final String className = "org.bukkit.craftbukkit." + getVersion() + "." + name; + return ReflectionUtils.getClass(className); + } + + public static Class getUtilClass(final String name) { + try { + return Class.forName(name); //Try before 1.8 first + } catch (final ClassNotFoundException ex) { + try { + return Class.forName("net.minecraft.util." + name); //Not 1.8 + } catch (final ClassNotFoundException ex2) { + return null; + } + } + } + + public static String getVersion() { + final String packageName = Bukkit.getServer().getClass().getPackage().getName(); + return packageName.substring(packageName.lastIndexOf('.') + 1); + } +} diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/util/ItemUtil.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/util/ItemUtil.java index ea146ed5..beccd4e5 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/util/ItemUtil.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/util/ItemUtil.java @@ -25,13 +25,13 @@ public class ItemUtil { private SoftReference>> hashToNMSTag = new SoftReference(new Int2ObjectOpenHashMap<>()); public ItemUtil() throws Exception { - this.classCraftItemStack = ReflectionUtils.getCbClass("inventory.CraftItemStack"); - this.classNMSItem = ReflectionUtils.getNmsClass("ItemStack"); + this.classCraftItemStack = BukkitReflectionUtils.getCbClass("inventory.CraftItemStack"); + this.classNMSItem = BukkitReflectionUtils.getNmsClass("ItemStack"); this.methodAsNMSCopy = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class)); this.methodHasTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("hasTag")); this.methodGetTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("getTag")); this.fieldHandle = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredField("handle")); - Class classNBTTagCompound = ReflectionUtils.getNmsClass("NBTTagCompound"); + Class classNBTTagCompound = BukkitReflectionUtils.getNmsClass("NBTTagCompound"); this.methodSetTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("setTag", classNBTTagCompound)); this.methodAsBukkitCopy = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredMethod("asBukkitCopy", classNMSItem)); } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java index 223f95a3..bf43caf8 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java @@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.bukkit.BukkitPlayer; import com.boydti.fawe.bukkit.FaweBukkit; +import com.boydti.fawe.bukkit.util.BukkitReflectionUtils; import com.boydti.fawe.bukkit.v1_12.packet.FaweChunkPacket; import com.boydti.fawe.bukkit.v1_12.packet.MCAChunkPacket; import com.boydti.fawe.example.CharFaweChunk; @@ -36,7 +37,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Bukkit; import org.bukkit.Chunk; -import org.bukkit.ChunkSnapshot; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; @@ -59,7 +59,7 @@ public abstract class BukkitQueue_0 extends NMSMa private static Method methodGetHandle; static { - Class classCraftChunk = ReflectionUtils.getCbClass("CraftChunk"); + Class classCraftChunk = BukkitReflectionUtils.getCbClass("CraftChunk"); try { methodGetHandle = ReflectionUtils.setAccessible(classCraftChunk.getDeclaredMethod("getHandle")); } catch (NoSuchMethodException e) { @@ -221,6 +221,11 @@ public abstract class BukkitQueue_0 extends NMSMa return false; } + @Override + public boolean removeSectionLighting(SECTION sections, int layer, boolean hasSky) { + return false; + } + public static void checkVersion(String supported) { String version = Bukkit.getServer().getClass().getPackage().getName(); if (!version.contains(supported)) { diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java index be5c57bf..303f2452 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java @@ -1,6 +1,7 @@ package com.boydti.fawe.bukkit.v0; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.bukkit.util.BukkitReflectionUtils; import com.boydti.fawe.config.Settings; import com.boydti.fawe.example.NullRelighter; import com.boydti.fawe.example.Relighter; @@ -101,17 +102,17 @@ public class BukkitQueue_All extends BukkitQueue_0, Integer> TagToId = new ConcurrentHashMap<>(); public FaweAdapter_All() throws Throwable { - ReflectionUtils.init(); - classCraftWorld = ReflectionUtils.getCbClass("CraftWorld"); - classCraftBlock = ReflectionUtils.getCbClass("block.CraftBlock"); - classCraftEntity = ReflectionUtils.getCbClass("entity.CraftEntity"); - classBiomeBase = ReflectionUtils.getNmsClass("BiomeBase"); - classWorld = ReflectionUtils.getNmsClass("World"); - classTileEntity = ReflectionUtils.getNmsClass("TileEntity"); + BukkitReflectionUtils.init(); + classCraftWorld = BukkitReflectionUtils.getCbClass("CraftWorld"); + classCraftBlock = BukkitReflectionUtils.getCbClass("block.CraftBlock"); + classCraftEntity = BukkitReflectionUtils.getCbClass("entity.CraftEntity"); + classBiomeBase = BukkitReflectionUtils.getNmsClass("BiomeBase"); + classWorld = BukkitReflectionUtils.getNmsClass("World"); + classTileEntity = BukkitReflectionUtils.getNmsClass("TileEntity"); biomeToBiomeBase = ReflectionUtils.setAccessible(classCraftBlock.getDeclaredMethod("biomeToBiomeBase", Biome.class)); biomeBaseToBiome = ReflectionUtils.setAccessible(classCraftBlock.getDeclaredMethod("biomeBaseToBiome", classBiomeBase)); @@ -97,7 +98,7 @@ public class FaweAdapter_All implements BukkitImplAdapter { getHandleWorld = ReflectionUtils.setAccessible(classCraftWorld.getDeclaredMethod("getHandle")); getHandleEntity = ReflectionUtils.setAccessible(classCraftEntity.getDeclaredMethod("getHandle")); try { - classBlockPosition = ReflectionUtils.getNmsClass("BlockPosition"); + classBlockPosition = BukkitReflectionUtils.getNmsClass("BlockPosition"); } catch (Throwable ignore) { } if (classBlockPosition != null) { @@ -109,9 +110,9 @@ public class FaweAdapter_All implements BukkitImplAdapter { getTileEntity2 = ReflectionUtils.setAccessible(classWorld.getDeclaredMethod("getTileEntity", int.class, int.class, int.class)); } - classNBTTagCompound = ReflectionUtils.getNmsClass("NBTTagCompound"); - classNBTBase = ReflectionUtils.getNmsClass("NBTBase"); - classNBTTagInt = ReflectionUtils.getNmsClass("NBTTagInt"); + classNBTTagCompound = BukkitReflectionUtils.getNmsClass("NBTTagCompound"); + classNBTBase = BukkitReflectionUtils.getNmsClass("NBTBase"); + classNBTTagInt = BukkitReflectionUtils.getNmsClass("NBTTagInt"); newNBTTagInt = ReflectionUtils.setAccessible(classNBTTagInt.getConstructor(int.class)); setNBTTagCompound = ReflectionUtils.setAccessible(classNBTTagCompound.getDeclaredMethod("set", String.class, classNBTBase)); newNBTTagCompound = ReflectionUtils.setAccessible(classNBTTagCompound.getConstructor()); @@ -139,7 +140,7 @@ public class FaweAdapter_All implements BukkitImplAdapter { int noMods = Modifier.STATIC; int hasMods = 0; for (int i = 0; i < nmsClasses.size(); i++) { - Class nmsClass = ReflectionUtils.getNmsClass(nmsClasses.get(i)); + Class nmsClass = BukkitReflectionUtils.getNmsClass(nmsClasses.get(i)); Class weClass = weClasses.get(i); TagToId.put(weClass, ids[i]); @@ -217,15 +218,15 @@ public class FaweAdapter_All implements BukkitImplAdapter { } } try { - classEntity = ReflectionUtils.getNmsClass("Entity"); - classEntityTypes = ReflectionUtils.getNmsClass("EntityTypes"); + classEntity = BukkitReflectionUtils.getNmsClass("Entity"); + classEntityTypes = BukkitReflectionUtils.getNmsClass("EntityTypes"); getBukkitEntity = ReflectionUtils.setAccessible(classEntity.getDeclaredMethod("getBukkitEntity")); addEntity = ReflectionUtils.setAccessible(classWorld.getDeclaredMethod("addEntity", classEntity, CreatureSpawnEvent.SpawnReason.class)); setLocation = ReflectionUtils.setAccessible(classEntity.getDeclaredMethod("setLocation", double.class, double.class, double.class, float.class, float.class)); try { - classMinecraftKey = ReflectionUtils.getNmsClass("MinecraftKey"); + classMinecraftKey = BukkitReflectionUtils.getNmsClass("MinecraftKey"); newMinecraftKey = classMinecraftKey.getConstructor(String.class); } catch (Throwable ignore) { } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java index 13d70a67..057ffcd9 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java @@ -648,19 +648,15 @@ public class BukkitQueue_1_10 extends BukkitQueue_0 { if (copy != null) { copy.storeEntity(entity); } - removeEntity(entity); iter.remove(); + synchronized (BukkitQueue_0.class) { + removeEntity(entity); + } } } } @@ -290,7 +292,9 @@ public class BukkitChunk_1_12 extends CharFaweChunk { copy.storeEntity(entity); } iter.remove(); - removeEntity(entity); + synchronized (BukkitQueue_0.class) { + removeEntity(entity); + } } } } @@ -340,7 +344,9 @@ public class BukkitChunk_1_12 extends CharFaweChunk { entity.f(tag); } entity.setLocation(x, y, z, yaw, pitch); - nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + synchronized (BukkitQueue_0.class) { + nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + } createdEntities.add(entity.getUniqueID()); } } @@ -373,15 +379,16 @@ public class BukkitChunk_1_12 extends CharFaweChunk { } } if (toRemove != null) { - for (Map.Entry entry : toRemove.entrySet()) { - BlockPosition bp = entry.getKey(); - TileEntity tile = entry.getValue(); - tiles.remove(bp); - tile.z(); - nmsWorld.s(bp); - tile.invalidateBlockCache(); + synchronized (BukkitQueue_0.class) { + for (Map.Entry entry : toRemove.entrySet()) { + BlockPosition bp = entry.getKey(); + TileEntity tile = entry.getValue(); + tiles.remove(bp); + tile.z(); + nmsWorld.s(bp); + tile.invalidateBlockCache(); + } } - } // Set blocks for (int j = 0; j < sections.length; j++) { @@ -485,16 +492,18 @@ public class BukkitChunk_1_12 extends CharFaweChunk { int y = (blockHash & 0xFF); int z = (blockHash >> 8 & 0xF) + bz; BlockPosition pos = new BlockPosition(x, y, z); // Set pos - TileEntity tileEntity = nmsWorld.getTileEntity(pos); - if (tileEntity != null) { - NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.fromNative(nativeTag); - tag.set("x", new NBTTagInt(x)); - tag.set("y", new NBTTagInt(y)); - tag.set("z", new NBTTagInt(z)); - if (BukkitQueue_1_12.methodTileEntityLoad != null) { - BukkitQueue_1_12.methodTileEntityLoad.invoke(tileEntity, tag); // ReadTagIntoTile - } else { - tileEntity.load(tag); + synchronized (BukkitQueue_0.class) { + TileEntity tileEntity = nmsWorld.getTileEntity(pos); + if (tileEntity != null) { + NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.fromNative(nativeTag); + tag.set("x", new NBTTagInt(x)); + tag.set("y", new NBTTagInt(y)); + tag.set("z", new NBTTagInt(z)); + if (BukkitQueue_1_12.methodTileEntityLoad != null) { + BukkitQueue_1_12.methodTileEntityLoad.invoke(tileEntity, tag); // ReadTagIntoTile + } else { + tileEntity.load(tag); + } } } } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/BukkitQueue_1_12.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/BukkitQueue_1_12.java index 4cc40907..9173bec6 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/BukkitQueue_1_12.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/BukkitQueue_1_12.java @@ -730,19 +730,15 @@ public class BukkitQueue_1_12 extends BukkitQueue_0 ex TaskManager.IMP.async(new Runnable() { @Override public void run() { - getRelighter().fixLightingSafe(hasSky()); + if (Settings.IMP.LIGHTING.REMOVE_FIRST) { + getRelighter().removeAndRelight(hasSky()); + } else { + getRelighter().fixLightingSafe(hasSky()); + } } }); } @@ -109,7 +113,18 @@ public abstract class NMSMappedFaweQueue ex public abstract void setFullbright(CHUNKSECTION sections); - public abstract boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky); + public boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky) { + boolean result = false; + for (int i = 0; i < 16; i++) { + SECTION section = getCachedSection(sections, i); + if (section != null) { + result |= removeSectionLighting(section, i, hasSky); + } + } + return result; + } + + public abstract boolean removeSectionLighting(SECTION sections, int layer, boolean hasSky); public boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) { return this.isSolid(this.getId(sections, x, y + 1, z)) diff --git a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java index 72b1cc96..69191e68 100644 --- a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java +++ b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java @@ -40,6 +40,7 @@ public class NMSRelighter implements Relighter { public final IntegerTrio mutableBlockPos = new IntegerTrio(); private static final int DISPATCH_SIZE = 64; + private boolean removeFirst; public NMSRelighter(NMSMappedFaweQueue queue) { this.queue = queue; @@ -55,6 +56,13 @@ public class NMSRelighter implements Relighter { return skyToRelight.isEmpty() && lightQueue.isEmpty() && queuedSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty(); } + @Override + public synchronized void removeAndRelight(boolean sky) { + removeFirst = true; + fixLightingSafe(true); + removeFirst = false; + } + private void set(int x, int y, int z, long[][][] map) { long[][] m1 = map[z]; if (m1 == null) { @@ -392,6 +400,11 @@ public class NMSRelighter implements Relighter { Object section = queue.getCachedSection(sections, layer); if (section == null) continue; chunk.smooth = false; + + if (removeFirst && (y & 15) == 15) { + queue.removeSectionLighting(sections, y >> 4, true); + } + for (int j = 0; j <= maxY; j++) { int x = cacheX[j]; int z = cacheZ[j]; diff --git a/core/src/main/java/com/boydti/fawe/example/NullRelighter.java b/core/src/main/java/com/boydti/fawe/example/NullRelighter.java index 061ba988..94d62c76 100644 --- a/core/src/main/java/com/boydti/fawe/example/NullRelighter.java +++ b/core/src/main/java/com/boydti/fawe/example/NullRelighter.java @@ -22,6 +22,11 @@ public class NullRelighter implements Relighter { } + @Override + public void removeLighting() { + + } + @Override public void fixBlockLighting() { diff --git a/core/src/main/java/com/boydti/fawe/example/Relighter.java b/core/src/main/java/com/boydti/fawe/example/Relighter.java index db3cb33f..901dd4c6 100644 --- a/core/src/main/java/com/boydti/fawe/example/Relighter.java +++ b/core/src/main/java/com/boydti/fawe/example/Relighter.java @@ -7,6 +7,13 @@ public interface Relighter { void fixLightingSafe(boolean sky); + default void removeAndRelight(boolean sky) { + removeLighting(); + fixLightingSafe(sky); + } + + void removeLighting(); + void fixBlockLighting(); void fixSkyLighting(); diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/ChunkSimplifier.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/ChunkSimplifier.java new file mode 100644 index 00000000..24637e5f --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/ChunkSimplifier.java @@ -0,0 +1,19 @@ +package com.boydti.fawe.jnbt.anvil; + +public class ChunkSimplifier { + private final HeightMapMCAGenerator gen; + + public ChunkSimplifier(HeightMapMCAGenerator gen) { + this.gen = gen; + } + + public void simplify(MCAChunk chunk) { + // Copy biome + // Calculate water level + // Determine floor block + // Determine overlay block + // determine main block + // Copy bedrock + // copy anomalies to blocks + } +} diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index 7a87b9c6..31f7e47e 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -510,7 +510,6 @@ public class MCAChunk extends FaweChunk { if (entities == null) { entities = new HashMap(); } - long least = entityTag.getLong("UUIDLeast"); long most = entityTag.getLong("UUIDMost"); entities.put(new UUID(most, least), entityTag); @@ -733,16 +732,20 @@ public class MCAChunk extends FaweChunk { public void removeLight() { for (int i = 0; i < skyLight.length; i++) { - byte[] array1 = skyLight[i]; - if (array1 == null) { - continue; - } - byte[] array2 = blockLight[i]; - Arrays.fill(array1, (byte) 0); - Arrays.fill(array2, (byte) 0); + removeLight(i); } } + public void removeLight(int i) { + byte[] array1 = skyLight[i]; + if (array1 == null) { + return; + } + byte[] array2 = blockLight[i]; + Arrays.fill(array1, (byte) 0); + Arrays.fill(array2, (byte) 0); + } + public int getNibble(int index, byte[] array) { int indexShift = index >> 1; if ((index & 1) == 0) { diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java index f01c0806..6e6d365a 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java @@ -687,6 +687,22 @@ public class MCAQueue extends NMSMappedFaweQueue player, FaweChangeSet parent) { + public static FaweChangeSet wrap(FawePlayer player, FaweChangeSet parent) { if (!initialized) { initialized = true; api = (IBlocksHubApi) Fawe.imp().getBlocksHubApi(); diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java index 3e117577..5ed48dd1 100644 --- a/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java @@ -23,6 +23,7 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; @@ -273,6 +274,16 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { clean.setAccessible(true); clean.invoke(cleaner.invoke(cb)); } catch (Exception ex) { + try { + final Class unsafeClass = Class.forName("sun.misc.Unsafe"); + final Field theUnsafeField = unsafeClass.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + final Object theUnsafe = theUnsafeField.get(null); + final Method invokeCleanerMethod = unsafeClass.getMethod("invokeCleaner", ByteBuffer.class); + invokeCleanerMethod.invoke(theUnsafe, cb); + } catch (Exception e) { + System.gc(); + } } cb = null; } diff --git a/core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java b/core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java index 17b8df15..a2ccec24 100644 --- a/core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java +++ b/core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java @@ -39,7 +39,7 @@ import java.io.Serializable; *

* A SparseBitSet is not safe for multithreaded use without * external synchronization. - * + * @see source * @author Bruce K. Haddon * @author Arthur van Hoff * @author Michael McCloskey diff --git a/core/src/main/java/com/boydti/fawe/object/queue/NullFaweQueue.java b/core/src/main/java/com/boydti/fawe/object/queue/NullFaweQueue.java new file mode 100644 index 00000000..1e9a4939 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/queue/NullFaweQueue.java @@ -0,0 +1,214 @@ +package com.boydti.fawe.object.queue; + +import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.FaweQueue; +import com.boydti.fawe.object.RunnableVal2; +import com.boydti.fawe.object.exception.FaweException; +import com.boydti.fawe.util.SetQueue; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; +import javax.annotation.Nullable; + +public class NullFaweQueue implements FaweQueue { + private final String worldName; + + public NullFaweQueue(String worldName) { + this.worldName = worldName; + } + + @Override + public boolean setBlock(int x, int y, int z, int id, int data) { + return false; + } + + @Override + public void setTile(int x, int y, int z, CompoundTag tag) { + + } + + @Override + public void setEntity(int x, int y, int z, CompoundTag tag) { + + } + + @Override + public void removeEntity(int x, int y, int z, UUID uuid) { + + } + + @Override + public boolean setBiome(int x, int z, BaseBiome biome) { + return false; + } + + @Override + public FaweChunk getFaweChunk(int x, int z) { + return null; + } + + @Override + public Collection getFaweChunks() { + return Collections.emptyList(); + } + + @Override + public void setChunk(FaweChunk chunk) { + + } + + @Override + public File getSaveFolder() { + return null; + } + + @Override + public void setWorld(String world) { + + } + + @Override + public World getWEWorld() { + return null; + } + + @Override + public String getWorldName() { + return worldName; + } + + @Override + public long getModified() { + return 0; + } + + @Override + public void setModified(long modified) { + + } + + @Override + public RunnableVal2 getProgressTask() { + return null; + } + + @Override + public void setProgressTask(RunnableVal2 progressTask) { + + } + + @Override + public void setChangeTask(RunnableVal2 changeTask) { + + } + + @Override + public RunnableVal2 getChangeTask() { + return null; + } + + @Override + public SetQueue.QueueStage getStage() { + return SetQueue.QueueStage.NONE; + } + + @Override + public void setStage(SetQueue.QueueStage stage) { + + } + + @Override + public void addNotifyTask(Runnable runnable) { + runnable.run(); + } + + @Override + public void runTasks() { + + } + + @Override + public void addTask(Runnable whenFree) { + whenFree.run(); + } + + @Override + public boolean regenerateChunk(int x, int z, @Nullable BaseBiome biome, @Nullable Long seed) { + return false; + } + + @Override + public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) { + + } + + @Override + public boolean next(int amount, long time) { + return false; + } + + @Override + public void sendChunk(FaweChunk chunk) { + + } + + @Override + public void sendChunk(int x, int z, int bitMask) { + + } + + @Override + public void clear() { + + } + + @Override + public void addNotifyTask(int x, int z, Runnable runnable) { + runnable.run(); + } + + @Override + public int getBiomeId(int x, int z) throws FaweException.FaweChunkLoadException { + return 0; + } + + @Override + public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { + return 0; + } + + @Override + public int getCachedCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { + return 0; + } + + @Override + public boolean hasSky() { + return true; + } + + @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public CompoundTag getTileEntity(int x, int y, int z) throws FaweException.FaweChunkLoadException { + return null; + } + + @Override + public int size() { + return 0; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/regions/FuzzyRegion.java b/core/src/main/java/com/boydti/fawe/object/regions/FuzzyRegion.java index d0c5898b..5e1771cf 100644 --- a/core/src/main/java/com/boydti/fawe/object/regions/FuzzyRegion.java +++ b/core/src/main/java/com/boydti/fawe/object/regions/FuzzyRegion.java @@ -48,7 +48,8 @@ public class FuzzyRegion extends AbstractRegion { public void select(int x, int y, int z) { RecursiveVisitor search = new RecursiveVisitor(mask, new RegionFunction() { @Override - public boolean apply(Vector position) throws WorldEditException { + public boolean apply(Vector p) throws WorldEditException { + setMinMax(p.getBlockX(), p.getBlockY(), p.getBlockZ()); return true; } }, 256, extent instanceof HasFaweQueue ? (HasFaweQueue) extent : null); @@ -62,8 +63,7 @@ public class FuzzyRegion extends AbstractRegion { return (Iterator) set.iterator(); } - public void set(int x, int y, int z) throws RegionOperationException { - set.add(x, y, z); + private final void setMinMax(int x, int y, int z) { if (x > maxX) { maxX = x; } @@ -84,6 +84,11 @@ public class FuzzyRegion extends AbstractRegion { } } + public final void set(int x, int y, int z) throws RegionOperationException { + set.add(x, y, z); + setMinMax(x, y, z); + } + public boolean contains(int x, int y, int z) { return set.contains(x, y, z); } diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweTrim.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweTrim.java index 7261ed69..4b155597 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweTrim.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweTrim.java @@ -7,8 +7,8 @@ import com.intellectualcrafters.plot.commands.SubCommand; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.util.WorldUtil; import com.plotsquared.general.commands.CommandDeclaration; -import org.bukkit.Bukkit; @CommandDeclaration( command = "trimchunks", @@ -32,7 +32,7 @@ public class FaweTrim extends SubCommand { plotPlayer.sendMessage("use /plot trimall "); return false; } - if (Bukkit.getWorld(strings[0]) == null) { + if (!WorldUtil.IMP.isWorld(strings[0])) { C.NOT_VALID_PLOT_WORLD.send(plotPlayer, strings[0]); return false; } diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java index 22e80806..747241c9 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java @@ -26,6 +26,7 @@ import com.intellectualcrafters.plot.object.RunnableVal2; import com.intellectualcrafters.plot.object.RunnableVal3; import com.intellectualcrafters.plot.object.SetupObject; import com.intellectualcrafters.plot.util.SetupUtils; +import com.intellectualcrafters.plot.util.WorldUtil; import com.plotsquared.general.commands.Command; import com.plotsquared.general.commands.CommandDeclaration; import java.io.File; @@ -33,8 +34,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Map; -import org.bukkit.Bukkit; -import org.bukkit.World; @CommandDeclaration( command = "moveto512", @@ -160,9 +159,7 @@ public class MoveTo512 extends Command { check(area, C.COMMAND_SYNTAX, getUsage()); checkTrue(area instanceof HybridPlotWorld, C.NOT_VALID_HYBRID_PLOT_WORLD); - for (World world : Bukkit.getWorlds()) { - world.save(); - } + WorldUtil.IMP.saveWorld(area.worldname); FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(area.worldname, true, false); MCAQueue queueFrom = new MCAQueue(area.worldname, defaultQueue.getSaveFolder(), defaultQueue.hasSky()); diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotTrim.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotTrim.java index 5a31f4e5..5392eff6 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotTrim.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/PlotTrim.java @@ -4,8 +4,10 @@ import com.boydti.fawe.jnbt.anvil.MCAChunk; import com.boydti.fawe.jnbt.anvil.MCAFile; import com.boydti.fawe.jnbt.anvil.MCAFilter; import com.boydti.fawe.jnbt.anvil.MCAQueue; +import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MathMan; +import com.boydti.fawe.util.SetQueue; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; @@ -21,14 +23,11 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.bukkit.Bukkit; -import org.bukkit.event.Listener; -import org.bukkit.plugin.Plugin; import static com.google.common.base.Preconditions.checkNotNull; -public class PlotTrim implements Listener { +public class PlotTrim { private final MCAQueue queue; private final PlotArea area; private final PlotPlayer player; @@ -39,8 +38,10 @@ public class PlotTrim implements Listener { private boolean deleteUnowned = true; public PlotTrim(PlotPlayer player, PlotArea area, String worldName, boolean deleteUnowned) { - this.root = new File(Bukkit.getWorldContainer(), worldName + "-Copy" + File.separator + "region"); - this.originalRoot = new File(Bukkit.getWorldContainer(), worldName + File.separator + "region"); + FaweQueue tmpQueue = SetQueue.IMP.getNewQueue(worldName, true, false); + File saveFolder = tmpQueue.getSaveFolder(); + this.root = new File(saveFolder.getParentFile().getParentFile(), worldName + "-Copy" + File.separator + "region"); + this.originalRoot = saveFolder; this.originalQueue = new MCAQueue(worldName, originalRoot, true); this.queue = new MCAQueue(worldName + "-Copy", root, true); this.area = area; @@ -76,7 +77,6 @@ public class PlotTrim implements Listener { } public void run() { - Bukkit.getPluginManager().registerEvents(this, (Plugin) PS.get().IMP); final Set mcas = new HashSet<>(); if (deleteUnowned && area != null) { originalQueue.filterWorld(new MCAFilter() { diff --git a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java index 7e9fb760..df321bde 100644 --- a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java +++ b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java @@ -12,8 +12,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import org.bukkit.Bukkit; -import org.bukkit.Server; import sun.reflect.ConstructorAccessor; import sun.reflect.FieldAccessor; import sun.reflect.ReflectionFactory; @@ -24,49 +22,6 @@ import sun.reflect.ReflectionFactory; */ @SuppressWarnings({"UnusedDeclaration", "rawtypes"}) public class ReflectionUtils { - /** - * prefix of bukkit classes - */ - private static volatile String preClassB = null; - /** - * prefix of minecraft classes - */ - private static volatile String preClassM = null; - /** - * boolean value, TRUE if server uses forge or MCPC+ - */ - private static boolean forge = false; - - /** - * check server version and class names - */ - public static void init() { - if (Bukkit.getServer() != null) { - if (Bukkit.getVersion().contains("MCPC") || Bukkit.getVersion().contains("Forge")) { - forge = true; - } - final Server server = Bukkit.getServer(); - final Class bukkitServerClass = server.getClass(); - String[] pas = bukkitServerClass.getName().split("\\."); - if (pas.length == 5) { - final String verB = pas[3]; - preClassB = "org.bukkit.craftbukkit." + verB; - } - try { - final Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle"); - final Object handle = getHandle.invoke(server); - final Class handleServerClass = handle.getClass(); - pas = handleServerClass.getName().split("\\."); - if (pas.length == 5) { - final String verM = pas[3]; - preClassM = "net.minecraft.server." + verM; - } - } catch (final Exception ignored) { - MainUtil.handleError(ignored); - } - } - } - public static T as(Class t, Object o) { return t.isInstance(o) ? t.cast(o) : null; } @@ -200,33 +155,6 @@ public class ReflectionUtils { } } - public static Class getNmsClass(final String name) { - final String className = "net.minecraft.server." + getVersion() + "." + name; - return getClass(className); - } - - public static Class getCbClass(final String name) { - final String className = "org.bukkit.craftbukkit." + getVersion() + "." + name; - return getClass(className); - } - - public static Class getUtilClass(final String name) { - try { - return Class.forName(name); //Try before 1.8 first - } catch (final ClassNotFoundException ex) { - try { - return Class.forName("net.minecraft.util." + name); //Not 1.8 - } catch (final ClassNotFoundException ex2) { - return null; - } - } - } - - public static String getVersion() { - final String packageName = Bukkit.getServer().getClass().getPackage().getName(); - return packageName.substring(packageName.lastIndexOf('.') + 1); - } - public static Object getHandle(final Object wrapper) { final Method getHandle = makeMethod(wrapper.getClass(), "getHandle"); return callMethod(getHandle, wrapper); @@ -414,34 +342,6 @@ public class ReflectionUtils { } } - /** - * @return true if server has forge classes - */ - public static boolean isForge() { - return forge; - } - - /** - * Get class for name. Replace {nms} to net.minecraft.server.V*. Replace {cb} to org.bukkit.craftbukkit.V*. Replace - * {nm} to net.minecraft - * - * @param classes possible class paths - * @return RefClass object - * @throws RuntimeException if no class found - */ - public static RefClass getRefClass(final String... classes) throws RuntimeException { - if (preClassM == null) { - init(); - } - for (String className : classes) { - try { - className = className.replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft"); - return getRefClass(Class.forName(className)); - } catch (final ClassNotFoundException ignored) { - } - } - throw new RuntimeException("no class found: " + classes[0].replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft")); - } /** * get RefClass object by real class diff --git a/core/src/main/java/com/boydti/fawe/util/gui/FormBuilder.java b/core/src/main/java/com/boydti/fawe/util/gui/FormBuilder.java new file mode 100644 index 00000000..7710fb36 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/util/gui/FormBuilder.java @@ -0,0 +1,29 @@ +package com.boydti.fawe.util.gui; + +import com.boydti.fawe.object.FawePlayer; +import java.net.URL; +import java.util.List; +import java.util.function.Consumer; +import javax.annotation.Nullable; + +public interface FormBuilder { + FormBuilder setTitle(String text); + + FormBuilder setIcon(URL icon); + + FormBuilder addButton(String text, @Nullable URL image); + + FormBuilder addDropdown(String text, int def, String... options); + + FormBuilder addInput(String text, String placeholder, String def); + + FormBuilder addLabel(String text); + + FormBuilder addSlider(String text, double min, double max, int step, double def); + + FormBuilder addStepSlider(String text, int def, String... options); + + FormBuilder addToggle(String text, boolean def); + + void display(FawePlayer fp, Consumer> response); +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 614e8ae5..486c7754 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -31,6 +31,7 @@ import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.chat.Message; import com.boydti.fawe.util.chat.UsageMessage; +import com.boydti.fawe.util.gui.FormBuilder; import com.google.common.base.Joiner; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; @@ -100,6 +101,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; import java.util.stream.Collectors; @@ -889,6 +891,33 @@ public class UtilityCommands extends MethodCommands { help(args, we, actor, "/", null); } + @Command( + aliases = {"/gui"}, + desc = "Open the GUI" + ) + @Logging(PLACEMENT) + public void gui(FawePlayer fp, LocalSession session, CommandContext args) throws WorldEditException { + FormBuilder gui = Fawe.imp().getFormBuilder(); + if (gui == null) throw new UnsupportedOperationException("Not implemented"); + + Dispatcher callable = worldEdit.getPlatformManager().getCommandManager().getDispatcher(); + CommandLocals locals = args.getLocals(); + + // TODO build form + + + gui.display(fp, new Consumer>() { + @Override + public void accept(List strings) { + + } + }); + } + + private void help(CommandCallable callable) { + + } + public static void help(CommandContext args, WorldEdit we, Actor actor, String prefix, CommandCallable callable) { try { if (callable == null) { diff --git a/forge110/src/main/java/com/boydti/fawe/forge/v110/ForgeQueue_All.java b/forge110/src/main/java/com/boydti/fawe/forge/v110/ForgeQueue_All.java index 4efaa864..c98cc62c 100644 --- a/forge110/src/main/java/com/boydti/fawe/forge/v110/ForgeQueue_All.java +++ b/forge110/src/main/java/com/boydti/fawe/forge/v110/ForgeQueue_All.java @@ -473,19 +473,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/nukkit/build.gradle b/nukkit/build.gradle index 22d339c3..9e01be89 100644 --- a/nukkit/build.gradle +++ b/nukkit/build.gradle @@ -3,7 +3,7 @@ repositories { } dependencies { compile project(':core') - compile group: "cn.nukkit", name: "nukkit", version: "1.0-20170704.231613-609" + compile group: "cn.nukkit", name: "nukkit", version: "1.0" compile name: 'worldedit-core-6.1.4-SNAPSHOT-dist' } diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java index ee62603b..08f9f874 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java @@ -19,6 +19,7 @@ package com.boydti.fawe.nukkit.core; +import cn.nukkit.AdventureSettings; import cn.nukkit.Player; import cn.nukkit.inventory.PlayerInventory; import cn.nukkit.item.Item; @@ -174,7 +175,8 @@ public class NukkitPlayer extends LocalPlayer { } setPosition(new Vector(x + 0.5, y, z + 0.5)); - player.getAdventureSettings().setCanFly(true); + player.getAdventureSettings().set(AdventureSettings.Type.ALLOW_FLIGHT, true); + player.getAdventureSettings().set(AdventureSettings.Type.FLYING, true); player.getAdventureSettings().update(); } diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/DelegateFormWindow.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/DelegateFormWindow.java new file mode 100644 index 00000000..3875b64a --- /dev/null +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/DelegateFormWindow.java @@ -0,0 +1,26 @@ +package com.boydti.fawe.nukkit.core.gui; + +import cn.nukkit.form.response.FormResponse; +import cn.nukkit.form.window.FormWindow; + +public class DelegateFormWindow extends FormWindow { + private final FormWindow parent; + + public DelegateFormWindow(FormWindow parent) { + this.parent = parent; + } + @Override + public String getJSONData() { + return parent.getJSONData(); + } + + @Override + public void setResponse(String s) { + parent.setResponse(s); + } + + @Override + public FormResponse getResponse() { + return parent.getResponse(); + } +} diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/NukkitFormBuilder.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/NukkitFormBuilder.java new file mode 100644 index 00000000..e8e2d7ec --- /dev/null +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/NukkitFormBuilder.java @@ -0,0 +1,147 @@ +package com.boydti.fawe.nukkit.core.gui; + +import cn.nukkit.Player; +import cn.nukkit.form.element.Element; +import cn.nukkit.form.element.ElementButton; +import cn.nukkit.form.element.ElementButtonImageData; +import cn.nukkit.form.element.ElementDropdown; +import cn.nukkit.form.element.ElementInput; +import cn.nukkit.form.element.ElementLabel; +import cn.nukkit.form.element.ElementSlider; +import cn.nukkit.form.element.ElementStepSlider; +import cn.nukkit.form.element.ElementToggle; +import cn.nukkit.form.window.FormWindow; +import cn.nukkit.form.window.FormWindowCustom; +import cn.nukkit.form.window.FormWindowSimple; +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.util.gui.FormBuilder; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; + + +import static com.google.common.base.Preconditions.checkNotNull; + +public class NukkitFormBuilder implements FormBuilder { + private final List elements; + private final List buttons; + private String title = ""; + private String icon; + + public NukkitFormBuilder() { + this.elements = new ArrayList<>(); + this.buttons = new ArrayList<>(); + } + + @Override + public FormBuilder setTitle(String text) { + checkNotNull(text); + this.title = text; + return this; + } + + @Override + public FormBuilder setIcon(URL icon) { + checkNotNull(icon); + this.icon = icon.toString(); + return this; + } + + @Override + public FormBuilder addButton(String text, URL image) { + checkNotNull(text); + if (!elements.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + ElementButton button; + if (image != null) { + ElementButtonImageData imageData = new ElementButtonImageData("url", image.toString()); + button = new ElementButton(text, imageData); + } else { + button = new ElementButton(text); + } + buttons.add(button); + return this; + } + + @Override + public FormBuilder addDropdown(String text, int def, String... options) { + checkNotNull(text); + checkNotNull(options); + for (String option : options) checkNotNull(option); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementDropdown(text, Arrays.asList(options), def)); + return this; + } + + @Override + public FormBuilder addInput(String text, String placeholder, String def) { + checkNotNull(text); + checkNotNull(placeholder); + checkNotNull(def); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementInput(text, placeholder, def)); + return this; + } + + @Override + public FormBuilder addLabel(String text) { + checkNotNull(text); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementLabel(text)); + return this; + } + + @Override + public FormBuilder addSlider(String text, double min, double max, int step, double def) { + checkNotNull(text); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementSlider(text, (float) min, (float) max, step, (float) def)); + return this; + } + + @Override + public FormBuilder addStepSlider(String text, int def, String... options) { + checkNotNull(text); + checkNotNull(options); + for (String option : options) checkNotNull(option); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementStepSlider(text, Arrays.asList(options), def)); + return this; + } + + @Override + public FormBuilder addToggle(String text, boolean def) { + checkNotNull(text); + if (!buttons.isEmpty()) throw new UnsupportedOperationException("GUI does not support mixed buttons / elements"); + + elements.add(new ElementToggle(text, def)); + return this; + } + + @Override + public void display(FawePlayer fp, Consumer> response) { + FormWindow window; + if (buttons.isEmpty()) { + if (icon == null) { + window = new FormWindowCustom("Title", elements); + } else { + window = new FormWindowCustom("Title", elements, icon); + } + } else { + window = new FormWindowSimple("Title", "", buttons); + } + + if (response != null) { + window = new ResponseFormWindow(window, response); + } + + Player player = fp.parent; + player.showFormWindow(window); + } +} diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/ResponseFormWindow.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/ResponseFormWindow.java new file mode 100644 index 00000000..1d67237b --- /dev/null +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/gui/ResponseFormWindow.java @@ -0,0 +1,22 @@ +package com.boydti.fawe.nukkit.core.gui; + +import cn.nukkit.form.window.FormWindow; +import java.util.List; +import java.util.function.Consumer; + + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ResponseFormWindow extends DelegateFormWindow { + private final Consumer> task; + + public ResponseFormWindow(FormWindow parent, Consumer> onResponse) { + super(parent); + checkNotNull(onResponse); + this.task = onResponse; + } + + public void respond(List response) { + task.accept(response); + } +} \ No newline at end of file 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 da5b6db9..6d2a49da 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 @@ -4,12 +4,14 @@ import cn.nukkit.Nukkit; import cn.nukkit.Player; import cn.nukkit.event.EventHandler; import cn.nukkit.event.Listener; +import cn.nukkit.event.player.PlayerFormRespondedEvent; import cn.nukkit.event.player.PlayerQuitEvent; import com.boydti.fawe.Fawe; import com.boydti.fawe.IFawe; import com.boydti.fawe.config.Settings; import com.boydti.fawe.nukkit.core.NukkitTaskManager; import com.boydti.fawe.nukkit.core.NukkitWorldEdit; +import com.boydti.fawe.nukkit.core.gui.NukkitFormBuilder; import com.boydti.fawe.nukkit.listener.BrushListener; import com.boydti.fawe.nukkit.optimization.queue.NukkitQueue; import com.boydti.fawe.object.FaweChunk; @@ -19,6 +21,7 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.brush.visualization.VisualChunk; import com.boydti.fawe.regions.FaweMaskManager; import com.boydti.fawe.util.TaskManager; +import com.boydti.fawe.util.gui.FormBuilder; import com.sk89q.worldedit.world.World; import java.io.File; import java.util.ArrayList; @@ -34,6 +37,9 @@ public class FaweNukkit implements IFawe, Listener { this.plugin = mod; FaweChunk.HEIGHT = 256; VisualChunk.VISUALIZE_BLOCK = 20 << 4; + + + plugin.getServer().getPluginManager().registerEvents(this, plugin); try { new BrushListener(mod); @@ -44,6 +50,11 @@ public class FaweNukkit implements IFawe, Listener { } } + @Override + public FormBuilder getFormBuilder() { + return new NukkitFormBuilder(); + } + @Override public int getPlayerCount() { return plugin.getServer().getOnlinePlayers().size(); @@ -59,6 +70,11 @@ public class FaweNukkit implements IFawe, Listener { return Nukkit.VERSION; } + @EventHandler + public void onFormSubmit(PlayerFormRespondedEvent event) { + // TODO + } + @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); @@ -86,6 +102,8 @@ public class FaweNukkit implements IFawe, Listener { @Override public void setupCommand(String label, final FaweCommand cmd) { plugin.getServer().getCommandMap().register(label, new NukkitCommand(label, cmd)); + + } @Override diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java index 7c92510a..3b9fd9d8 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java @@ -193,6 +193,21 @@ public class NukkitQueue extends NMSMappedFaweQueue