From 0bc703e1b91c35cb5a496a63b617957259627223 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sat, 14 May 2016 23:38:07 +1000 Subject: [PATCH] Forge/Sponge 3.5.0 --- build.gradle | 4 +- bukkit0/build.gradle | 10 - bukkit18/build.gradle | 10 + bukkit18/src/main/resources/plugin.yml | 2 +- bukkit19/build.gradle | 11 +- bukkit19/src/main/resources/plugin.yml | 4 +- core/src/main/java/com/boydti/fawe/Fawe.java | 59 +-- .../boydti/fawe/example/CharFaweChunk.java | 10 +- .../com/boydti/fawe/object/FawePlayer.java | 13 +- .../object/extent/FastWorldEditExtent.java | 25 +- .../progress/DefaultProgressTracker.java | 3 +- .../java/com/boydti/fawe/util/FaweQueue.java | 1 + .../com/sk89q/worldedit/LocalSession.java | 2 +- .../worldedit/command/SchematicCommands.java | 85 ++-- .../worldedit/command/ScriptingCommands.java | 42 +- .../java/com/boydti/fawe/forge/FaweForge.java | 2 +- .../java/com/boydti/fawe/forge/ForgeMain.java | 2 +- .../com/boydti/fawe/forge/ForgePlayer.java | 11 + .../boydti/fawe/forge/v0/ForgeChunk_All.java | 141 ++---- .../boydti/fawe/forge/v0/ForgeQueue_All.java | 328 +++++++++++-- forge1710/src/main/resources/mcmod.info | 2 +- .../java/com/boydti/fawe/forge/FaweForge.java | 2 +- .../java/com/boydti/fawe/forge/ForgeMain.java | 2 +- .../com/boydti/fawe/forge/ForgePlayer.java | 11 + .../boydti/fawe/forge/v0/ForgeQueue_All.java | 442 ++++++++++++++---- pom.xml | 2 +- .../com/boydti/fawe/sponge/FaweSponge.java | 3 +- .../com/boydti/fawe/sponge/SpongeMain.java | 2 +- .../com/boydti/fawe/sponge/SpongePlayer.java | 15 + .../fawe/sponge/v1_8/SpongeQueue_1_8.java | 273 +++++++++-- .../fawe/sponge/v1_8/SpongeQueue_ALL.java | 84 +++- 31 files changed, 1138 insertions(+), 465 deletions(-) diff --git a/build.gradle b/build.gradle index 47cba7b3..3ebce119 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3' - classpath 'org.ajoberstar:grgit:1.1.0' + classpath 'org.ajoberstar:grgit:1.7.0' } } @@ -17,7 +17,7 @@ clean { delete "target" } group = 'com.boydti.fawe' def revision = "" ext { - git = org.ajoberstar.grgit.Grgit.open(file(".git/")) + git = org.ajoberstar.grgit.Grgit.open(file(".git")) revision = "-${git.head().abbreviatedId}" } version = "3.5.0${revision}" diff --git a/bukkit0/build.gradle b/bukkit0/build.gradle index e49bd8ad..79befbb2 100644 --- a/bukkit0/build.gradle +++ b/bukkit0/build.gradle @@ -13,14 +13,4 @@ dependencies { compile 'com.worldcretornica:plotme_core:0.16.3' compile 'junit:junit:4.11' compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.1-SNAPSHOT' -} - -processResources { - from('src/main/resources') { - include 'plugin.yml' - expand( - name: project.parent.name, - version: project.parent.version - ) - } } \ No newline at end of file diff --git a/bukkit18/build.gradle b/bukkit18/build.gradle index b756423d..698b4c80 100644 --- a/bukkit18/build.gradle +++ b/bukkit18/build.gradle @@ -3,6 +3,16 @@ dependencies { compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8' } +processResources { + from('src/main/resources') { + include 'plugin.yml' + expand( + name: project.parent.name, + version: project.parent.version + ) + } +} + apply plugin: 'com.github.johnrengelman.shadow' // We only want the shadow jar produced jar.enabled = false diff --git a/bukkit18/src/main/resources/plugin.yml b/bukkit18/src/main/resources/plugin.yml index 50b71af8..3549a844 100644 --- a/bukkit18/src/main/resources/plugin.yml +++ b/bukkit18/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: FastAsyncWorldEdit main: com.boydti.fawe.bukkit.v1_8.BukkitMain_18 -version: 3.4.3 +version: ${version} description: Fast Async WorldEdit plugin authors: [Empire92] loadbefore: [WorldEdit] diff --git a/bukkit19/build.gradle b/bukkit19/build.gradle index f8ab8b0f..3d673ef8 100644 --- a/bukkit19/build.gradle +++ b/bukkit19/build.gradle @@ -3,8 +3,17 @@ dependencies { compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4' } -apply plugin: 'com.github.johnrengelman.shadow' +processResources { + from('src/main/resources') { + include 'plugin.yml' + expand( + name: project.parent.name, + version: project.parent.version + ) + } +} +apply plugin: 'com.github.johnrengelman.shadow' // We only want the shadow jar produced jar.enabled = false shadowJar { diff --git a/bukkit19/src/main/resources/plugin.yml b/bukkit19/src/main/resources/plugin.yml index 91d1012b..17f77a6d 100644 --- a/bukkit19/src/main/resources/plugin.yml +++ b/bukkit19/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ -name: FastAsyncWorldEdit +name: ${name} main: com.boydti.fawe.bukkit.v1_9.BukkitMain_19 -version: 3.4.3 +version: ${version} description: Fast Async WorldEdit plugin authors: [Empire92] loadbefore: [WorldEdit] diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 0078d932..331ca37d 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -226,46 +226,46 @@ public class Fawe { * - LocalSession supports VirtualPlayers and undo on disk */ try { - EditSession.inject(); - LocalSession.inject(); + EditSession.inject(); // Custom block placer + optimizations + LocalSession.inject(); // Add remember order / queue flushing // Commands - BrushCommands.inject(); - ClipboardCommands.inject(); - SchematicCommands.inject(); - ScriptingCommands.inject(); - SelectionCommand.inject(); - RegionCommands.inject(); - HistoryCommands.inject(); + BrushCommands.inject(); // Translations + heightmap + ClipboardCommands.inject(); // Translations + lazycopy + paste optimizations + SchematicCommands.inject(); // Translations + ScriptingCommands.inject(); // Translations + SelectionCommand.inject(); // Translations + set optimizations + RegionCommands.inject(); // Translations + HistoryCommands.inject(); // Translations // Brushes - GravityBrush.inject(); + GravityBrush.inject(); // Fix for instant placement assumption // Selectors - CuboidRegionSelector.inject(); + CuboidRegionSelector.inject(); // Translations // Visitors - BreadthFirstSearch.inject(); - DownwardVisitor.inject(); - EntityVisitor.inject(); - FlatRegionVisitor.inject(); - LayerVisitor.inject(); - NonRisingVisitor.inject(); - RecursiveVisitor.inject(); - RegionVisitor.inject(); + BreadthFirstSearch.inject(); // Translations + Optimizations + DownwardVisitor.inject(); // Optimizations + EntityVisitor.inject(); // Translations + Optimizations + FlatRegionVisitor.inject(); // Translations + Optimizations + LayerVisitor.inject(); // Optimizations + NonRisingVisitor.inject(); // Optimizations + RecursiveVisitor.inject(); // Optimizations + RegionVisitor.inject(); // Translations + Optimizations // Entity create/remove - EntityCreate.inject(); - EntityRemove.inject(); + EntityCreate.inject(); // Optimizations + EntityRemove.inject(); // Optimizations // Clipboards - BlockArrayClipboard.inject(); - CuboidClipboard.inject(); + BlockArrayClipboard.inject(); // Optimizations + disk + CuboidClipboard.inject(); // Optimizations // Regions - CuboidRegion.inject(); + CuboidRegion.inject(); // Optimizations // Extents - BlockTransformExtent.inject(); + BlockTransformExtent.inject(); // Fix for cache not being mutable // Vector - Vector.inject(); + Vector.inject(); // Optimizations // Operations - Operations.inject(); + Operations.inject(); // Optimizations try { - CommandManager.inject(); - PlatformManager.inject(); + CommandManager.inject(); // Async commands + PlatformManager.inject(); // Async brushes / tools } catch (Throwable e) { debug("====== UPDATE WORLDEDIT TO 6.1.1 ======"); e.printStackTrace(); @@ -284,6 +284,7 @@ public class Fawe { e.printStackTrace(); debug("======================================="); debug("Things to check: "); + debug(" - Using WorldEdit 6.1.1"); debug(" - AsyncWorldEdit/WorldEditRegions isn't installed"); debug(" - Any other errors in the startup log"); debug(" - Contact Empire92 for assistance!"); diff --git a/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java b/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java index e85ba28b..7342db87 100644 --- a/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java +++ b/core/src/main/java/com/boydti/fawe/example/CharFaweChunk.java @@ -188,10 +188,8 @@ public abstract class CharFaweChunk extends FaweChunk { char[] vs = this.ids[i]; if (vs == null) { vs = this.ids[i] = new char[4096]; - this.count[i]++; - } else if (vs[j] == 0) { - this.count[i]++; } + this.count[i]++; switch (id) { case 0: this.air[i]++; @@ -277,11 +275,7 @@ public abstract class CharFaweChunk extends FaweChunk { case 146: case 61: case 65: - case 68: -// if (data < 2) { -// data = 2; -// } - + case 68: // removed default: vs[j] = (char) ((id << 4) + data); return; 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 3cbff22a..8e93988b 100644 --- a/core/src/main/java/com/boydti/fawe/object/FawePlayer.java +++ b/core/src/main/java/com/boydti/fawe/object/FawePlayer.java @@ -109,9 +109,9 @@ public abstract class FawePlayer { } public void loadClipboardFromDisk() { + File file = new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + getUUID()); try { - File file = new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + getUUID()); - if (file.exists()) { + if (file.exists() && file.length() > 5) { DiskOptimizedClipboard doc = new DiskOptimizedClipboard(file); Player player = getPlayer(); LocalSession session = getSession(); @@ -128,8 +128,13 @@ public abstract class FawePlayer { getSession().setClipboard(holder); } } - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception ignore) { + Fawe.debug("====== INVALID CLIPBOARD ======"); + ignore.printStackTrace(); + Fawe.debug("===============---============="); + Fawe.debug("This shouldn't result in any failure"); + Fawe.debug("File: " + file.getName() + " (len:" + file.length() + ")"); + Fawe.debug("===============---============="); } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java index d891a0e3..1e4fa0fc 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java @@ -108,17 +108,29 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { @Override public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { final short id = (short) block.getId(); + byte data = (byte) block.getData(); final int x = location.getBlockX(); final int y = location.getBlockY(); final int z = location.getBlockZ(); switch (id) { + case 68: { + if (data == 0) { + data = 2; + } + } case 63: - case 68: if (block.hasNbtData() && !MainUtil.isValidSign(block.getNbtData())) { queue.setBlock(x, y, z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0); return true; } case 54: + case 146: + case 61: + { + if (data == 0) { + data = 2; + } + } case 130: case 142: case 27: @@ -138,10 +150,8 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { case 28: case 66: case 157: - case 61: case 62: case 140: - case 146: case 149: case 150: case 158: @@ -157,11 +167,16 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { MainUtil.setPosition(nbt, x, y, z); queue.setTile(x, y, z, nbt); } - queue.setBlock(x, y, z, id, (byte) block.getData()); + queue.setBlock(x, y, z, id, data); return true; } + case 65: { + if (data == 0) { + data = 2; + } + } default: { - queue.setBlock(x, y, z, id, (byte) block.getData()); + queue.setBlock(x, y, z, id, data); return true; } } diff --git a/core/src/main/java/com/boydti/fawe/object/progress/DefaultProgressTracker.java b/core/src/main/java/com/boydti/fawe/object/progress/DefaultProgressTracker.java index 9aeb208b..854b70f1 100644 --- a/core/src/main/java/com/boydti/fawe/object/progress/DefaultProgressTracker.java +++ b/core/src/main/java/com/boydti/fawe/object/progress/DefaultProgressTracker.java @@ -7,7 +7,6 @@ import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.TaskManager; -import org.bukkit.Bukkit; public class DefaultProgressTracker extends RunnableVal2 { @@ -63,7 +62,7 @@ public class DefaultProgressTracker extends RunnableVal2 lastTick + Settings.DISPLAY_PROGRESS_INTERVAL) { lastTick = currentTick; String queue = StringMan.padRight("" + amountQueue, 3); diff --git a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java index 3a4299e9..f979c47d 100644 --- a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java @@ -97,6 +97,7 @@ public abstract class FaweQueue { public void endSet(boolean parallel) {} public int cancel() { + clear(); int count = 0; for (EditSession session : sessions) { if (session.cancel()) { diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 7f02c6db..6b7fbe2f 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -204,7 +204,7 @@ public class LocalSession { } public void remember(final EditSession editSession, final boolean append, final boolean sendMessage) { - if (editSession == null) { + if (editSession == null || editSession.getChangeSet() == null) { return; } if (Settings.STORE_HISTORY_ON_DISK) { diff --git a/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 2b168261..d61e3ca9 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -20,8 +20,6 @@ package com.sk89q.worldedit.command; import com.boydti.fawe.config.BBC; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; @@ -162,41 +160,31 @@ public class SchematicCommands { target = clipboard; } - SetQueue.IMP.addTask(new Runnable() { - @Override - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - final Closer closer = Closer.create(); - try { - // Create parent directories - final File parent = f.getParentFile(); - if ((parent != null) && !parent.exists()) { - if (!parent.mkdirs()) { - log.info("Could not create folder for schematics!"); - return; - } - } - - final FileOutputStream fos = closer.register(new FileOutputStream(f)); - final BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos)); - final ClipboardWriter writer = closer.register(format.getWriter(bos)); - writer.write(target, holder.getWorldData()); - log.info(player.getName() + " saved " + f.getCanonicalPath()); - BBC.SCHEMATIC_SAVED.send(player, filename); - } catch (final IOException e) { - player.printError("Schematic could not written: " + e.getMessage()); - log.log(Level.WARNING, "Failed to write a saved clipboard", e); - } finally { - try { - closer.close(); - } catch (final IOException ignored) {} - } - } - }); + final Closer closer = Closer.create(); + try { + // Create parent directories + final File parent = f.getParentFile(); + if ((parent != null) && !parent.exists()) { + if (!parent.mkdirs()) { + log.info("Could not create folder for schematics!"); + return; + } } - }); + + final FileOutputStream fos = closer.register(new FileOutputStream(f)); + final BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos)); + final ClipboardWriter writer = closer.register(format.getWriter(bos)); + writer.write(target, holder.getWorldData()); + log.info(player.getName() + " saved " + f.getCanonicalPath()); + BBC.SCHEMATIC_SAVED.send(player, filename); + } catch (final IOException e) { + player.printError("Schematic could not written: " + e.getMessage()); + log.log(Level.WARNING, "Failed to write a saved clipboard", e); + } finally { + try { + closer.close(); + } catch (final IOException ignored) {} + } } @Command(aliases = { "delete", "d" }, usage = "", desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1) @@ -207,22 +195,15 @@ public class SchematicCommands { final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir); final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, "schematic", "schematic"); - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - if (!f.exists()) { - player.printError("Schematic " + filename + " does not exist!"); - return; - } - - if (!f.delete()) { - player.printError("Deletion of " + filename + " failed! Maybe it is read-only."); - return; - } - - BBC.SCHEMATIC_DELETE.send(player, filename); - } - }); + if (!f.exists()) { + player.printError("Schematic " + filename + " does not exist!"); + return; + } + if (!f.delete()) { + player.printError("Deletion of " + filename + " failed! Maybe it is read-only."); + return; + } + BBC.SCHEMATIC_DELETE.send(player, filename); } @Command(aliases = { "formats", "listformats", "f" }, desc = "List available formats", max = 0) diff --git a/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java index 0b687c37..cad8e25c 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java @@ -19,8 +19,6 @@ package com.sk89q.worldedit.command; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; @@ -69,21 +67,11 @@ public class ScriptingCommands { final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir); final File f = this.worldEdit.getSafeOpenFile(player, dir, name, "js", "js"); - SetQueue.IMP.addTask(new Runnable() { - @Override - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - try { - ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs); - } catch (final WorldEditException ex) { - player.printError("Error while executing CraftScript."); - } - } - }); - } - }); + try { + ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs); + } catch (final WorldEditException ex) { + player.printError("Error while executing CraftScript."); + } } @Command(aliases = { ".s" }, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1) @@ -107,21 +95,11 @@ public class ScriptingCommands { final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir); final File f = this.worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js"); - SetQueue.IMP.addTask(new Runnable() { - @Override - public void run() { - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - try { - ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs); - } catch (final WorldEditException ex) { - player.printError("Error while executing CraftScript."); - } - } - }); - } - }); + try { + ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs); + } catch (final WorldEditException ex) { + player.printError("Error while executing CraftScript."); + } } public static Class inject() { 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 7a88b448..06a1a17d 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -125,7 +125,7 @@ public class FaweForge implements IFawe { @Override public void startMetrics() { try { - ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.3"); + ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.5.0"); metrics.start(); debug("[FAWE] &6Metrics enabled."); } catch (Throwable e) { diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/ForgeMain.java b/forge1710/src/main/java/com/boydti/fawe/forge/ForgeMain.java index 2142ed10..facb9bde 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/ForgeMain.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/ForgeMain.java @@ -19,7 +19,7 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import org.apache.logging.log4j.Logger; -@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.3", acceptableRemoteVersions = "*") +@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.5.0", acceptableRemoteVersions = "*") public class ForgeMain { private static FaweForge IMP; private Logger logger; diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/ForgePlayer.java b/forge1710/src/main/java/com/boydti/fawe/forge/ForgePlayer.java index 45c50bcc..bba22bf9 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/ForgePlayer.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/ForgePlayer.java @@ -1,5 +1,6 @@ package com.boydti.fawe.forge; +import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweLocation; import com.boydti.fawe.object.FawePlayer; import com.sk89q.worldedit.entity.Player; @@ -16,6 +17,16 @@ public class ForgePlayer extends FawePlayer { super(parent); } + @Override + public void sendTitle(String head, String sub) { // Not supported + Settings.DISPLAY_PROGRESS = false; + } + + @Override + public void resetTitle() { // Not supported + Settings.DISPLAY_PROGRESS = false; + } + @Override public String getName() { return parent.getCommandSenderName(); diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java index 36098fa4..bba53893 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java @@ -1,105 +1,32 @@ package com.boydti.fawe.forge.v0; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.MainUtil; -import com.sk89q.worldedit.world.biome.BaseBiome; -import java.util.Arrays; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.NibbleArray; -public class ForgeChunk_All extends FaweChunk { +public class ForgeChunk_All extends CharFaweChunk { - public byte[][] ids; + public byte[][] byteIds; public NibbleArray[] datas; - public short[] count; - public short[] air; - public short[] relight; - public byte[][] biomes; - public Chunk chunk; - public ForgeChunk_All(FaweQueue parent, int x, int z) { super(parent, x, z); - this.ids = new byte[16][]; + this.byteIds = new byte[16][]; this.datas = new NibbleArray[16]; - this.count = new short[16]; - this.air = new short[16]; - this.relight = new short[16]; - } - - - @Override - public Chunk getChunk() { - if (this.chunk == null) { - World world = ((ForgeQueue_All) getParent()).getWorld(); - this.chunk = world.getChunkProvider().provideChunk(getX(), getZ()); - } - return this.chunk; } @Override - public void setLoc(final FaweQueue parent, int x, int z) { - super.setLoc(parent, x, z); - this.chunk = null; + public Chunk getNewChunk() { + World world = ((ForgeQueue_All) getParent()).getWorld(); + return world.getChunkProvider().provideChunk(getX(), getZ()); } - /** - * Get the number of block changes in a specified section. - * @param i - * @return - */ - public int getCount(int i) { - return this.count[i]; - } - - public int getAir(int i) { - return this.air[i]; - } - - public void setCount(int i, short value) { - this.count[i] = value; - } - - /** - * Get the number of block changes in a specified section. - * @param i - * @return - */ - public int getRelight(int i) { - return this.relight[i]; - } - - public int getTotalCount() { - int total = 0; - for (int i = 0; i < 16; i++) { - total += this.count[i]; - } - return total; - } - - public int getTotalRelight() { - if (getTotalCount() == 0) { - Arrays.fill(this.count, (short) 1); - Arrays.fill(this.relight, Short.MAX_VALUE); - return Short.MAX_VALUE; - } - int total = 0; - for (int i = 0; i < 16; i++) { - total += this.relight[i]; - } - return total; - } - - /** - * Get the raw data for a section. - * @param i - * @return - */ - public byte[] getIdArray(int i) { - return this.ids[i]; + public byte[] getByteIdArray(int i) { + return this.byteIds[i]; } public NibbleArray getDataArray(int i) { @@ -110,17 +37,20 @@ public class ForgeChunk_All extends FaweChunk { public void setBlock(int x, int y, int z, int id, byte data) { int i = FaweCache.CACHE_I[y][x][z]; int j = FaweCache.CACHE_J[y][x][z]; - byte[] vs = this.ids[i]; - if (vs == null) { - vs = this.ids[i] = new byte[4096]; - this.count[i]++; - } else if (vs[j] == 0) { - this.count[i]++; + byte[] vs = this.byteIds[i]; + char[] vs2 = this.ids[i]; + if (vs2 == null) { + vs2 = this.ids[i] = new char[4096]; } + if (vs == null) { + vs = this.byteIds[i] = new byte[4096]; + } + this.count[i]++; switch (id) { case 0: this.air[i]++; vs[j] = -1; + vs2[j] = (char) 1; return; case 10: case 11: @@ -193,6 +123,7 @@ public class ForgeChunk_All extends FaweChunk { case 191: case 192: vs[j] = (byte) (id); + vs2[j] = (char) (id << 4); return; case 130: case 76: @@ -203,38 +134,26 @@ public class ForgeChunk_All extends FaweChunk { case 146: case 61: case 65: - case 68: -// if (data < 2) { -// data = 2; -// } + case 68: // removed default: + vs2[j] = (char) ((id << 4) + data); vs[j] = (byte) id; - NibbleArray dataArray = datas[i]; - if (dataArray == null) { - datas[i] = dataArray = new NibbleArray(4096, 4); + if (data != 0) { + NibbleArray dataArray = datas[i]; + if (dataArray == null) { + datas[i] = dataArray = new NibbleArray(4096, 4); + } + dataArray.set(x, y & 15, z, data); } - dataArray.set(x, y & 15, z, data); return; } } @Override - public void setBiome(int x, int z, BaseBiome biome) { - if (this.biomes == null) { - this.biomes = new byte[16][]; - } - byte[] index = this.biomes[x]; - if (index == null) { - index = this.biomes[x] = new byte[16]; - } - index[z] = (byte) biome.getId(); - } - - @Override - public FaweChunk copy(boolean shallow) { + public CharFaweChunk copy(boolean shallow) { ForgeChunk_All copy = new ForgeChunk_All(getParent(), getX(), getZ()); if (shallow) { - copy.ids = ids; + copy.byteIds = byteIds; copy.datas = datas; copy.air = air; copy.biomes = biomes; @@ -242,7 +161,7 @@ public class ForgeChunk_All extends FaweChunk { copy.count = count; copy.relight = relight; } else { - copy.ids = (byte[][]) MainUtil.copyNd(ids); + copy.byteIds = (byte[][]) MainUtil.copyNd(byteIds); copy.datas = datas.clone(); copy.air = air.clone(); copy.biomes = biomes.clone(); diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index 140a964e..09a1917b 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -2,20 +2,38 @@ package com.boydti.fawe.forge.v0; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.forge.ForgePlayer; +import com.boydti.fawe.object.BytePair; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.util.MathMan; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.play.server.S21PacketChunkData; import net.minecraft.server.MinecraftServer; @@ -32,10 +50,22 @@ import net.minecraft.world.chunk.NibbleArray; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.gen.ChunkProviderServer; -public class ForgeQueue_All extends NMSMappedFaweQueue { +public class ForgeQueue_All extends NMSMappedFaweQueue { - public ForgeQueue_All(final String world) { + private Method methodFromNative; + private Method methodToNative; + + public ForgeQueue_All(String world) { super(world); + try { + Class converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter"); + this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class); + this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class); + methodFromNative.setAccessible(true); + methodToNative.setAccessible(true); + } catch (Throwable e) { + throw new RuntimeException(e); + } } @Override @@ -44,12 +74,17 @@ public class ForgeQueue_All extends NMSMappedFaweQueue changeTask) { ForgeChunk_All fs = (ForgeChunk_All) fc; - Chunk forgeChunk = fs.getChunk(); - net.minecraft.world.World nmsWorld = forgeChunk.worldObj; + net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk(); + net.minecraft.world.World nmsWorld = nmsChunk.worldObj; try { boolean flag = !nmsWorld.provider.hasNoSky; // Sections - ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray(); - Map tiles = forgeChunk.chunkTileEntityMap; - List[] entities = forgeChunk.entityLists; + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + Map tiles = nmsChunk.chunkTileEntityMap; + List[] entities = nmsChunk.entityLists; + + // Remove entities + for (int i = 0; i < 16; i++) { + int count = fs.getCount(i); + if (count == 0) { + continue; + } else if (count >= 4096) { + entities[i].clear(); + } else { + char[] array = fs.getIdArray(i); + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entity instanceof EntityPlayer) { + continue; + } + int x = ((int) Math.round(entity.posX) & 15); + int z = ((int) Math.round(entity.posZ) & 15); + int y = (int) Math.round(entity.posY); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + nmsWorld.removeEntity(entity); + } + } + } + } + // Set entities + Set createdEntities = new HashSet<>(); + Set entitiesToSpawn = fs.getEntities(); + for (CompoundTag nativeTag : entitiesToSpawn) { + Map entityTagMap = nativeTag.getValue(); + StringTag idTag = (StringTag) entityTagMap.get("Id"); + ListTag posTag = (ListTag) entityTagMap.get("Pos"); + ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); + if (idTag == null || posTag == null || rotTag == null) { + Fawe.debug("Unknown entity tag: " + nativeTag); + continue; + } + double x = posTag.getDouble(0); + double y = posTag.getDouble(1); + double z = posTag.getDouble(2); + float yaw = rotTag.getFloat(0); + float pitch = rotTag.getFloat(1); + String id = idTag.getValue(); + NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(null, nativeTag); + Entity entity = EntityList.createEntityFromNBT(tag, nmsWorld); + if (entity != null) { + entity.setPositionAndRotation(x, y, z, yaw, pitch); + nmsWorld.spawnEntityInWorld(entity); + } + } + // Run change task if applicable + if (changeTask != null) { + CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false); + changeTask.run(previous); + } // Trim tiles Set> entryset = tiles.entrySet(); Iterator> iterator = entryset.iterator(); @@ -206,21 +300,33 @@ public class ForgeQueue_All extends NMSMappedFaweQueue entsToRemove = fs.getEntityRemoves(); + if (entsToRemove.size() > 0) { + for (int i = 0; i < entities.length; i++) { + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entsToRemove.contains(entity.getUniqueID())) { + nmsWorld.removeEntity(entity); + } + } + } + } // Efficiently merge sections for (int j = 0; j < sections.length; j++) { if (fs.getCount(j) == 0) { continue; } - byte[] newIdArray = fs.getIdArray(j); + byte[] newIdArray = fs.getByteIdArray(j); if (newIdArray == null) { continue; } @@ -232,8 +338,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue tilesToSpawn = fs.getTiles(); + int bx = fs.getX() << 4; + int bz = fs.getZ() << 4; + + for (Map.Entry entry : tilesToSpawn.entrySet()) { + CompoundTag nativeTag = entry.getValue(); + BytePair pair = entry.getKey(); + int x = MathMan.unpair16x(pair.pair[0]) + bx; + int y = pair.pair[1] & 0xFF; + int z = MathMan.unpair16y(pair.pair[0]) + bz; + TileEntity tileEntity = nmsWorld.getTileEntity(x, y, z); + if (tileEntity != null) { + NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag); + tileEntity.readFromNBT(tag); // ReadTagIntoTile + } + } } catch (Throwable e) { e.printStackTrace(); } - byte[][] biomes = fs.biomes; + int[][] biomes = fs.biomes; if (biomes != null) { for (int x = 0; x < 16; x++) { - byte[] array = biomes[x]; + int[] array = biomes[x]; if (array == null) { continue; } for (int z = 0; z < 16; z++) { - byte biome = array[z]; + int biome = array[z]; if (biome == 0) { continue; } - forgeChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = biome; + nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome; } } } - sendChunk(fs); + sendChunk(fs, null); return true; } + public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ExtendedBlockStorage section) throws NoSuchFieldException, IllegalAccessException { + Class clazz = section.getClass(); + Field fieldTickingBlockCount = clazz.getDeclaredField("field_76683_c"); // tickRefCount + Field fieldNonEmptyBlockCount = clazz.getDeclaredField("field_76682_b"); // blockRefCount + fieldTickingBlockCount.setAccessible(true); + fieldNonEmptyBlockCount.setAccessible(true); + fieldTickingBlockCount.set(section, tickingBlockCount); + fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount); + } + + @Override + public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map tilesGeneric, Collection[] entitiesGeneric, Set createdEntities, boolean all) throws Exception { + Map tiles = (Map) tilesGeneric; + Collection[] entities = (Collection[]) entitiesGeneric; + CharFaweChunk previous = (CharFaweChunk) getChunk(fs.getX(), fs.getZ()); + char[][] idPrevious = new char[16][]; + for (int layer = 0; layer < sections.length; layer++) { + if (fs.getCount(layer) != 0 || all) { + ExtendedBlockStorage section = sections[layer]; + if (section != null) { + byte[] currentIdArray = section.getBlockLSBArray(); + NibbleArray currentDataArray = section.getMetadataArray(); + char[] array = new char[4096]; + for (int j = 0; j < currentIdArray.length; j++) { + int x = FaweCache.CACHE_X[layer][j]; + int y = FaweCache.CACHE_Y[layer][j]; + int z = FaweCache.CACHE_Z[layer][j]; + int id = currentIdArray[j] & 0xFF; + byte data = (byte) currentDataArray.get(x, y & 15, z); + previous.setBlock(x, y, z, id, data); + } + } + } + } + previous.ids = idPrevious; + if (tiles != null) { + for (Map.Entry entry : tiles.entrySet()) { + TileEntity tile = entry.getValue(); + NBTTagCompound tag = new NBTTagCompound(); + tile.readFromNBT(tag); // readTileEntityIntoTag + ChunkPosition pos = entry.getKey(); + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + previous.setTile(pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, nativeTag); + } + } + if (entities != null) { + for (Collection entityList : entities) { + for (Entity ent : entityList) { + if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && !createdEntities.contains(ent.getUniqueID()))) { + continue; + } + int x = ((int) Math.round(ent.posX) & 15); + int z = ((int) Math.round(ent.posZ) & 15); + int y = (int) Math.round(ent.posY); + int i = FaweCache.CACHE_I[y][x][z]; + char[] array = fs.getIdArray(i); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + String id = EntityList.getEntityString(ent); + if (id != null) { + NBTTagCompound tag = ent.getEntityData(); // readEntityIntoTag + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + Map map = ReflectionUtils.getMap(nativeTag.getValue()); + map.put("Id", new StringTag(id)); + previous.setEntity(nativeTag); + } + } + } + } + } + return previous; + } + @Override public FaweChunk getChunk(int x, int z) { return new ForgeChunk_All(this, x, z); } @Override - public boolean fixLighting(FaweChunk chunk, boolean fixAll) { + public boolean fixLighting(FaweChunk fc, RelightMode mode) { + if (mode == RelightMode.NONE) { + return true; + } try { - ForgeChunk_All fc = (ForgeChunk_All) chunk; - Chunk forgeChunk = fc.getChunk(); - if (!forgeChunk.isChunkLoaded) { - forgeChunk.onChunkLoad(); + ForgeChunk_All bc = (ForgeChunk_All) fc; + net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk(); + if (!nmsChunk.isChunkLoaded) { + return false; } - forgeChunk.generateSkylightMap(); - if (fc.getTotalRelight() == 0 && !fixAll) { + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + if (mode == RelightMode.ALL) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + section.setSkylightArray(new NibbleArray(4096, 4)); + section.setBlocklightArray(new NibbleArray(4096, 4)); + } + } + } + nmsChunk.generateSkylightMap(); + if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) { return true; } - ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray(); - net.minecraft.world.World nmsWorld = forgeChunk.worldObj; + net.minecraft.world.World nmsWorld = nmsChunk.worldObj; int X = fc.getX() << 4; int Z = fc.getZ() << 4; - for (int j = 0; j < sections.length; j++) { ExtendedBlockStorage section = sections[j]; if (section == null) { continue; } - if ((fc.getRelight(j) == 0 && !fixAll) || fc.getCount(j) == 0 || (fc.getCount(j) >= 4096 && fc.getAir(j) == 0)) { + if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) { continue; } byte[] array = section.getBlockLSBArray(); - int l = PseudoRandom.random.random(2); - for (int k = 0; k < array.length; k++) { - int i = array[k]; - if (i < 16) { - continue; + if (mode == RelightMode.ALL) { + for (int k = array.length - 1; k >= 0; k--) { + final int x = FaweCache.CACHE_X[j][k]; + final int y = FaweCache.CACHE_Y[j][k]; + final int z = FaweCache.CACHE_Z[j][k]; + if (isSurrounded(sections, x, y, z)) { + continue; + } + nmsWorld.func_147451_t(X + x, y, Z + z); } - short id = (short) (i); + continue; + } + for (int k = array.length - 1; k >= 0; k--) { + final int i = array[k]; + final short id = (short) (i >> 4); switch (id) { // Lighting + case 0: + continue; default: - if (!fixAll) { + if (mode == RelightMode.MINIMAL) { continue; } - if ((k & 1) == l) { - l = 1 - l; + if (PseudoRandom.random.random(3) != 0) { continue; } case 10: @@ -358,9 +598,9 @@ public class ForgeQueue_All extends NMSMappedFaweQueue { super(parent); } + @Override + public void sendTitle(String head, String sub) { // Not supported + Settings.DISPLAY_PROGRESS = false; + } + + @Override + public void resetTitle() { // Not supported + Settings.DISPLAY_PROGRESS = false; + } + @Override public String getName() { return parent.getName(); diff --git a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index 7c59c9b1..2cd59129 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -2,18 +2,36 @@ package com.boydti.fawe.forge.v0; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.forge.ForgePlayer; +import com.boydti.fawe.object.BytePair; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.PseudoRandom; +import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.util.MathMan; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.UUID; import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.play.server.S21PacketChunkData; import net.minecraft.server.MinecraftServer; @@ -25,13 +43,26 @@ import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.chunk.NibbleArray; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.gen.ChunkProviderServer; -public class ForgeQueue_All extends NMSMappedFaweQueue { +public class ForgeQueue_All extends NMSMappedFaweQueue { - public ForgeQueue_All(final String world) { + private Method methodFromNative; + private Method methodToNative; + + public ForgeQueue_All(String world) { super(world); + try { + Class converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter"); + this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class); + this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class); + methodFromNative.setAccessible(true); + methodToNative.setAccessible(true); + } catch (Throwable e) { + throw new RuntimeException(e); + } } @Override @@ -89,12 +120,18 @@ public class ForgeQueue_All extends NMSMappedFaweQueue clazz = section.getClass(); + Field fieldTickingBlockCount = clazz.getDeclaredField("field_76683_c"); + Field fieldNonEmptyBlockCount = clazz.getDeclaredField("field_76682_b"); + fieldTickingBlockCount.setAccessible(true); + fieldNonEmptyBlockCount.setAccessible(true); + fieldTickingBlockCount.set(section, tickingBlockCount); + fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount); + } + @Override - public boolean setComponents(FaweChunk fc) { - ForgeChunk_All fs = (ForgeChunk_All) fc; - Chunk forgeChunk = fs.getChunk(); - net.minecraft.world.World nmsWorld = forgeChunk.getWorld(); + public boolean fixLighting(FaweChunk fc, RelightMode mode) { + if (mode == RelightMode.NONE) { + return true; + } + try { + CharFaweChunk bc = (CharFaweChunk) fc; + Chunk nmsChunk = bc.getChunk(); + if (!nmsChunk.isLoaded()) { + return false; + } + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + if (mode == RelightMode.ALL) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + section.setSkylightArray(new NibbleArray()); + section.setBlocklightArray(new NibbleArray()); + } + } + } + nmsChunk.generateSkylightMap(); + if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) { + return true; + } + net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); + + int X = fc.getX() << 4; + int Z = fc.getZ() << 4; + + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0); + for (int j = 0; j < sections.length; j++) { + ExtendedBlockStorage section = sections[j]; + if (section == null) { + continue; + } + if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) { + continue; + } + char[] array = section.getData(); + if (mode == RelightMode.ALL) { + for (int k = array.length - 1; k >= 0; k--) { + final int x = FaweCache.CACHE_X[j][k]; + final int y = FaweCache.CACHE_Y[j][k]; + final int z = FaweCache.CACHE_Z[j][k]; + if (isSurrounded(sections, x, y, z)) { + continue; + } + pos.set(X + x, y, Z + z); + nmsWorld.checkLight(pos); + } + continue; + } + for (int k = array.length - 1; k >= 0; k--) { + final int i = array[k]; + final short id = (short) (i >> 4); + switch (id) { // Lighting + case 0: + continue; + default: + if (mode == RelightMode.MINIMAL) { + continue; + } + if (PseudoRandom.random.random(3) != 0) { + continue; + } + case 10: + case 11: + case 39: + case 40: + case 50: + case 51: + case 62: + case 74: + case 76: + case 89: + case 122: + case 124: + case 130: + case 138: + case 169: + final int x = FaweCache.CACHE_X[j][k]; + final int y = FaweCache.CACHE_Y[j][k]; + final int z = FaweCache.CACHE_Z[j][k]; + if (isSurrounded(sections, x, y, z)) { + continue; + } + pos.set(X + x, y, Z + z); + nmsWorld.checkLight(pos); + } + } + } + return true; + } catch (Throwable e) { + if (Thread.currentThread() == Fawe.get().getMainThread()) { + e.printStackTrace(); + } + } + return false; + } + + @Override + public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map tilesGeneric, Collection[] entitiesGeneric, Set createdEntities, boolean all) throws Exception { + Map tiles = (Map) tilesGeneric; + ClassInheritanceMultiMap[] entities = (ClassInheritanceMultiMap[]) entitiesGeneric; + CharFaweChunk previous = (CharFaweChunk) getChunk(fs.getX(), fs.getZ()); + char[][] idPrevious = new char[16][]; + for (int layer = 0; layer < sections.length; layer++) { + if (fs.getCount(layer) != 0 || all) { + ExtendedBlockStorage section = sections[layer]; + if (section != null) { + idPrevious[layer] = section.getData().clone(); + short solid = 0; + for (int combined : idPrevious[layer]) { + if (combined > 1) { + solid++; + } + } + previous.count[layer] = 4096; + previous.air[layer] = (short) (4096 - solid); + } + } + } + previous.ids = idPrevious; + if (tiles != null) { + for (Map.Entry entry : tiles.entrySet()) { + TileEntity tile = entry.getValue(); + NBTTagCompound tag = new NBTTagCompound(); + tile.readFromNBT(tag); // readTileEntityIntoTag + BlockPos pos = entry.getKey(); + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + previous.setTile(pos.getX(), pos.getY(), pos.getZ(), nativeTag); + } + } + if (entities != null) { + for (Collection entityList : entities) { + for (Entity ent : entityList) { + if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && !createdEntities.contains(ent.getUniqueID()))) { + continue; + } + int x = ((int) Math.round(ent.posX) & 15); + int z = ((int) Math.round(ent.posZ) & 15); + int y = (int) Math.round(ent.posY); + int i = FaweCache.CACHE_I[y][x][z]; + char[] array = fs.getIdArray(i); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + String id = EntityList.getEntityString(ent); + if (id != null) { + NBTTagCompound tag = ent.getNBTTagCompound(); // readEntityIntoTag + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + Map map = ReflectionUtils.getMap(nativeTag.getValue()); + map.put("Id", new StringTag(id)); + previous.setEntity(nativeTag); + } + } + } + } + } + return previous; + } + + @Override + public boolean setComponents(FaweChunk fc, RunnableVal changeTask) { + CharFaweChunk fs = (CharFaweChunk) fc; + net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk(); + net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); try { boolean flag = !nmsWorld.provider.getHasNoSky(); // Sections - ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray(); - Map tiles = forgeChunk.getTileEntityMap(); - ClassInheritanceMultiMap[] entities = forgeChunk.getEntityLists(); + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + Map tiles = nmsChunk.getTileEntityMap(); + ClassInheritanceMultiMap[] entities = nmsChunk.getEntityLists(); + + + // Remove entities + for (int i = 0; i < 16; i++) { + int count = fs.getCount(i); + if (count == 0) { + continue; + } else if (count >= 4096) { + entities[i] = new ClassInheritanceMultiMap<>(Entity.class); + } else { + char[] array = fs.getIdArray(i); + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entity instanceof EntityPlayer) { + continue; + } + int x = ((int) Math.round(entity.posX) & 15); + int z = ((int) Math.round(entity.posZ) & 15); + int y = (int) Math.round(entity.posY); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + nmsWorld.removeEntity(entity); + } + } + } + } + // Set entities + Set createdEntities = new HashSet<>(); + Set entitiesToSpawn = fs.getEntities(); + for (CompoundTag nativeTag : entitiesToSpawn) { + Map entityTagMap = nativeTag.getValue(); + StringTag idTag = (StringTag) entityTagMap.get("Id"); + ListTag posTag = (ListTag) entityTagMap.get("Pos"); + ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); + if (idTag == null || posTag == null || rotTag == null) { + Fawe.debug("Unknown entity tag: " + nativeTag); + continue; + } + double x = posTag.getDouble(0); + double y = posTag.getDouble(1); + double z = posTag.getDouble(2); + float yaw = rotTag.getFloat(0); + float pitch = rotTag.getFloat(1); + String id = idTag.getValue(); + NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(null, nativeTag); + Entity entity = EntityList.createEntityFromNBT(tag, nmsWorld); + if (entity != null) { + entity.setPositionAndRotation(x, y, z, yaw, pitch); + nmsWorld.spawnEntityInWorld(entity); + } + } + // Run change task if applicable + if (changeTask != null) { + CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false); + changeTask.run(previous); + } // Trim tiles Set> entryset = tiles.entrySet(); Iterator> iterator = entryset.iterator(); @@ -128,24 +399,31 @@ public class ForgeQueue_All extends NMSMappedFaweQueue= 4096)) { - entities[i] = new ClassInheritanceMultiMap<>(Entity.class); + HashSet entsToRemove = fs.getEntityRemoves(); + if (entsToRemove.size() > 0) { + for (int i = 0; i < entities.length; i++) { + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entsToRemove.contains(entity.getUniqueID())) { + nmsWorld.removeEntity(entity); + } + } } } // Efficiently merge sections for (int j = 0; j < sections.length; j++) { - if (fs.getCount(j) == 0) { + int count = fs.getCount(j); + if (count == 0) { continue; } char[] newArray = fs.getIdArray(j); @@ -153,14 +431,20 @@ public class ForgeQueue_All extends NMSMappedFaweQueue= 4096)) { + + if ((section == null)) { section = new ExtendedBlockStorage(j << 4, flag); section.setData(newArray); sections[j] = section; continue; + } else if (count >= 4096){ + section.setData(newArray); + setCount(0, count - fs.getAir(j), section); + continue; } char[] currentArray = section.getData(); boolean fill = true; + int solid = 0; for (int k = 0; k < newArray.length; k++) { char n = newArray[k]; switch (n) { @@ -169,18 +453,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue 1) { + solid++; + } currentArray[k] = 0; continue; default: + solid++; currentArray[k] = n; continue; } } + setCount(0, solid, section); if (fill) { fs.setCount(j, Short.MAX_VALUE); } } -// // Clear + + // Set biomes + int[][] biomes = fs.biomes; + if (biomes != null) { + for (int x = 0; x < 16; x++) { + int[] array = biomes[x]; + if (array == null) { + continue; + } + for (int z = 0; z < 16; z++) { + int biome = array[z]; + if (biome == 0) { + continue; + } + nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome; + } + } + } + // Set tiles + Map tilesToSpawn = fs.getTiles(); + int bx = fs.getX() << 4; + int bz = fs.getZ() << 4; + + for (Map.Entry entry : tilesToSpawn.entrySet()) { + CompoundTag nativeTag = entry.getValue(); + BytePair pair = entry.getKey(); + BlockPos pos = new BlockPos(MathMan.unpair16x(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos + TileEntity tileEntity = nmsWorld.getTileEntity(pos); + if (tileEntity != null) { + NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag); + tileEntity.readFromNBT(tag); // ReadTagIntoTile + } + } } catch (Throwable e) { e.printStackTrace(); } @@ -196,11 +517,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue= 4096 && fc.getAir(j) == 0)) { - continue; - } - char[] array = section.getData(); - int l = PseudoRandom.random.random(2); - for (int k = 0; k < array.length; k++) { - int i = array[k]; - if (i < 16) { - continue; - } - short id = (short) (i >> 4); - switch (id) { // Lighting - default: - if (!fixAll) { - continue; - } - if ((k & 1) == l) { - l = 1 - l; - continue; - } - case 10: - case 11: - case 39: - case 40: - case 50: - case 51: - case 62: - case 74: - case 76: - case 89: - case 122: - case 124: - case 130: - case 138: - case 169: - int x = FaweCache.CACHE_X[j][k]; - int y = FaweCache.CACHE_Y[j][k]; - int z = FaweCache.CACHE_Z[j][k]; - if (isSurrounded(sections, x, y, z)) { - continue; - } - BlockPos pos = new BlockPos(X + x, y, Z + z); - nmsWorld.checkLight(pos); - } - } - } - return true; - } catch (Throwable e) { - if (Thread.currentThread() == Fawe.get().getMainThread()) { - e.printStackTrace(); - } - } - return false; - } - public boolean isSurrounded(ExtendedBlockStorage[] sections, int x, int y, int z) { return isSolid(getId(sections, x, y + 1, z)) && isSolid(getId(sections, x + 1, y - 1, z)) diff --git a/pom.xml b/pom.xml index c6e0e232..696b96a1 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ UTF-8 FastAsyncWorldEdit - 3.4.3 + 3.5.0 FastAsyncWorldEdit jar 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 4ebaa1b3..7ce6b755 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java @@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.IFawe; import com.boydti.fawe.SpongeCommand; import com.boydti.fawe.config.BBC; +import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.EditSessionWrapper; import com.boydti.fawe.object.FaweCommand; import com.boydti.fawe.object.FawePlayer; @@ -109,7 +110,7 @@ public class FaweSponge implements IFawe { @Override public FaweQueue getNewQueue(String world, boolean fast) { - if (fast) { + if (fast || Settings.COMBINE_HISTORY_STAGE) { try { return new SpongeQueue_1_8(world); } catch (Throwable e) { diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java index 79bda8c9..94fd5728 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java @@ -18,7 +18,7 @@ import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.profile.GameProfileManager; import org.spongepowered.api.world.World; -@Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.4.3", authors = "Empire92") +@Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.5.0", authors = "Empire92") public class SpongeMain { public PluginContainer plugin; diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java b/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java index c9780bc2..49a6e435 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java @@ -8,7 +8,9 @@ import java.util.UUID; import net.minecraft.entity.player.EntityPlayerMP; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.text.Text; import org.spongepowered.api.text.serializer.TextSerializers; +import org.spongepowered.api.text.title.Title; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; @@ -17,6 +19,19 @@ public class SpongePlayer extends FawePlayer { super(parent); } + @Override + public void sendTitle(String head, String sub) { // Not supported + Text headText = TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(head)); + Text subText = TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(sub)); + final Title title = Title.builder().title(headText).subtitle(subText).fadeIn(0).stay(60).fadeOut(20).build(); + parent.sendTitle(title); + } + + @Override + public void resetTitle() { // Not supported + parent.resetTitle(); + } + @Override public String getName() { return this.parent.getName(); diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java index ed37998e..c86e529f 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java @@ -2,17 +2,35 @@ package com.boydti.fawe.sponge.v1_8; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.NMSMappedFaweQueue; +import com.boydti.fawe.object.BytePair; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.PseudoRandom; +import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.util.MathMan; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.play.server.S21PacketChunkData; import net.minecraft.tileentity.TileEntity; @@ -21,6 +39,7 @@ import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.util.LongHashMap; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.chunk.NibbleArray; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import net.minecraft.world.gen.ChunkProviderServer; import org.spongepowered.api.Sponge; @@ -30,8 +49,20 @@ import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; public class SpongeQueue_1_8 extends NMSMappedFaweQueue { + private Method methodFromNative; + private Method methodToNative; + public SpongeQueue_1_8(String world) { super(world); + try { + Class converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter"); + this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class); + this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class); + methodFromNative.setAccessible(true); + methodToNative.setAccessible(true); + } catch (Throwable e) { + throw new RuntimeException(e); + } } @Override @@ -120,7 +151,71 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue tilesGeneric, Collection[] entitiesGeneric, Set createdEntities, boolean all) throws Exception { + Map tiles = (Map) tilesGeneric; + ClassInheritanceMultiMap[] entities = (ClassInheritanceMultiMap[]) entitiesGeneric; + CharFaweChunk previous = (CharFaweChunk) getChunk(fs.getX(), fs.getZ()); + char[][] idPrevious = new char[16][]; + for (int layer = 0; layer < sections.length; layer++) { + if (fs.getCount(layer) != 0 || all) { + ExtendedBlockStorage section = sections[layer]; + if (section != null) { + idPrevious[layer] = section.getData().clone(); + short solid = 0; + for (int combined : idPrevious[layer]) { + if (combined > 1) { + solid++; + } + } + previous.count[layer] = solid; + previous.air[layer] = (short) (4096 - solid); + } + } + } + previous.ids = idPrevious; + if (tiles != null) { + for (Map.Entry entry : tiles.entrySet()) { + TileEntity tile = entry.getValue(); + NBTTagCompound tag = new NBTTagCompound(); + tile.readFromNBT(tag); // readTileEntityIntoTag + BlockPos pos = entry.getKey(); + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + previous.setTile(pos.getX(), pos.getY(), pos.getZ(), nativeTag); + } + } + if (entities != null) { + for (Collection entityList : entities) { + for (Entity ent : entityList) { + if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && !createdEntities.contains(ent.getUniqueID()))) { + continue; + } + int x = ((int) Math.round(ent.posX) & 15); + int z = ((int) Math.round(ent.posZ) & 15); + int y = (int) Math.round(ent.posY); + int i = FaweCache.CACHE_I[y][x][z]; + char[] array = fs.getIdArray(i); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + String id = EntityList.getEntityString(ent); + if (id != null) { + NBTTagCompound tag = ent.getNBTTagCompound(); // readEntityIntoTag + CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag); + Map map = ReflectionUtils.getMap(nativeTag.getValue()); + map.put("Id", new StringTag(id)); + previous.setEntity(nativeTag); + } + } + } + } + } + return previous; + } + + @Override + public boolean setComponents(FaweChunk fc, RunnableVal changeTask) { SpongeChunk_1_8 fs = (SpongeChunk_1_8) fc; net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk(); net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); @@ -130,6 +225,65 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue tiles = nmsChunk.getTileEntityMap(); ClassInheritanceMultiMap[] entities = nmsChunk.getEntityLists(); + + + // Remove entities + for (int i = 0; i < 16; i++) { + int count = fs.getCount(i); + if (count == 0) { + continue; + } else if (count >= 4096) { + entities[i] = new ClassInheritanceMultiMap<>(Entity.class); + } else { + char[] array = fs.getIdArray(i); + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entity instanceof EntityPlayer) { + continue; + } + int x = ((int) Math.round(entity.posX) & 15); + int z = ((int) Math.round(entity.posZ) & 15); + int y = (int) Math.round(entity.posY); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][x][z]; + if (array[j] != 0) { + nmsWorld.removeEntity(entity); + } + } + } + } + // Set entities + Set createdEntities = new HashSet<>(); + Set entitiesToSpawn = fs.getEntities(); + for (CompoundTag nativeTag : entitiesToSpawn) { + Map entityTagMap = nativeTag.getValue(); + StringTag idTag = (StringTag) entityTagMap.get("Id"); + ListTag posTag = (ListTag) entityTagMap.get("Pos"); + ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); + if (idTag == null || posTag == null || rotTag == null) { + Fawe.debug("Unknown entity tag: " + nativeTag); + continue; + } + double x = posTag.getDouble(0); + double y = posTag.getDouble(1); + double z = posTag.getDouble(2); + float yaw = rotTag.getFloat(0); + float pitch = rotTag.getFloat(1); + String id = idTag.getValue(); + NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(null, nativeTag); + Entity entity = EntityList.createEntityFromNBT(tag, nmsWorld); + if (entity != null) { + entity.setPositionAndRotation(x, y, z, yaw, pitch); + nmsWorld.spawnEntityInWorld(entity); + } + } + // Run change task if applicable + if (changeTask != null) { + CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false); + changeTask.run(previous); + } // Trim tiles Set> entryset = tiles.entrySet(); Iterator> iterator = entryset.iterator(); @@ -140,19 +294,25 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue= 4096)) { - entities[i] = new ClassInheritanceMultiMap<>(Entity.class); + HashSet entsToRemove = fs.getEntityRemoves(); + if (entsToRemove.size() > 0) { + for (int i = 0; i < entities.length; i++) { + Collection ents = new ArrayList<>(entities[i]); + for (Entity entity : ents) { + if (entsToRemove.contains(entity.getUniqueID())) { + nmsWorld.removeEntity(entity); + } + } } } // Efficiently merge sections @@ -204,6 +364,39 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue tilesToSpawn = fs.getTiles(); + int bx = fs.getX() << 4; + int bz = fs.getZ() << 4; + + for (Map.Entry entry : tilesToSpawn.entrySet()) { + CompoundTag nativeTag = entry.getValue(); + BytePair pair = entry.getKey(); + BlockPos pos = new BlockPos(MathMan.unpair16x(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos + TileEntity tileEntity = nmsWorld.getTileEntity(pos); + if (tileEntity != null) { + NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag); + tileEntity.readFromNBT(tag); // ReadTagIntoTile + } + } } catch (Throwable e) { e.printStackTrace(); } @@ -223,7 +416,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue fc, RelightMode mode) { + if (mode == RelightMode.NONE) { + return true; + } try { SpongeChunk_1_8 bc = (SpongeChunk_1_8) fc; net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk(); if (!nmsChunk.isLoaded()) { - if (!((Chunk) nmsChunk).loadChunk(false)) { - return false; + return false; + } + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + if (mode == RelightMode.ALL) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + section.setSkylightArray(new NibbleArray()); + section.setBlocklightArray(new NibbleArray()); + } } } nmsChunk.generateSkylightMap(); - if (bc.getTotalRelight() == 0 && !fixAll) { + if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) { return true; } - ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); - int X = bc.getX() << 4; - int Z = bc.getZ() << 4; - + int X = fc.getX() << 4; + int Z = fc.getZ() << 4; + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0); for (int j = 0; j < sections.length; j++) { ExtendedBlockStorage section = sections[j]; if (section == null) { continue; } - if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) { + if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) { continue; } char[] array = section.getData(); - int l = PseudoRandom.random.random(2); - for (int k = 0; k < array.length; k++) { - int i = array[k]; - if (i < 16) { - continue; + if (mode == RelightMode.ALL) { + for (int k = array.length - 1; k >= 0; k--) { + final int x = FaweCache.CACHE_X[j][k]; + final int y = FaweCache.CACHE_Y[j][k]; + final int z = FaweCache.CACHE_Z[j][k]; + if (isSurrounded(sections, x, y, z)) { + continue; + } + pos.set(X + x, y, Z + z); + nmsWorld.checkLight(pos); } - short id = (short) (i >> 4); + continue; + } + for (int k = array.length - 1; k >= 0; k--) { + final int i = array[k]; + final short id = (short) (i >> 4); switch (id) { // Lighting + case 0: + continue; default: - if (!fixAll) { + if (mode == RelightMode.MINIMAL) { continue; } - if ((k & 1) == l) { - l = 1 - l; + if (PseudoRandom.random.random(3) != 0) { continue; } case 10: @@ -304,13 +517,13 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue changeTask) { + if (changeTask != null) { + Settings.COMBINE_HISTORY_STAGE = false; + throw new UnsupportedOperationException("Combine stages not supported"); + } SpongeChunk_1_8 fs = (SpongeChunk_1_8) fc; net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk(); Chunk spongeChunk = (Chunk) nmsChunk; @@ -162,7 +173,7 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue tilesGeneric, Collection[] entitiesGeneric, Set createdEntities, boolean all) throws Exception { + Settings.COMBINE_HISTORY_STAGE = false; + throw new UnsupportedOperationException("Combine stages not supported"); + } @Override - public boolean fixLighting(FaweChunk fc, boolean fixAll) { + public boolean fixLighting(FaweChunk fc, RelightMode mode) { + if (mode == RelightMode.NONE) { + return true; + } try { SpongeChunk_1_8 bc = (SpongeChunk_1_8) fc; net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk(); if (!nmsChunk.isLoaded()) { - if (!((Chunk) nmsChunk).loadChunk(false)) { - return false; + return false; + } + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + if (mode == RelightMode.ALL) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + section.setSkylightArray(new NibbleArray()); + section.setBlocklightArray(new NibbleArray()); + } } } nmsChunk.generateSkylightMap(); - if (bc.getTotalRelight() == 0 && !fixAll) { + if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) { return true; } - ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); - int X = bc.getX() << 4; - int Z = bc.getZ() << 4; - + int X = fc.getX() << 4; + int Z = fc.getZ() << 4; + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0); for (int j = 0; j < sections.length; j++) { ExtendedBlockStorage section = sections[j]; if (section == null) { continue; } - if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) { + if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) { continue; } char[] array = section.getData(); - int l = PseudoRandom.random.random(2); - for (int k = 0; k < array.length; k++) { - int i = array[k]; - if (i < 16) { - continue; + if (mode == RelightMode.ALL) { + for (int k = array.length - 1; k >= 0; k--) { + final int x = FaweCache.CACHE_X[j][k]; + final int y = FaweCache.CACHE_Y[j][k]; + final int z = FaweCache.CACHE_Z[j][k]; + if (isSurrounded(sections, x, y, z)) { + continue; + } + pos.set(X + x, y, Z + z); + nmsWorld.checkLight(pos); } - short id = (short) (i >> 4); + continue; + } + for (int k = array.length - 1; k >= 0; k--) { + final int i = array[k]; + final short id = (short) (i >> 4); switch (id) { // Lighting + case 0: + continue; default: - if (!fixAll) { + if (mode == RelightMode.MINIMAL) { continue; } - if ((k & 1) == l) { - l = 1 - l; + if (PseudoRandom.random.random(3) != 0) { continue; } case 10: @@ -243,13 +279,13 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue