Update sponge jar

This commit is contained in:
Jesse Boyd 2016-12-26 18:42:33 +11:00
parent 4ea09c11de
commit 32ae0f1d48
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
28 changed files with 1045 additions and 1041 deletions

View File

@ -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 {

View File

@ -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");

View File

@ -122,4 +122,8 @@ public class Commands {
return command.anyFlags();
}
}
public static Class<Commands> inject() {
return Commands.class;
}
}

View File

@ -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(?,?,?,?,?,?,?,?,?)";

View File

@ -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) {

View File

@ -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")

View File

@ -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());

View File

@ -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<Vector> dirs = new ArrayList<Vector>();
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<Vector> dirs = new ArrayList<Vector>();
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<Countable<Integer>> distribution = null;

View File

@ -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<String, FaweStateValue> 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<String, FaweStateValue> valuesEntry : dir.values.entrySet()) {
valuesEntry.getValue().setDirection(dirs[index]);
index ++;
index++;
}
return true;
}

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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");

View File

@ -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'

View File

@ -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'))
}

View File

@ -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<String> getSuggestions(CommandSource source, String arguments) throws CommandException {return null;}
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) throws CommandException {
return null;
}
@Override
public boolean testPermission(CommandSource source) {return true;}
@Override
public Optional<? extends Text> getShortDescription(final CommandSource cmd) {
public Optional<Text> getShortDescription(CommandSource source) {
return Optional.of(Text.of("Various"));
}
@Override
public Optional<? extends Text> getHelp(final CommandSource cmd) {
return Optional.of(Text.of("/<stream|wea|select>"));
public Optional<Text> getHelp(CommandSource source) {
return Optional.of(Text.of("/" + this.cmd));
}
@Override

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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 {

View File

@ -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<Player> {
@Override
public com.sk89q.worldedit.entity.Player getPlayer() {
return PlayerWrapper.wrap(Fawe.<FaweSponge> 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;
}
}
}

View File

@ -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<String, Integer> biomeMap;
public static Map<Integer, BiomeData> 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<Integer, BiomeData>) bdf.get(null);
biomes = new BiomeType[256];
biomeMap = new HashMap<>();
int lastId = 0;
loop:
for (Map.Entry<Integer, BiomeData> 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);
}
}

View File

