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 cc4ac53b..0913f688 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -88,7 +88,7 @@ public class FaweBukkit implements IFawe, Listener { public void setupInjector() { if (Bukkit.getPluginManager().getPlugin("WorldEdit") != null) { - Fawe.get().setupInjector(); + Fawe.setupInjector(); // Inject EditSessionBlockChangeDelegate.inject(); } else { diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index b1e92758..ca759cb4 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -229,7 +229,6 @@ public class Fawe { MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.PATHS.CLIPBOARD), TimeUnit.DAYS.toMillis(Settings.CLIPBOARD.DELETE_AFTER_DAYS)); TaskManager.IMP = this.IMP.getTaskManager(); - TaskManager.IMP.repeat(timer = new FaweTimer(), 1); if (Settings.METRICS) { this.IMP.startMetrics(); } @@ -238,22 +237,32 @@ public class Fawe { * Instance independent stuff */ this.setupMemoryListener(); + timer = new FaweTimer(); + Fawe.this.IMP.setupVault(); + Commands.load(new File(this.IMP.getDirectory(), "commands.yml")); - // Delayed event setup + // Delayed worldedit setup TaskManager.IMP.later(new Runnable() { @Override public void run() { - // Events - Fawe.this.IMP.setupVault(); + try { + WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers()); + WEManager.IMP.managers.add(new PlotSquaredFeature()); + Fawe.debug("Plugin 'PlotSquared' found. Using it now."); + } catch (Throwable e) {} + Fawe.this.worldedit = WorldEdit.getInstance(); + Fawe.this.setupEvents(); } }, 0); + TaskManager.IMP.repeat(timer, 1); + if (Settings.UPDATE) { // Delayed updating TaskManager.IMP.async(new Runnable() { @Override public void run() { - Updater.update(implementation.getPlatform(), getVersion()); + Updater.update(IMP.getPlatform(), getVersion()); } }); } @@ -326,28 +335,15 @@ public class Fawe { return this.worldedit; } - public void setupInjector() { + public static void setupInjector() { /* * Modify the sessions * - EditSession supports custom queue and a lot of optimizations * - LocalSession supports VirtualPlayers and undo on disk */ try { - // Delayed worldedit setup - TaskManager.IMP.later(new Runnable() { - @Override - public void run() { - try { - WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers()); - WEManager.IMP.managers.add(new PlotSquaredFeature()); - Fawe.debug("Plugin 'PlotSquared' found. Using it now."); - } catch (Throwable e) {} - Fawe.this.worldedit = WorldEdit.getInstance(); - Fawe.this.setupEvents(); - } - }, 0); // Setting up commands.yml - Commands.load(new File(this.IMP.getDirectory(), "commands.yml")); + Commands.inject(); // Translations EditSession.inject(); // Custom block placer + optimizations EditSessionEvent.inject(); // Add EditSession to event (API) LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk @@ -464,12 +460,7 @@ public class Fawe { MainUtil.handleError(e, false); debug("======================================="); debug("Update the plugin, or contact the Author!"); - if (IMP.getPlatform().equals("bukkit")) { - debug(" - http://builds.enginehub.org/job/worldedit?branch=master"); - } else { - debug(" - http://builds.enginehub.org/job/worldedit?branch=forge-archive%2F1.8.9 (FORGE)"); - debug(" - https://ci.minecrell.net/job/worldedit-spongevanilla/ (SV)"); - } + debug(" - http://builds.enginehub.org/job/worldedit?branch=master"); debug("======================================="); } } catch (Throwable e) { @@ -519,7 +510,7 @@ public class Fawe { debug("===================================="); } } catch (Throwable ignore) {} - if (!isJava8) { + if (MainUtil.getJavaVersion() < 1.8) { debug("====== UPGRADE TO JAVA 8 ======"); debug("You are running " + System.getProperty("java.version")); debug(" - This is only a recommendation"); diff --git a/core/src/main/java/com/boydti/fawe/config/Commands.java b/core/src/main/java/com/boydti/fawe/config/Commands.java index cd178c68..d0165335 100644 --- a/core/src/main/java/com/boydti/fawe/config/Commands.java +++ b/core/src/main/java/com/boydti/fawe/config/Commands.java @@ -122,4 +122,8 @@ public class Commands { return command.anyFlags(); } } + + public static Class inject() { + return Commands.class; + } } diff --git a/core/src/main/java/com/boydti/fawe/database/RollbackDatabase.java b/core/src/main/java/com/boydti/fawe/database/RollbackDatabase.java index 03578901..68cce46b 100644 --- a/core/src/main/java/com/boydti/fawe/database/RollbackDatabase.java +++ b/core/src/main/java/com/boydti/fawe/database/RollbackDatabase.java @@ -50,7 +50,7 @@ public class RollbackDatabase { this.prefix = ""; this.worldName = Fawe.imp().getWorldName(world); this.world = world; - this.dbLocation = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.PATHS.HISTORY + File.separator + world.getName() + File.separator + "summary.db"); + this.dbLocation = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.PATHS.HISTORY + File.separator + Fawe.imp().getWorldName(world) + File.separator + "summary.db"); connection = openConnection(); CREATE_TABLE = "CREATE TABLE IF NOT EXISTS `" + prefix + "edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL,`x1` INT NOT NULL,`y1` INT NOT NULL,`z1` INT NOT NULL,`x2` INT NOT NULL,`y2` INT NOT NULL,`z2` INT NOT NULL,`time` INT NOT NULL, PRIMARY KEY (player, id))"; INSERT_EDIT = "INSERT OR REPLACE INTO `" + prefix + "edits` (`player`,`id`,`x1`,`y1`,`z1`,`x2`,`y2`,`z2`,`time`) VALUES(?,?,?,?,?,?,?,?,?)"; diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index c27782a4..36c056b4 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -202,7 +202,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting } public EditSession(@Nullable String worldName, @Nullable World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) { - this.worldName = worldName == null ? world == null ? queue == null ? "" : queue.getWorldName() : world.getName() : worldName; + this.worldName = worldName == null ? world == null ? queue == null ? "" : queue.getWorldName() : Fawe.imp().getWorldName(world) : worldName; if (world == null && this.worldName != null) world = FaweAPI.getWorld(this.worldName); this.world = world = WorldWrapper.wrap((AbstractWorld) world); if (bus == null) { diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 45e53663..de39ffcc 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -183,7 +183,7 @@ public class ClipboardCommands { BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard); clipboard.setOrigin(session.getPlacementPosition(player)); session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData())); - BBC.COMMAND_CUT_SLOW.send(player, region.getArea()); + BBC.COMMAND_CUT_LAZY.send(player, region.getArea()); } @Command( @@ -221,7 +221,7 @@ public class ClipboardCommands { Operations.completeLegacy(copy); session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData())); - BBC.COMMAND_CUT_LAZY.send(player, region.getArea()); + BBC.COMMAND_CUT_SLOW.send(player, region.getArea()); } @Command(aliases = { "download" }, desc = "Download your clipboard") 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 4a252f91..9705ee09 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -61,7 +61,6 @@ import java.util.List; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; import static com.google.common.base.Preconditions.checkNotNull; @@ -356,7 +355,6 @@ public class SchematicCommands { build.append(file.getName()); } else { String relative = dir.toURI().relativize(file.toURI()).getPath(); - String[] split = file.getPath().split(Pattern.quote(prefix + File.separator)); build.append(relative); } build.append(": ").append(format == null ? "Unknown" : format.name()); diff --git a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index e562feef..1601d227 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -89,7 +89,6 @@ public class SelectionCommands { @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException { - Vector pos; if (args.argsLength() == 1) { @@ -122,7 +121,6 @@ public class SelectionCommands { @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException { - Vector pos; if (args.argsLength() == 1) { if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { @@ -156,7 +154,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.selection.hpos") public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException { - Vector pos = player.getBlockTrace(300); if (pos != null) { @@ -181,7 +178,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.selection.hpos") public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException { - Vector pos = player.getBlockTrace(300); if (pos != null) { @@ -275,7 +271,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.wand") public void wand(Player player, LocalSession session, CommandContext args) throws WorldEditException { - player.giveItem(we.getConfiguration().wandItem, 1); BBC.SELECTION_WAND.send(player); BBC.TIP_SEL_LIST.or(BBC.TIP_SELECT_CONNECTED, BBC.TIP_SET_POS1, BBC.TIP_FARWAND).send(player); @@ -290,7 +285,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.wand.toggle") public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException { - session.setToolControl(!session.isToolControlEnabled()); if (session.isToolControlEnabled()) { @@ -310,7 +304,6 @@ public class SelectionCommands { @Logging(REGION) @CommandPermissions("worldedit.selection.expand") public void expand(Player player, LocalSession session, CommandContext args) throws WorldEditException { - // Special syntax (//expand vert) to expand the selection between // sky and bedrock. if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) { @@ -402,7 +395,6 @@ public class SelectionCommands { @Logging(REGION) @CommandPermissions("worldedit.selection.contract") public void contract(Player player, LocalSession session, CommandContext args) throws WorldEditException { - List dirs = new ArrayList(); int change = args.getInteger(0); int reverseChange = 0; @@ -476,7 +468,6 @@ public class SelectionCommands { @Logging(REGION) @CommandPermissions("worldedit.selection.shift") public void shift(Player player, LocalSession session, CommandContext args) throws WorldEditException { - List dirs = new ArrayList(); int change = args.getInteger(0); if (args.argsLength() == 2) { @@ -582,7 +573,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.selection.size") public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException { - if (args.hasFlag('c')) { ClipboardHolder holder = session.getClipboard(); Clipboard clipboard = holder.getClipboard(); @@ -626,7 +616,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.analysis.count") public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - boolean useData = args.hasFlag('d'); if (args.getString(0).contains(":")) { useData = true; //override d flag, if they specified data they want it @@ -656,7 +645,6 @@ public class SelectionCommands { ) @CommandPermissions("worldedit.analysis.distr") public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException { - int size; boolean useData = args.hasFlag('d'); List> distribution = null; diff --git a/core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java b/core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java index 84bcd24a..b15329b7 100644 --- a/core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java +++ b/core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java @@ -162,7 +162,7 @@ public class BundledBlockData { } FaweState dir = entry.states.get("rotation"); if (dir != null && dir.values != null) { - Vector[] dirs = new Vector[]{new Vector(0, 0, -1), + Vector[] range = new Vector[]{new Vector(0, 0, -1), new Vector(0.5, 0, -1), new Vector(1, 0, -1), new Vector(1, 0, -0.5), @@ -178,12 +178,9 @@ public class BundledBlockData { new Vector(-1, 0, -0.5), new Vector(-1, 0, -1), new Vector(-0.5, 0, -1)}; - int len = dir.values.size(); - int increment = 16 / len; - int index = 0; for (Map.Entry valuesEntry : dir.values.entrySet()) { - valuesEntry.getValue().setDirection(dirs[index]); - index += increment; + int index = Integer.parseInt(valuesEntry.getKey()); + valuesEntry.getValue().setDirection(range[index]); } return true; } @@ -194,15 +191,15 @@ public class BundledBlockData { FaweStateValue z = axis.values.get("z"); if (x != null) { x.setDirection(new Vector(1, 0, 0)); - axis.values.put("x2", new FaweStateValue(x).setDirection(new Vector(-1, 0, 0))); + axis.values.put("-x", new FaweStateValue(x).setDirection(new Vector(-1, 0, 0))); } if (y != null) { y.setDirection(new Vector(0, 1, 0)); - axis.values.put("y2", new FaweStateValue(y).setDirection(new Vector(0, -1, 0))); + axis.values.put("-y", new FaweStateValue(y).setDirection(new Vector(0, -1, 0))); } if (z != null) { z.setDirection(new Vector(0, 0, 1)); - axis.values.put("z2", new FaweStateValue(z).setDirection(new Vector(0, 0, -1))); + axis.values.put("-z", new FaweStateValue(z).setDirection(new Vector(0, 0, -1))); } return true; } @@ -221,7 +218,7 @@ public class BundledBlockData { int index = 0; for (Map.Entry valuesEntry : dir.values.entrySet()) { valuesEntry.getValue().setDirection(dirs[index]); - index ++; + index++; } return true; } diff --git a/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java index 2385bbac..80e44d95 100644 --- a/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge110/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -51,7 +51,7 @@ public class FaweForge implements IFawe { public void setupInjector() { try { - Fawe.get().setupInjector(); + Fawe.setupInjector(); com.sk89q.worldedit.forge.ForgePlayer.inject(); } catch (Throwable e) { Fawe.debug("Failed to inject WorldEdit classes."); diff --git a/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java index 2385bbac..80e44d95 100644 --- a/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge111/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -51,7 +51,7 @@ public class FaweForge implements IFawe { public void setupInjector() { try { - Fawe.get().setupInjector(); + Fawe.setupInjector(); com.sk89q.worldedit.forge.ForgePlayer.inject(); } catch (Throwable e) { Fawe.debug("Failed to inject WorldEdit classes."); 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 73e81aa9..29196501 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -51,7 +51,7 @@ public class FaweForge implements IFawe { public void setupInjector() { try { - Fawe.get().setupInjector(); + Fawe.setupInjector(); com.sk89q.worldedit.forge.ForgePlayer.inject(); } catch (Throwable e) { Fawe.debug("Failed to inject WorldEdit classes."); diff --git a/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java index 58bd68f7..1d88cf17 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -51,7 +51,7 @@ public class FaweForge implements IFawe { public void setupInjector() { try { - Fawe.get().setupInjector(); + Fawe.setupInjector(); com.sk89q.worldedit.forge.ForgePlayer.inject(); } catch (Throwable e) { Fawe.debug("Failed to inject WorldEdit classes."); diff --git a/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java b/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java index 5992b7a3..8301db4d 100644 --- a/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java +++ b/forge194/src/main/java/com/boydti/fawe/forge/FaweForge.java @@ -51,7 +51,7 @@ public class FaweForge implements IFawe { public void setupInjector() { try { - Fawe.get().setupInjector(); + Fawe.setupInjector(); com.sk89q.worldedit.forge.ForgePlayer.inject(); } catch (Throwable e) { Fawe.debug("Failed to inject WorldEdit classes."); diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitWorldEdit.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitWorldEdit.java index 673e7e48..b282de5d 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitWorldEdit.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitWorldEdit.java @@ -75,7 +75,7 @@ public class NukkitWorldEdit extends PluginBase { public void onEnable() { try { Fawe.set(new FaweNukkit(this)); - Fawe.get().setupInjector(); + Fawe.setupInjector(); Settings.HISTORY.COMBINE_STAGES = false; logger = Logger.getLogger(NukkitWorldEdit.class.getCanonicalName()); createDefaultConfiguration("config-basic.yml"); diff --git a/settings.gradle b/settings.gradle index 88e990db..c25a2b04 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ rootProject.name = 'FastAsyncWorldEdit' -include 'core', 'bukkit', 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'favs', 'nukkit' +include 'core', 'bukkit', 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'favs', 'nukkit', 'sponge' diff --git a/sponge/build.gradle b/sponge/build.gradle index ccb114be..0f7b8add 100644 --- a/sponge/build.gradle +++ b/sponge/build.gradle @@ -11,6 +11,9 @@ buildscript { } maven {url = "https://oss.sonatype.org/content/repositories/snapshots/"} maven {url = "http://repo.minecrell.net/snapshots"} + maven { url = "http://files.minecraftforge.net/maven" } + maven { url = "http://repo.minecrell.net/releases" } + maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } } dependencies { classpath 'net.minecrell:VanillaGradle:2.0.3_1' @@ -18,13 +21,18 @@ buildscript { } } +plugins { + id 'org.spongepowered.plugin' version '0.6' +} + apply plugin: 'net.minecrell.vanilla.server.library' apply plugin: 'com.github.johnrengelman.shadow' dependencies { compile project(':core') - compile 'org.spongepowered:spongeapi:4.+' - compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1' + compile 'org.spongepowered:spongeapi:5.1.0-SNAPSHOT' + compile 'org.spongepowered:mixin:0.6.1-SNAPSHOT' + compile 'com.sk89q.worldedit:worldedit-forge-mc1.10.2:6.1.5' } sourceCompatibility = 1.8 @@ -45,8 +53,8 @@ repositories { } } minecraft { - version = "1.8.9" - mappings = "stable_22" + version = "1.10.2" + mappings = "snapshot_20161029" runDir = 'run' } @@ -63,6 +71,7 @@ processResources { shadowJar { relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml' dependencies { + include(dependency('com.github.luben:zstd-jni:1.1.1')) include(dependency(':core')) include(dependency('org.yaml:snakeyaml:1.16')) } diff --git a/sponge/src/main/java/com/boydti/fawe/SpongeCommand.java b/sponge/src/main/java/com/boydti/fawe/SpongeCommand.java index b6e6d909..5a5d5e29 100644 --- a/sponge/src/main/java/com/boydti/fawe/SpongeCommand.java +++ b/sponge/src/main/java/com/boydti/fawe/SpongeCommand.java @@ -1,16 +1,18 @@ package com.boydti.fawe; -import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweCommand; import com.boydti.fawe.object.FawePlayer; import java.util.List; import java.util.Optional; +import javax.annotation.Nullable; import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.command.CommandException; import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.text.Text; +import org.spongepowered.api.world.Location; +import org.spongepowered.api.world.World; /** * Created by Jesse on 4/2/2016. @@ -35,19 +37,22 @@ public class SpongeCommand implements CommandCallable { } @Override - public List getSuggestions(CommandSource source, String arguments) throws CommandException {return null;} + public List getSuggestions(CommandSource source, String arguments, @Nullable Location targetPosition) throws CommandException { + return null; + } + @Override public boolean testPermission(CommandSource source) {return true;} @Override - public Optional getShortDescription(final CommandSource cmd) { + public Optional getShortDescription(CommandSource source) { return Optional.of(Text.of("Various")); } @Override - public Optional getHelp(final CommandSource cmd) { - return Optional.of(Text.of("/")); + public Optional getHelp(CommandSource source) { + return Optional.of(Text.of("/" + this.cmd)); } @Override 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 a28bbb31..b5167753 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java @@ -4,16 +4,12 @@ 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.FaweCommand; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.regions.FaweMaskManager; -import com.boydti.fawe.sponge.v1_8.SpongeQueue_1_8; -import com.boydti.fawe.sponge.v1_8.SpongeQueue_ALL; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.TaskManager; -import com.sk89q.worldedit.forge.ForgeWorldEdit; import com.sk89q.worldedit.world.World; import java.io.File; import java.util.ArrayList; @@ -34,24 +30,15 @@ public class FaweSponge implements IFawe { public FaweSponge instance; - private ForgeWorldEdit worldedit; - - public ForgeWorldEdit getWorldEditPlugin() { - if (this.worldedit == null) { - this.worldedit = ForgeWorldEdit.inst; - } - return this.worldedit; - } - public FaweSponge(SpongeMain plugin) { instance = this; this.plugin = plugin; try { Fawe.set(this); + Fawe.setupInjector(); } catch (final Throwable e) { MainUtil.handleError(e); } - TaskManager.IMP.later(() -> SpongeUtil.initBiomeCache(), 0); } @Override @@ -100,23 +87,13 @@ public class FaweSponge implements IFawe { } @Override - public int[] getVersion() { - debug("[FAWE] Checking minecraft version: Sponge: "); - String version = Sponge.getGame().getPlatform().getMinecraftVersion().getName(); - String[] split = version.split("\\."); - return new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), split.length == 3 ? Integer.parseInt(split[2]) : 0}; + public FaweQueue getNewQueue(World world, boolean fast) { + return new com.boydti.fawe.sponge.v1_10.SpongeQueue_1_10(getWorldName(world)); } @Override public FaweQueue getNewQueue(String world, boolean fast) { - if (fast || Settings.HISTORY.COMBINE_STAGES) { - try { - return new SpongeQueue_1_8(world); - } catch (Throwable e) { - MainUtil.handleError(e); - } - } - return new SpongeQueue_ALL(world); + return new com.boydti.fawe.sponge.v1_10.SpongeQueue_1_10(world); } @Override 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 05de2a2f..ab545c9b 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMain.java @@ -1,7 +1,6 @@ package com.boydti.fawe.sponge; import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweAPI; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FawePlayer; import com.google.inject.Inject; @@ -10,16 +9,16 @@ import org.spongepowered.api.Game; import org.spongepowered.api.Server; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.entity.DisplaceEntityEvent; +import org.spongepowered.api.event.Order; import org.spongepowered.api.event.game.state.GamePreInitializationEvent; import org.spongepowered.api.event.network.ClientConnectionEvent; import org.spongepowered.api.plugin.Plugin; 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.5.1", authors = "Empire92") +@Plugin(id = "fastasyncworldedit", name = "FastAsyncWorldEdit", description = "fawe", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "development", authors = "Empire92") public class SpongeMain { + @Inject public PluginContainer plugin; @Inject @@ -46,12 +45,11 @@ public class SpongeMain { return this.resolver; } - - @Listener + @Listener(order = Order.PRE) public void onGamePreInit(GamePreInitializationEvent event) { - plugin = this.game.getPluginManager().fromInstance(this).get(); this.server = this.game.getServer(); new FaweSponge(this); + Settings.QUEUE.PARALLEL_THREADS = 1; } @Listener @@ -61,20 +59,4 @@ public class SpongeMain { fp.unregister(); Fawe.get().unregister(player.getName()); } - - @Listener - public void onMove(DisplaceEntityEvent.TargetPlayer event) { - if (Settings.HISTORY.USE_DISK) { - World from = event.getFromTransform().getExtent(); - World to = event.getToTransform().getExtent(); - if (!from.equals(to)) { - Player player = event.getTargetEntity(); - FawePlayer fp = FawePlayer.wrap(player); - com.sk89q.worldedit.world.World world = FaweAPI.getWorld(to.getName()); - fp.getSession().clearHistory(); - fp.loadSessionsFromDisk(world); - return; - } - } - } } diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMetrics.java b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMetrics.java index c4d75106..1daa6443 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMetrics.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeMetrics.java @@ -29,10 +29,10 @@ package com.boydti.fawe.sponge; */ import com.boydti.fawe.Fawe; +import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.util.MainUtil; import com.google.inject.Inject; import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; @@ -131,7 +131,7 @@ public class SpongeMetrics { * @return */ public static byte[] gzip(final String input) { - final ByteArrayOutputStream baos = new FastByteArrayOutputStream(); + final FastByteArrayOutputStream baos = new FastByteArrayOutputStream(); GZIPOutputStream gzos = null; try { 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 fb79963c..fc292463 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/SpongePlayer.java @@ -1,12 +1,14 @@ package com.boydti.fawe.sponge; -import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLocation; import com.boydti.fawe.object.FawePlayer; -import com.boydti.fawe.wrappers.PlayerWrapper; +import com.boydti.fawe.wrappers.FakePlayer; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import java.lang.reflect.Method; 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; @@ -72,6 +74,19 @@ public class SpongePlayer extends FawePlayer { @Override public com.sk89q.worldedit.entity.Player getPlayer() { - return PlayerWrapper.wrap(Fawe. imp().getWorldEditPlugin().wrap((EntityPlayerMP) this.parent)); + if (WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.USER_COMMANDS) != null) { + for (Platform platform : WorldEdit.getInstance().getPlatformManager().getPlatforms()) { + return platform.matchPlayer(new FakePlayer(getName(), getUUID(), null)); + } + } + try { + Class clazz = Class.forName("com.sk89q.worldedit.sponge.SpongeWorldEdit"); + Object spongeWorldEdit = clazz.getDeclaredMethod("inst").invoke(null); + Method methodGetPlayer = clazz.getMethod("wrapPlayer", org.spongepowered.api.entity.living.player.Player.class); + return (com.sk89q.worldedit.entity.Player) methodGetPlayer.invoke(spongeWorldEdit, this.parent); + } catch (Throwable e) { + e.printStackTrace(); + return null; + } } } diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeUtil.java b/sponge/src/main/java/com/boydti/fawe/sponge/SpongeUtil.java deleted file mode 100644 index 104e83d6..00000000 --- a/sponge/src/main/java/com/boydti/fawe/sponge/SpongeUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.boydti.fawe.sponge; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.util.MainUtil; -import com.sk89q.worldedit.world.biome.BiomeData; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; -import net.minecraft.world.biome.BiomeGenBase; -import org.spongepowered.api.world.biome.BiomeType; -import org.spongepowered.api.world.biome.BiomeTypes; - -/** - * Created by Jesse on 4/2/2016. - */ -public class SpongeUtil { - private static BiomeType[] biomes; - private static HashMap biomeMap; - public static Map biomeData; - - public static void initBiomeCache() { - try { - Class clazz = Class.forName("com.sk89q.worldedit.forge.ForgeBiomeRegistry"); - Field bdf = clazz.getDeclaredField("biomeData"); - bdf.setAccessible(true); - biomeData = (Map) bdf.get(null); - biomes = new BiomeType[256]; - biomeMap = new HashMap<>(); - int lastId = 0; - loop: - for (Map.Entry entry : biomeData.entrySet()) { - int id = entry.getKey(); - BiomeData data = entry.getValue(); - String name = data.getName().toUpperCase().replaceAll(" ", "_").replaceAll("[+]", "_PLUS"); - if (name.endsWith("_M") || name.contains("_M_")) { - name = name.replaceAll("_M", "_MOUNTAINS"); - } - if (name.endsWith("_F") || name.contains("_F_")) { - name = name.replaceAll("_F", "_FOREST"); - } - try { - biomes[id] = (BiomeType) BiomeTypes.class.getField(name).get(null); - biomeMap.put(biomes[id].getId(), id); - lastId = id; - } - catch (Throwable e) { - Field[] fields = BiomeTypes.class.getDeclaredFields(); - for (Field field : fields) { - if (field.getName().replaceAll("_", "").equals(name.replaceAll("_", ""))) { - biomes[id] = (BiomeType) field.get(null); - biomeMap.put(biomes[id].getId(), id); - lastId = id; - continue loop; - } - } - Fawe.debug("Unknown biome: " + name); - biomes[id] = biomes[lastId]; - biomeMap.put(biomes[lastId].getId(), lastId); - } - } - } catch (Throwable e) { - MainUtil.handleError(e); - } - } - - public static BiomeType getBiome(String biome) { - if (biomes == null) { - initBiomeCache(); - } - return biomes[biomeMap.get(biome.toUpperCase())]; - } - - public static BiomeType getBiome(int index) { - return (BiomeType) BiomeGenBase.getBiome(index); - } -} diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeChunk_1_10.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeChunk_1_10.java new file mode 100644 index 00000000..c6e6b964 --- /dev/null +++ b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeChunk_1_10.java @@ -0,0 +1,401 @@ +package com.boydti.fawe.sponge.v1_10; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.example.CharFaweChunk; +import com.boydti.fawe.object.FaweQueue; +import com.boydti.fawe.util.MainUtil; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.DoubleTag; +import com.sk89q.jnbt.FloatTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; +import java.lang.reflect.Field; +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.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BitArray; +import net.minecraft.util.ClassInheritanceMultiMap; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.BlockStateContainer; +import net.minecraft.world.chunk.BlockStatePaletteRegistry; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IBlockStatePalette; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +public class SpongeChunk_1_10 extends CharFaweChunk { + + public BlockStateContainer[] sectionPalettes; + + /** + * A FaweSections object represents a chunk and the blocks that you wish to change in it. + * + * @param parent + * @param x + * @param z + */ + public SpongeChunk_1_10(FaweQueue parent, int x, int z) { + super(parent, x, z); + } + + public SpongeChunk_1_10(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) { + super(parent, x, z, ids, count, air, heightMap); + } + + @Override + public CharFaweChunk copy(boolean shallow) { + SpongeChunk_1_10 copy; + if (shallow) { + copy = new SpongeChunk_1_10(getParent(), getX(), getZ(), ids, count, air, heightMap); + copy.biomes = biomes; + copy.chunk = chunk; + } else { + copy = new SpongeChunk_1_10(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone()); + copy.biomes = biomes; + copy.chunk = chunk; + copy.biomes = biomes.clone(); + copy.chunk = chunk; + } + if (sectionPalettes != null) { + copy.sectionPalettes = new BlockStateContainer[16]; + try { + Field fieldBits = BlockStateContainer.class.getDeclaredField("field_186021_b"); + fieldBits.setAccessible(true); + Field fieldPalette = BlockStateContainer.class.getDeclaredField("field_186022_c"); + fieldPalette.setAccessible(true); + Field fieldSize = BlockStateContainer.class.getDeclaredField("field_186024_e"); + fieldSize.setAccessible(true); + for (int i = 0; i < sectionPalettes.length; i++) { + BlockStateContainer current = sectionPalettes[i]; + if (current == null) { + continue; + } + // Clone palette + IBlockStatePalette currentPalette = (IBlockStatePalette) fieldPalette.get(current); + if (!(currentPalette instanceof BlockStatePaletteRegistry)) { + current.onResize(128, null); + } + BlockStateContainer paletteBlock = new BlockStateContainer(); + currentPalette = (IBlockStatePalette) fieldPalette.get(current); + if (!(currentPalette instanceof BlockStatePaletteRegistry)) { + throw new RuntimeException("Palette must be global!"); + } + fieldPalette.set(paletteBlock, currentPalette); + // Clone size + fieldSize.set(paletteBlock, fieldSize.get(current)); + // Clone palette + BitArray currentBits = (BitArray) fieldBits.get(current); + BitArray newBits = new BitArray(1, 0); + for (Field field : BitArray.class.getDeclaredFields()) { + field.setAccessible(true); + Object currentValue = field.get(currentBits); + if (currentValue instanceof long[]) { + currentValue = ((long[]) currentValue).clone(); + } + field.set(newBits, currentValue); + } + fieldBits.set(paletteBlock, newBits); + copy.sectionPalettes[i] = paletteBlock; + } + } catch (Throwable e) { + MainUtil.handleError(e); + } + } + return copy; + } + + @Override + public Chunk getNewChunk() { + World world = ((SpongeQueue_1_10) getParent()).getWorld(); + return world.getChunkProvider().provideChunk(getX(), getZ()); + } + + public void optimize() { + if (sectionPalettes != null) { + return; + } + char[][] arrays = getCombinedIdArrays(); + char lastChar = Character.MAX_VALUE; + for (int layer = 0; layer < 16; layer++) { + if (getCount(layer) > 0) { + if (sectionPalettes == null) { + sectionPalettes = new BlockStateContainer[16]; + } + BlockStateContainer palette = new BlockStateContainer(); + char[] blocks = getIdArray(layer); + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + char combinedId = blocks[FaweCache.CACHE_J[y][z][x]]; + if (combinedId > 1) { + palette.set(x, y, z, Block.getBlockById(combinedId >> 4).getStateFromMeta(combinedId & 0xF)); + } + } + } + } + } + } + } + + @Override + public SpongeChunk_1_10 call() { + net.minecraft.world.chunk.Chunk nmsChunk = this.getChunk(); + int bx = this.getX() << 4; + int bz = this.getZ() << 4; + nmsChunk.setModified(true); + net.minecraft.world.World nmsWorld = getParent().getWorld(); + try { + boolean flag = !nmsWorld.provider.getHasNoSky(); + // Sections + ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); + Map tiles = nmsChunk.getTileEntityMap(); + ClassInheritanceMultiMap[] entities = nmsChunk.getEntityLists(); + + // Set heightmap + getParent().setHeightMap(this, heightMap); + + // Remove entities + for (int i = 0; i < 16; i++) { + int count = this.getCount(i); + if (count == 0) { + continue; + } else if (count >= 4096) { + Collection ents = entities[i]; + if (!ents.isEmpty()) { + synchronized (SpongeChunk_1_10.class) { + entities[i] = new ClassInheritanceMultiMap<>(Entity.class); + } + } + } else { + char[] array = this.getIdArray(i); + Collection ents = new ArrayList<>(entities[i]); + synchronized (SpongeChunk_1_10.class) { + 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; + } + if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) { + nmsWorld.removeEntity(entity); + } + } + } + } + } + // Set entities + Set createdEntities = new HashSet<>(); + Set entitiesToSpawn = this.getEntities(); + if (!entitiesToSpawn.isEmpty()) { + synchronized (SpongeChunk_1_10.class) { + 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; + } + List value = posTag.getValue(); + double x = ((DoubleTag) value.get(0)).getValue(); + double y = ((DoubleTag) value.get(1)).getValue(); + double z = ((DoubleTag) value.get(2)).getValue(); + value = rotTag.getValue(); + float yaw = ((FloatTag) value.get(0)).getValue(); + float pitch = ((FloatTag) value.get(1)).getValue(); + String id = idTag.getValue(); + if (id != null) { + Entity entity = EntityList.createEntityByName(id, nmsWorld); + if (entity != null) { + NBTTagCompound tag = (NBTTagCompound) SpongeQueue_1_10.methodFromNative.invoke(null, nativeTag); + tag.removeTag("UUIDMost"); + tag.removeTag("UUIDLeast"); + entity.readFromNBT(tag); + entity.setPositionAndRotation(x, y, z, yaw, pitch); + nmsWorld.spawnEntityInWorld(entity); + } + } + } + } + } + // Run change task if applicable + if (getParent().getChangeTask() != null) { + CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false); + getParent().getChangeTask().run(previous, this); + } + // Trim tiles + Set> entryset = tiles.entrySet(); + Iterator> iterator = entryset.iterator(); + while (iterator.hasNext()) { + Map.Entry tile = iterator.next(); + BlockPos pos = tile.getKey(); + int lx = pos.getX() & 15; + int ly = pos.getY(); + int lz = pos.getZ() & 15; + int j = FaweCache.CACHE_I[ly][lz][lx]; + char[] array = this.getIdArray(j); + if (array == null) { + continue; + } + int k = FaweCache.CACHE_J[ly][lz][lx]; + if (array[k] != 0) { + tile.getValue().invalidate();; + iterator.remove(); + } + } + HashSet entsToRemove = this.getEntityRemoves(); + if (!entsToRemove.isEmpty()) { + synchronized (SpongeChunk_1_10.class) { + 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++) { + int count = this.getCount(j); + if (count == 0) { + continue; + } + final char[] array = this.getIdArray(j); + if (array == null) { + continue; + } + ExtendedBlockStorage section = sections[j]; + if (section == null) { + if (this.sectionPalettes != null && this.sectionPalettes[j] != null) { + section = sections[j] = new ExtendedBlockStorage(j << 4, flag); + getParent().setPalette(section, this.sectionPalettes[j]); + getParent().setCount(0, count - this.getAir(j), section); + continue; + } else { + sections[j] = section = new ExtendedBlockStorage(j << 4, flag); + } + } else if (count >= 4096) { + if (this.sectionPalettes != null && this.sectionPalettes[j] != null) { + getParent().setPalette(section, this.sectionPalettes[j]); + getParent().setCount(0, count - this.getAir(j), section); + continue; + } else { + sections[j] = section = new ExtendedBlockStorage(j << 4, flag); + } + } + IBlockState existing; + int by = j << 4; + BlockStateContainer nibble = section.getData(); + int nonEmptyBlockCount = 0; + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + char combinedId = array[FaweCache.CACHE_J[y][z][x]]; + switch (combinedId) { + case 0: + continue; + case 1: + existing = nibble.get(x, y, z); + if (existing != SpongeQueue_1_10.air) { + if (existing.getLightValue() > 0) { + getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z); + } + nonEmptyBlockCount--; + } + nibble.set(x, y, z, SpongeQueue_1_10.air); + continue; + default: + existing = nibble.get(x, y, z); + if (existing != SpongeQueue_1_10.air) { + if (existing.getLightValue() > 0) { + getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z); + } + } else { + nonEmptyBlockCount++; + } + nibble.set(x, y, z, Block.getBlockById(combinedId >> 4).getStateFromMeta(combinedId & 0xF)); + } + } + } + } + getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section); + } + // Set biomes + int[][] biomes = this.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 = this.getTiles(); + + for (Map.Entry entry : tilesToSpawn.entrySet()) { + CompoundTag nativeTag = entry.getValue(); + short blockHash = entry.getKey(); + int x = (blockHash >> 12 & 0xF) + bx; + int y = (blockHash & 0xFF); + int z = (blockHash >> 8 & 0xF) + bz; + BlockPos pos = new BlockPos(x, y, z); // Set pos + TileEntity tileEntity = nmsWorld.getTileEntity(pos); + if (tileEntity != null) { + NBTTagCompound tag = (NBTTagCompound) SpongeQueue_1_10.methodFromNative.invoke(null, nativeTag); + tag.setInteger("x", pos.getX()); + tag.setInteger("y", pos.getY()); + tag.setInteger("z", pos.getZ()); + tileEntity.readFromNBT(tag); // ReadTagIntoTile + } + } + } catch (Throwable e) { + MainUtil.handleError(e); + } + int[][] biomes = this.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; + } + } + } + return this; + } +} diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_1_10.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_1_10.java new file mode 100644 index 00000000..6bbe868b --- /dev/null +++ b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_1_10.java @@ -0,0 +1,541 @@ +package com.boydti.fawe.sponge.v1_10; + +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.example.CharFaweChunk; +import com.boydti.fawe.example.NMSMappedFaweQueue; +import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.sponge.SpongePlayer; +import com.boydti.fawe.util.MainUtil; +import com.boydti.fawe.util.MathMan; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.world.biome.BaseBiome; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +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.init.Blocks; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SPacketChunkData; +import net.minecraft.network.play.server.SPacketMultiBlockChange; +import net.minecraft.server.management.PlayerChunkMap; +import net.minecraft.server.management.PlayerChunkMapEntry; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ClassInheritanceMultiMap; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.EnumSkyBlock; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.BlockStateContainer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkGenerator; +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; + +public class SpongeQueue_1_10 extends NMSMappedFaweQueue { + + protected final static Method methodFromNative; + protected final static Method methodToNative; + protected final static Field fieldTickingBlockCount; + protected final static Field fieldNonEmptyBlockCount; + + protected final static Field fieldId2ChunkMap; + protected final static Field fieldChunkGenerator; + + static { + try { + Class converter = Class.forName("com.sk89q.worldedit.sponge.nms.NBTConverter"); + methodFromNative = converter.getDeclaredMethod("toNative", Tag.class); + methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class); + methodFromNative.setAccessible(true); + methodToNative.setAccessible(true); + + fieldId2ChunkMap = ChunkProviderServer.class.getDeclaredField("field_73244_f"); + fieldChunkGenerator = ChunkProviderServer.class.getDeclaredField("field_186029_c"); + fieldId2ChunkMap.setAccessible(true); + fieldChunkGenerator.setAccessible(true); + + fieldTickingBlockCount = ExtendedBlockStorage.class.getDeclaredField("field_76683_c"); + fieldNonEmptyBlockCount = ExtendedBlockStorage.class.getDeclaredField("field_76682_b"); + fieldTickingBlockCount.setAccessible(true); + fieldNonEmptyBlockCount.setAccessible(true); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + public SpongeQueue_1_10(com.sk89q.worldedit.world.World world) { + super(world); + getImpWorld(); + } + + public SpongeQueue_1_10(String world) { + super(world); + getImpWorld(); + } + + @Override + public void startSet(boolean parallel) { + MixinMinecraftServer.ALLOW_THREADS = true; + } + + @Override + public void endSet(boolean parallel) { + MixinMinecraftServer.ALLOW_THREADS = false; + } + + @Override + public void sendBlockUpdate(Map> blockMap, FawePlayer... players) { + for (Map.Entry> chunkEntry : blockMap.entrySet()) { + try { + long chunkHash = chunkEntry.getKey(); + Map blocks = chunkEntry.getValue(); + SPacketMultiBlockChange packet = new SPacketMultiBlockChange(); + int cx = MathMan.unpairIntX(chunkHash); + int cz = MathMan.unpairIntY(chunkHash); + ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); + PacketBuffer buffer = new PacketBuffer(byteBuf); + buffer.writeInt(cx); + buffer.writeInt(cz); + buffer.writeVarIntToBuffer(blocks.size()); + for (Map.Entry blockEntry : blocks.entrySet()) { + buffer.writeShort(blockEntry.getKey()); + buffer.writeVarIntToBuffer(blockEntry.getValue()); + } + packet.readPacketData(buffer); + for (FawePlayer player : players) { + ((EntityPlayerMP) ((SpongePlayer) player).parent).connection.sendPacket(packet); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + @Override + public void setHeightMap(FaweChunk chunk, byte[] heightMap) { + Chunk forgeChunk = (Chunk) chunk.getChunk(); + if (forgeChunk != null) { + int[] otherMap = forgeChunk.getHeightMap(); + for (int i = 0; i < heightMap.length; i++) { + int newHeight = heightMap[i] & 0xFF; + int currentHeight = otherMap[i]; + if (newHeight > currentHeight) { + otherMap[i] = newHeight; + } + } + } + } + + protected BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0); + + @Override + public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) { + Map tiles = chunk.getTileEntityMap(); + pos.setPos(x, y, z); + TileEntity tile = tiles.get(pos); + return tile != null ? getTag(tile) : null; + } + + public CompoundTag getTag(TileEntity tile) { + try { + NBTTagCompound tag = new NBTTagCompound(); + tile.writeToNBT(tag); // readTagIntoEntity + CompoundTag result = (CompoundTag) methodToNative.invoke(null, tag); + return result; + } catch (Exception e) { + MainUtil.handleError(e); + return null; + } + } + + @Override + public Chunk getChunk(net.minecraft.world.World world, int x, int z) { + Chunk chunk = world.getChunkProvider().provideChunk(x, z); + if (chunk != null && !chunk.isLoaded()) { + chunk.onChunkLoad(); + } + return chunk; + } + + @Override + public boolean isChunkLoaded(int x, int z) { + return getWorld().getChunkProvider().getLoadedChunk(x, z) != null; + } + + @Override + public boolean regenerateChunk(net.minecraft.world.World world, int x, int z, BaseBiome biome, Long seed) { + IChunkProvider provider = world.getChunkProvider(); + if (!(provider instanceof ChunkProviderServer)) { + return false; + } + + + try { + ChunkProviderServer chunkServer = (ChunkProviderServer) provider; + IChunkGenerator gen = (IChunkGenerator) fieldChunkGenerator.get(chunkServer); + long pos = ChunkPos.asLong(x, z); + Chunk mcChunk; + if (chunkServer.chunkExists(x, z)) { + mcChunk = chunkServer.loadChunk(x, z); + mcChunk.onChunkUnload(); + } + PlayerChunkMap playerManager = ((WorldServer) getWorld()).getPlayerChunkMap(); + List oldWatchers = null; + if (chunkServer.chunkExists(x, z)) { + mcChunk = chunkServer.loadChunk(x, z); + PlayerChunkMapEntry entry = playerManager.getEntry(x, z); + if (entry != null) { + Field fieldPlayers = PlayerChunkMapEntry.class.getDeclaredField("field_187283_c"); + fieldPlayers.setAccessible(true); + oldWatchers = (List) fieldPlayers.get(entry); + playerManager.removeEntry(entry); + } + mcChunk.onChunkUnload(); + } + try { + Field droppedChunksSetField = chunkServer.getClass().getDeclaredField("field_73248_b"); + droppedChunksSetField.setAccessible(true); + Set droppedChunksSet = (Set) droppedChunksSetField.get(chunkServer); + droppedChunksSet.remove(pos); + } catch (Throwable e) { + MainUtil.handleError(e); + } + Long2ObjectMap id2ChunkMap = (Long2ObjectMap) fieldId2ChunkMap.get(chunkServer); + id2ChunkMap.remove(pos); + mcChunk = gen.provideChunk(x, z); + id2ChunkMap.put(pos, mcChunk); + if (mcChunk != null) { + mcChunk.onChunkLoad(); + mcChunk.populateChunk(chunkServer, gen); + } + if (oldWatchers != null) { + for (EntityPlayerMP player : oldWatchers) { + playerManager.addPlayer(player); + } + } + return true; + } catch (Throwable t) { + MainUtil.handleError(t); + return false; + } + } + + @Override + public boolean loadChunk(net.minecraft.world.World world, int x, int z, boolean generate) { + return getCachedSections(world, x, z) != null; + } + + @Override + public ExtendedBlockStorage[] getCachedSections(net.minecraft.world.World world, int x, int z) { + Chunk chunk = world.getChunkProvider().provideChunk(x, z); + if (chunk != null && !chunk.isLoaded()) { + chunk.onChunkLoad(); + } + return chunk == null ? null : chunk.getBlockStorageArray(); + } + + @Override + public ExtendedBlockStorage getCachedSection(ExtendedBlockStorage[] chunk, int cy) { + return chunk[cy]; + } + + @Override + public int getCombinedId4Data(ExtendedBlockStorage section, int x, int y, int z) { + IBlockState ibd = section.getData().get(x & 15, y & 15, z & 15); + Block block = ibd.getBlock(); + int id = Block.getIdFromBlock(block); + if (FaweCache.hasData(id)) { + return (id << 4) + block.getMetaFromState(ibd); + } else { + return id << 4; + } + } + + @Override + public boolean isChunkLoaded(net.minecraft.world.World world, int x, int z) { + return world.getChunkProvider().getLoadedChunk(x, z) != null; + } + + public int getNonEmptyBlockCount(ExtendedBlockStorage section) throws IllegalAccessException { + return (int) fieldNonEmptyBlockCount.get(section); + } + + public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ExtendedBlockStorage section) throws NoSuchFieldException, IllegalAccessException { + 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; + ClassInheritanceMultiMap[] entities = (ClassInheritanceMultiMap[]) entitiesGeneric; + CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ()); + char[][] idPrevious = previous.getCombinedIdArrays(); + for (int layer = 0; layer < sections.length; layer++) { + if (fs.getCount(layer) != 0 || all) { + ExtendedBlockStorage section = sections[layer]; + if (section != null) { + short solid = 0; + char[] previousLayer = idPrevious[layer] = new char[4096]; + BlockStateContainer blocks = section.getData(); + for (int j = 0; j < 4096; j++) { + int x = FaweCache.CACHE_X[0][j]; + int y = FaweCache.CACHE_Y[0][j]; + int z = FaweCache.CACHE_Z[0][j]; + IBlockState ibd = blocks.get(x, y, z); + Block block = ibd.getBlock(); + int combined = Block.getIdFromBlock(block); + if (FaweCache.hasData(combined)) { + combined = (combined << 4) + block.getMetaFromState(ibd); + } else { + combined = combined << 4; + } + if (combined > 1) { + solid++; + } + previousLayer[j] = (char) combined; + } + previous.count[layer] = solid; + previous.air[layer] = (short) (4096 - solid); + } + } + } + if (tiles != null) { + for (Map.Entry entry : tiles.entrySet()) { + TileEntity tile = entry.getValue(); + NBTTagCompound tag = new NBTTagCompound(); + tile.writeToNBT(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][z][x]; + char[] array = fs.getIdArray(i); + if (array == null) { + continue; + } + int j = FaweCache.CACHE_J[y][z][x]; + if (array[j] != 0) { + String id = EntityList.getEntityString(ent); + if (id != null) { + NBTTagCompound tag = new NBTTagCompound(); + ent.writeToNBT(tag); // 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; + } + + protected final static IBlockState air = Blocks.AIR.getDefaultState(); + + public void setPalette(ExtendedBlockStorage section, BlockStateContainer palette) throws NoSuchFieldException, IllegalAccessException { + Field fieldSection = ExtendedBlockStorage.class.getDeclaredField("data"); + fieldSection.setAccessible(true); + fieldSection.set(section, palette); + } + + @Override + public void refreshChunk(FaweChunk fc) { + SpongeChunk_1_10 fs = (SpongeChunk_1_10) fc; + ensureChunkLoaded(fc.getX(), fc.getZ()); + Chunk nmsChunk = fs.getChunk(); + if (!nmsChunk.isLoaded()) { + return; + } + try { + ChunkPos pos = nmsChunk.getChunkCoordIntPair(); + WorldServer w = (WorldServer) nmsChunk.getWorld(); + PlayerChunkMap chunkMap = w.getPlayerChunkMap(); + int x = pos.chunkXPos; + int z = pos.chunkZPos; + PlayerChunkMapEntry chunkMapEntry = chunkMap.getEntry(x, z); + if (chunkMapEntry == null) { + return; + } + final ArrayDeque players = new ArrayDeque<>(); + chunkMapEntry.hasPlayerMatching(input -> { + players.add(input); + return false; + }); + int mask = fc.getBitMask(); + if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) { + SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280); + for (EntityPlayerMP player : players) { + player.connection.sendPacket(packet); + } + mask = 255; + } + SPacketChunkData packet = new SPacketChunkData(nmsChunk, mask); + for (EntityPlayerMP player : players) { + player.connection.sendPacket(packet); + } + } catch (Throwable e) { + MainUtil.handleError(e); + } + } + + public boolean hasEntities(Chunk nmsChunk) { + ClassInheritanceMultiMap[] entities = nmsChunk.getEntityLists(); + for (int i = 0; i < entities.length; i++) { + ClassInheritanceMultiMap slice = entities[i]; + if (slice != null && !slice.isEmpty()) { + return true; + } + } + return false; + } + + + @Override + public FaweChunk getFaweChunk(int x, int z) { + return new SpongeChunk_1_10(this, x, z); + } + + @Override + public boolean removeLighting(ExtendedBlockStorage[] sections, RelightMode mode, boolean sky) { + if (mode == RelightMode.ALL) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + section.setBlocklightArray(new NibbleArray()); + if (sky) { + section.setSkylightArray(new NibbleArray()); + } + } + } + } + return true; + } + + @Override + public boolean hasSky() { + return !nmsWorld.provider.getHasNoSky(); + } + + @Override + public void setFullbright(ExtendedBlockStorage[] sections) { + for (int i = 0; i < sections.length; i++) { + ExtendedBlockStorage section = sections[i]; + if (section != null) { + byte[] bytes = section.getSkylightArray().getData(); + Arrays.fill(bytes, (byte) 255); + } + } + } + + @Override + public void relight(int x, int y, int z) { + pos.setPos(x, y, z); + nmsWorld.checkLight(pos); + } + + protected WorldServer nmsWorld; + + @Override + public net.minecraft.world.World getImpWorld() { + if (nmsWorld != null || getWorldName() == null) { + return nmsWorld; + } + nmsWorld = (WorldServer) Sponge.getServer().getWorld(getWorldName()).get(); + return nmsWorld; + } + + @Override + public void setSkyLight(ExtendedBlockStorage section, int x, int y, int z, int value) { + section.getSkylightArray().set(x & 15, y & 15, z & 15, value); + } + + @Override + public void setBlockLight(ExtendedBlockStorage section, int x, int y, int z, int value) { + section.getBlocklightArray().set(x & 15, y & 15, z & 15, value); + } + + @Override + public int getSkyLight(ExtendedBlockStorage section, int x, int y, int z) { + return section.getExtSkylightValue(x & 15, y & 15, z & 15); + } + + @Override + public int getEmmittedLight(ExtendedBlockStorage section, int x, int y, int z) { + return section.getExtBlocklightValue(x & 15, y & 15, z & 15); + } + + @Override + public int getOpacity(ExtendedBlockStorage section, int x, int y, int z) { + BlockStateContainer dataPalette = section.getData(); + IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15); + return ibd.getLightOpacity(); + } + + @Override + public int getBrightness(ExtendedBlockStorage section, int x, int y, int z) { + BlockStateContainer dataPalette = section.getData(); + IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15); + return ibd.getLightValue(); + } + + @Override + public int getOpacityBrightnessPair(ExtendedBlockStorage section, int x, int y, int z) { + BlockStateContainer dataPalette = section.getData(); + IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15); + return MathMan.pair16(ibd.getLightOpacity(), ibd.getLightValue()); + } + + @Override + public void relightBlock(int x, int y, int z) { + pos.setPos(x, y, z); + nmsWorld.checkLightFor(EnumSkyBlock.BLOCK, pos); + } + + @Override + public void relightSky(int x, int y, int z) { + pos.setPos(x, y, z); + nmsWorld.checkLightFor(EnumSkyBlock.SKY, pos); + } + + @Override + public File getSaveFolder() { + return new File(((WorldServer) getWorld()).getSaveHandler().getWorldDirectory(), "region"); + } +} diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_ALL.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_ALL.java.unused similarity index 71% rename from sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_ALL.java rename to sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_ALL.java.unused index 12b5fab7..7d61575d 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_ALL.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/v1_10/SpongeQueue_ALL.java.unused @@ -1,16 +1,15 @@ -package com.boydti.fawe.sponge.v1_8; +package com.boydti.fawe.sponge.v1_10; -import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.config.Settings; import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.object.FaweChunk; -import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.TaskManager; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.world.biome.BaseBiome; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collection; @@ -39,7 +38,6 @@ import net.minecraft.util.LongHashMap; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.WorldServer; 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; @@ -51,7 +49,7 @@ import org.spongepowered.api.world.extent.UnmodifiableBlockVolume; import org.spongepowered.api.world.extent.worker.MutableBlockVolumeWorker; import org.spongepowered.api.world.extent.worker.procedure.BlockVolumeMapper; -public class SpongeQueue_ALL extends NMSMappedFaweQueue { +public class SpongeQueue_ALL extends NMSMappedFaweQueue { private Method methodToNative; public SpongeQueue_ALL(String world) { @@ -65,6 +63,11 @@ public class SpongeQueue_ALL 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()) { - 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: - case 213: - 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()) { - MainUtil.handleError(e); - } - } - 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)) - && isSolid(getId(sections, x - 1, y, z)) - && isSolid(getId(sections, x, y, z + 1)) - && isSolid(getId(sections, x, y, z - 1)); - } - - public boolean isSolid(int i) { - return i != 0 && Block.getBlockById(i).isOpaqueCube(); - } - - public int getId(ExtendedBlockStorage[] sections, int x, int y, int z) { - if (x < 0 || x > 15 || z < 0 || z > 15) { - return 1; - } - if (y < 0 || y > 255) { - return 1; - } - int i = FaweCache.CACHE_I[y][z][x]; - ExtendedBlockStorage section = sections[i]; - if (section == null) { - return 0; - } - char[] array = section.getData(); - int j = FaweCache.CACHE_J[y][z][x]; - return array[j] >> 4; - } - @Override public boolean loadChunk(World world, int x, int z, boolean generate) { return getCachedSections(world, x, z) != null; diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeChunk_1_8.java b/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeChunk_1_8.java deleted file mode 100644 index c980e738..00000000 --- a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeChunk_1_8.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.boydti.fawe.sponge.v1_8; - -import com.boydti.fawe.example.CharFaweChunk; -import com.boydti.fawe.object.FaweQueue; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.world.World; - -public class SpongeChunk_1_8 extends CharFaweChunk { - - public SpongeChunk_1_8(FaweQueue parent, int x, int z) { - super(parent, x, z); - } - - @Override - public net.minecraft.world.chunk.Chunk getNewChunk() { - World world = Sponge.getServer().getWorld(getParent().getWorldName()).get(); - return (net.minecraft.world.chunk.Chunk) world.loadChunk(getX(), 0, getZ(), true).get(); - } -} 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 deleted file mode 100644 index 9c2804ac..00000000 --- a/sponge/src/main/java/com/boydti/fawe/sponge/v1_8/SpongeQueue_1_8.java +++ /dev/null @@ -1,680 +0,0 @@ -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.MainUtil; -import com.boydti.fawe.util.MathMan; -import com.boydti.fawe.util.ReflectionUtils; -import com.boydti.fawe.util.TaskManager; -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.EntityTracker; -import net.minecraft.entity.EntityTrackerEntry; -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.play.server.S13PacketDestroyEntities; -import net.minecraft.network.play.server.S21PacketChunkData; -import net.minecraft.server.management.PlayerManager; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockPos; -import net.minecraft.util.ClassInheritanceMultiMap; -import net.minecraft.util.IntHashMap; -import net.minecraft.util.LongHashMap; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.WorldServer; -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; -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); - } - } - - private BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0); - - @Override - public CompoundTag getTileEntity(net.minecraft.world.chunk.Chunk chunk, int x, int y, int z) { - Map tiles = chunk.getTileEntityMap(); - pos.set(x, y, z); - TileEntity tile = tiles.get(pos); - return tile != null ? getTag(tile) : null; - } - - public CompoundTag getTag(TileEntity tile) { - try { - NBTTagCompound tag = new NBTTagCompound(); - tile.readFromNBT(tag); // readTagIntoEntity - return (CompoundTag) methodToNative.invoke(null, tag); - } catch (Exception e) { - MainUtil.handleError(e); - return null; - } - } - - @Override - public net.minecraft.world.chunk.Chunk getChunk(World world, int x, int z) { - net.minecraft.world.chunk.Chunk chunk = ((net.minecraft.world.World) world).getChunkProvider().provideChunk(x, z); - if (chunk != null && !chunk.isLoaded()) { - chunk.onChunkLoad(); - } - return chunk; - } - - @Override - public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) { - if (!nmsChunk.isLoaded()) { - return; - } - try { - ChunkCoordIntPair pos = nmsChunk.getChunkCoordIntPair(); - WorldServer w = (WorldServer) nmsChunk.getWorld(); - PlayerManager chunkMap = w.getPlayerManager(); - int x = pos.chunkXPos; - int z = pos.chunkZPos; - if (!chunkMap.hasPlayerInstance(x, z)) { - return; - } - EntityTracker tracker = w.getEntityTracker(); - final HashSet players = new HashSet<>(); - for (EntityPlayer player : w.playerEntities) { - if (player instanceof EntityPlayerMP) { - if (chunkMap.isPlayerWatchingChunk((EntityPlayerMP) player, x, z)) { - players.add((EntityPlayerMP) player); - } - } - } - if (players.size() == 0) { - return; - } - HashSet entities = new HashSet<>(); - ClassInheritanceMultiMap[] entitieSlices = nmsChunk.getEntityLists(); - IntHashMap entries = null; - for (Field field : tracker.getClass().getDeclaredFields()) { - if (field.getType() == IntHashMap.class) { - field.setAccessible(true); - entries = (IntHashMap) field.get(tracker); - } - } - for (ClassInheritanceMultiMap slice : entitieSlices) { - if (slice == null) { - continue; - } - for (Entity ent : slice) { - EntityTrackerEntry entry = entries != null ? entries.lookup(ent.getEntityId()) : null; - if (entry == null) { - continue; - } - entities.add(entry); - S13PacketDestroyEntities packet = new S13PacketDestroyEntities(ent.getEntityId()); - for (EntityPlayerMP player : players) { - player.playerNetServerHandler.sendPacket(packet); - } - } - } - // Send chunks - S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65535); - for (EntityPlayerMP player : players) { - player.playerNetServerHandler.sendPacket(packet); - } - // send ents - for (final EntityTrackerEntry entry : entities) { - try { - TaskManager.IMP.later(new Runnable() { - @Override - public void run() { - for (EntityPlayerMP player : players) { - boolean result = entry.trackingPlayers.remove(player); - if (result && entry.trackedEntity != player) { - entry.updatePlayerEntity(player); - } - } - } - }, 2); - } catch (Throwable e) { - MainUtil.handleError(e); - } - } - } catch (Throwable e) { - MainUtil.handleError(e); - } - } - - @Override - public char[] getCachedSection(ExtendedBlockStorage[] chunk, int cy) { - ExtendedBlockStorage value = chunk[cy]; - return value == null ? null : value.getData(); - } - - @Override - public World getWorld(String world) { - return Sponge.getServer().getWorld(super.getWorldName()).get(); - } - - @Override - public boolean isChunkLoaded(World world, int x, int z) { - net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world; - IChunkProvider provider = nmsWorld.getChunkProvider(); - return provider.chunkExists(x, z); - } - - @Override - public boolean regenerateChunk(World world, int x, int z) { - try { - net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world; - IChunkProvider provider = nmsWorld.getChunkProvider(); - if (!(provider instanceof ChunkProviderServer)) { - return false; - } - ChunkProviderServer chunkServer = (ChunkProviderServer) provider; - Field chunkProviderField = chunkServer.getClass().getDeclaredField("field_73246_d"); - chunkProviderField.setAccessible(true); - IChunkProvider chunkProvider = (IChunkProvider) chunkProviderField.get(chunkServer); - long pos = ChunkCoordIntPair.chunkXZ2Int(x, z); - net.minecraft.world.chunk.Chunk mcChunk; - if (chunkServer.chunkExists(x, z)) { - mcChunk = chunkServer.loadChunk(x, z); - mcChunk.onChunkUnload(); - } - Field droppedChunksSetField = chunkServer.getClass().getDeclaredField("field_73248_b"); - droppedChunksSetField.setAccessible(true); - Set droppedChunksSet = (Set) droppedChunksSetField.get(chunkServer); - droppedChunksSet.remove(pos); - Field id2ChunkMapField = chunkServer.getClass().getDeclaredField("field_73244_f"); - id2ChunkMapField.setAccessible(true); - LongHashMap id2ChunkMap = (LongHashMap) id2ChunkMapField.get(chunkServer); - id2ChunkMap.remove(pos); - mcChunk = chunkProvider.provideChunk(x, z); - id2ChunkMap.add(pos, mcChunk); - List loadedChunks = chunkServer.func_152380_a(); - loadedChunks.add(mcChunk); - if (mcChunk != null) { - mcChunk.onChunkLoad(); - mcChunk.populateChunk(chunkProvider, chunkProvider, x, z); - } - return true; - } catch (Throwable e) { - MainUtil.handleError(e); - } - 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) getFaweChunk(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][z][x]; - char[] array = fs.getIdArray(i); - if (array == null) { - continue; - } - int j = FaweCache.CACHE_J[y][z][x]; - 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(); - try { - boolean flag = !nmsWorld.provider.getHasNoSky(); - // Sections - 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; - } - if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 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(); - while (iterator.hasNext()) { - Map.Entry tile = iterator.next(); - BlockPos pos = tile.getKey(); - int lx = pos.getX() & 15; - int ly = pos.getY(); - int lz = pos.getZ() & 15; - int j = FaweCache.CACHE_I[ly][lz][lx]; - char[] array = fs.getIdArray(j); - if (array == null) { - continue; - } - int k = FaweCache.CACHE_J[ly][lz][lx]; - if (array[k] != 0) { - tile.getValue().invalidate(); - iterator.remove(); - } - } - 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++) { - int count = fs.getCount(j); - if (count == 0) { - continue; - } - char[] newArray = fs.getIdArray(j); - if (newArray == null) { - continue; - } - ExtendedBlockStorage section = sections[j]; - - 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) { - case 0: - fill = false; - continue; - case 1: - fill = false; - if (currentArray[k] > 1) { - solid++; - } - currentArray[k] = 0; - continue; - default: - solid++; - currentArray[k] = n; - continue; - } - } - setCount(0, solid, section); - if (fill) { - fs.setCount(j, Short.MAX_VALUE); - } - } - - // 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((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + 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) { - MainUtil.handleError(e); - } - 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; - } - } - } - 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"); - Field fieldNonEmptyBlockCount = clazz.getDeclaredField("field_76682_b"); - fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount.setAccessible(true); - fieldTickingBlockCount.set(section, tickingBlockCount); - fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount); - } - - @Override - public FaweChunk getFaweChunk(int x, int z) { - return new SpongeChunk_1_8(this, x, z); - } - - - @Override - 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()) { - 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; - - 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: - case 213: - 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()) { - MainUtil.handleError(e); - } - } - 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)) - && isSolid(getId(sections, x - 1, y, z)) - && isSolid(getId(sections, x, y, z + 1)) - && isSolid(getId(sections, x, y, z - 1)); - } - - public boolean isSolid(int i) { - return i != 0 && Block.getBlockById(i).isOpaqueCube(); - } - - public int getId(ExtendedBlockStorage[] sections, int x, int y, int z) { - if (x < 0 || x > 15 || z < 0 || z > 15) { - return 1; - } - if (y < 0 || y > 255) { - return 1; - } - int i = FaweCache.CACHE_I[y][z][x]; - ExtendedBlockStorage section = sections[i]; - if (section == null) { - return 0; - } - char[] array = section.getData(); - int j = FaweCache.CACHE_J[y][z][x]; - return array[j] >> 4; - } - - @Override - public boolean loadChunk(World world, int x, int z, boolean generate) { - return getCachedSections(world, x, z) != null; - } - - @Override - public ExtendedBlockStorage[] getCachedSections(World world, int cx, int cz) { - net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world; - IChunkProvider provider = nmsWorld.getChunkProvider(); - net.minecraft.world.chunk.Chunk chunk = provider.provideChunk(cx, cz); - if (chunk == null) { - return null; - } - if (!chunk.isLoaded()) { - chunk.onChunkLoad(); - } - return chunk.getBlockStorageArray(); - } - - @Override - public int getCombinedId4Data(char[] chars, int x, int y, int z) { - return chars[FaweCache.CACHE_J[y][z & 15][x & 15]]; - } - - -}