@ -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<Chunk, SpongeQueue_1_10> {
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<BlockPos, TileEntity> tiles = nmsChunk.getTileEntityMap();
ClassInheritanceMultiMap<Entity>[] 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<Entity> ents = entities[i];
if (!ents.isEmpty()) {
synchronized (SpongeChunk_1_10.class) {
entities[i] = new ClassInheritanceMultiMap<>(Entity.class);
}
}
} else {
char[] array = this.getIdArray(i);
Collection<Entity> 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<UUID> createdEntities = new HashSet<>();
Set<CompoundTag> entitiesToSpawn = this.getEntities();
if (!entitiesToSpawn.isEmpty()) {
synchronized (SpongeChunk_1_10.class) {
for (CompoundTag nativeTag : entitiesToSpawn) {
Map<String, Tag> 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<Tag> 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<Map.Entry<BlockPos, TileEntity>> entryset = tiles.entrySet();
Iterator<Map.Entry<BlockPos, TileEntity>> iterator = entryset.iterator();
while (iterator.hasNext()) {
Map.Entry<BlockPos, TileEntity> 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<UUID> entsToRemove = this.getEntityRemoves();
if (!entsToRemove.isEmpty()) {
synchronized (SpongeChunk_1_10.class) {
for (int i = 0; i < entities.length; i++) {
Collection<Entity> 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<Short, CompoundTag> tilesToSpawn = this.getTiles();
for (Map.Entry<Short, CompoundTag> 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;
}
}

View File

@ -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<World, net.minecraft.world.chunk.Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
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<Long, Map<Short, Character>> blockMap, FawePlayer... players) {
for (Map.Entry<Long, Map<Short, Character>> chunkEntry : blockMap.entrySet()) {
try {
long chunkHash = chunkEntry.getKey();
Map<Short, Character> 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<Short, Character> 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<BlockPos, TileEntity> 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<EntityPlayerMP> 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<EntityPlayerMP>) 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<Chunk> id2ChunkMap = (Long2ObjectMap<Chunk>) 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<UUID> createdEntities, boolean all) throws Exception {
Map<BlockPos, TileEntity> tiles = (Map<BlockPos, TileEntity>) tilesGeneric;
ClassInheritanceMultiMap<Entity>[] entities = (ClassInheritanceMultiMap<Entity>[]) 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<BlockPos, TileEntity> 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<Entity> 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<String, Tag> 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<EntityPlayerMP> 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<Entity>[] entities = nmsChunk.getEntityLists();
for (int i = 0; i < entities.length; i++) {
ClassInheritanceMultiMap<Entity> slice = entities[i];
if (slice != null && !slice.isEmpty()) {
return true;
}
}
return false;
}
@Override
public FaweChunk<Chunk> 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");
}
}

View File

@ -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<World, net.minecraft.world.chunk.Chunk, ExtendedBlockStorage[], char[]> {
public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.world.chunk.Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
private Method methodToNative;
public SpongeQueue_ALL(String world) {
@ -65,6 +63,11 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
}
}
@Override
public void refreshChunk(FaweChunk fs) {
}
@Override
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) {
if (!nmsChunk.isLoaded()) {
@ -189,9 +192,8 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
return provider.chunkExists(x, z);
}
@Override
public boolean regenerateChunk(World world, int x, int z) {
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
try {
net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world;
IChunkProvider provider = nmsWorld.getChunkProvider();
@ -300,137 +302,6 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
throw new UnsupportedOperationException("Combine stages not supported");
}
@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;
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;

View File

@ -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<net.minecraft.world.chunk.Chunk> {
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();
}
}

View File

@ -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<World, net.minecraft.world.chunk.Chunk, ExtendedBlockStorage[], char[]> {
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<BlockPos, TileEntity> 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<EntityPlayerMP> 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<EntityTrackerEntry> entities = new HashSet<>();
ClassInheritanceMultiMap<Entity>[] entitieSlices = nmsChunk.getEntityLists();
IntHashMap<EntityTrackerEntry> entries = null;
for (Field field : tracker.getClass().getDeclaredFields()) {
if (field.getType() == IntHashMap.class) {
field.setAccessible(true);
entries = (IntHashMap<EntityTrackerEntry>) field.get(tracker);
}
}
for (ClassInheritanceMultiMap<Entity> 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<net.minecraft.world.chunk.Chunk> id2ChunkMap = (LongHashMap<net.minecraft.world.chunk.Chunk>) id2ChunkMapField.get(chunkServer);
id2ChunkMap.remove(pos);
mcChunk = chunkProvider.provideChunk(x, z);
id2ChunkMap.add(pos, mcChunk);
List<net.minecraft.world.chunk.Chunk> 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<UUID> createdEntities, boolean all) throws Exception {
Map<BlockPos, TileEntity> tiles = (Map<BlockPos, TileEntity>) tilesGeneric;
ClassInheritanceMultiMap<Entity>[] entities = (ClassInheritanceMultiMap<Entity>[]) 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<BlockPos, TileEntity> 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<Entity> 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<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
map.put("Id", new StringTag(id));
previous.setEntity(nativeTag);
}
}
}
}
}
return previous;
}
@Override
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> 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<BlockPos, TileEntity> tiles = nmsChunk.getTileEntityMap();
ClassInheritanceMultiMap<Entity>[] 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<Entity> 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<UUID> createdEntities = new HashSet<>();
Set<CompoundTag> entitiesToSpawn = fs.getEntities();
for (CompoundTag nativeTag : entitiesToSpawn) {
Map<String, Tag> 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<Map.Entry<BlockPos, TileEntity>> entryset = tiles.entrySet();
Iterator<Map.Entry<BlockPos, TileEntity>> iterator = entryset.iterator();
while (iterator.hasNext()) {
Map.Entry<BlockPos, TileEntity> 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<UUID> entsToRemove = fs.getEntityRemoves();
if (entsToRemove.size() > 0) {
for (int i = 0; i < entities.length; i++) {
Collection<Entity> 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<BytePair, CompoundTag> tilesToSpawn = fs.getTiles();
int bx = fs.getX() << 4;
int bz = fs.getZ() << 4;
for (Map.Entry<BytePair, CompoundTag> 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<? extends ExtendedBlockStorage> 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<net.minecraft.world.chunk.Chunk> 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]];
}
}