Update sponge jar
This commit is contained in:
parent
4ea09c11de
commit
32ae0f1d48
@ -88,7 +88,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
if (Bukkit.getPluginManager().getPlugin("WorldEdit") != null) {
|
if (Bukkit.getPluginManager().getPlugin("WorldEdit") != null) {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
// Inject
|
// Inject
|
||||||
EditSessionBlockChangeDelegate.inject();
|
EditSessionBlockChangeDelegate.inject();
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,7 +229,6 @@ public class Fawe {
|
|||||||
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.PATHS.CLIPBOARD), TimeUnit.DAYS.toMillis(Settings.CLIPBOARD.DELETE_AFTER_DAYS));
|
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.PATHS.CLIPBOARD), TimeUnit.DAYS.toMillis(Settings.CLIPBOARD.DELETE_AFTER_DAYS));
|
||||||
|
|
||||||
TaskManager.IMP = this.IMP.getTaskManager();
|
TaskManager.IMP = this.IMP.getTaskManager();
|
||||||
TaskManager.IMP.repeat(timer = new FaweTimer(), 1);
|
|
||||||
if (Settings.METRICS) {
|
if (Settings.METRICS) {
|
||||||
this.IMP.startMetrics();
|
this.IMP.startMetrics();
|
||||||
}
|
}
|
||||||
@ -238,22 +237,32 @@ public class Fawe {
|
|||||||
* Instance independent stuff
|
* Instance independent stuff
|
||||||
*/
|
*/
|
||||||
this.setupMemoryListener();
|
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() {
|
TaskManager.IMP.later(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Events
|
try {
|
||||||
Fawe.this.IMP.setupVault();
|
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);
|
}, 0);
|
||||||
|
|
||||||
|
TaskManager.IMP.repeat(timer, 1);
|
||||||
|
|
||||||
if (Settings.UPDATE) {
|
if (Settings.UPDATE) {
|
||||||
// Delayed updating
|
// Delayed updating
|
||||||
TaskManager.IMP.async(new Runnable() {
|
TaskManager.IMP.async(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Updater.update(implementation.getPlatform(), getVersion());
|
Updater.update(IMP.getPlatform(), getVersion());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -326,28 +335,15 @@ public class Fawe {
|
|||||||
return this.worldedit;
|
return this.worldedit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupInjector() {
|
public static void setupInjector() {
|
||||||
/*
|
/*
|
||||||
* Modify the sessions
|
* Modify the sessions
|
||||||
* - EditSession supports custom queue and a lot of optimizations
|
* - EditSession supports custom queue and a lot of optimizations
|
||||||
* - LocalSession supports VirtualPlayers and undo on disk
|
* - LocalSession supports VirtualPlayers and undo on disk
|
||||||
*/
|
*/
|
||||||
try {
|
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
|
// Setting up commands.yml
|
||||||
Commands.load(new File(this.IMP.getDirectory(), "commands.yml"));
|
Commands.inject(); // Translations
|
||||||
EditSession.inject(); // Custom block placer + optimizations
|
EditSession.inject(); // Custom block placer + optimizations
|
||||||
EditSessionEvent.inject(); // Add EditSession to event (API)
|
EditSessionEvent.inject(); // Add EditSession to event (API)
|
||||||
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk
|
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk
|
||||||
@ -464,12 +460,7 @@ public class Fawe {
|
|||||||
MainUtil.handleError(e, false);
|
MainUtil.handleError(e, false);
|
||||||
debug("=======================================");
|
debug("=======================================");
|
||||||
debug("Update the plugin, or contact the Author!");
|
debug("Update the plugin, or contact the Author!");
|
||||||
if (IMP.getPlatform().equals("bukkit")) {
|
|
||||||
debug(" - http://builds.enginehub.org/job/worldedit?branch=master");
|
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("=======================================");
|
debug("=======================================");
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -519,7 +510,7 @@ public class Fawe {
|
|||||||
debug("====================================");
|
debug("====================================");
|
||||||
}
|
}
|
||||||
} catch (Throwable ignore) {}
|
} catch (Throwable ignore) {}
|
||||||
if (!isJava8) {
|
if (MainUtil.getJavaVersion() < 1.8) {
|
||||||
debug("====== UPGRADE TO JAVA 8 ======");
|
debug("====== UPGRADE TO JAVA 8 ======");
|
||||||
debug("You are running " + System.getProperty("java.version"));
|
debug("You are running " + System.getProperty("java.version"));
|
||||||
debug(" - This is only a recommendation");
|
debug(" - This is only a recommendation");
|
||||||
|
@ -122,4 +122,8 @@ public class Commands {
|
|||||||
return command.anyFlags();
|
return command.anyFlags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<Commands> inject() {
|
||||||
|
return Commands.class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class RollbackDatabase {
|
|||||||
this.prefix = "";
|
this.prefix = "";
|
||||||
this.worldName = Fawe.imp().getWorldName(world);
|
this.worldName = Fawe.imp().getWorldName(world);
|
||||||
this.world = 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();
|
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))";
|
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(?,?,?,?,?,?,?,?,?)";
|
INSERT_EDIT = "INSERT OR REPLACE INTO `" + prefix + "edits` (`player`,`id`,`x1`,`y1`,`z1`,`x2`,`y2`,`z2`,`time`) VALUES(?,?,?,?,?,?,?,?,?)";
|
||||||
|
@ -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) {
|
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);
|
if (world == null && this.worldName != null) world = FaweAPI.getWorld(this.worldName);
|
||||||
this.world = world = WorldWrapper.wrap((AbstractWorld) world);
|
this.world = world = WorldWrapper.wrap((AbstractWorld) world);
|
||||||
if (bus == null) {
|
if (bus == null) {
|
||||||
|
@ -183,7 +183,7 @@ public class ClipboardCommands {
|
|||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
|
||||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||||
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
|
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
|
||||||
BBC.COMMAND_CUT_SLOW.send(player, region.getArea());
|
BBC.COMMAND_CUT_LAZY.send(player, region.getArea());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -221,7 +221,7 @@ public class ClipboardCommands {
|
|||||||
Operations.completeLegacy(copy);
|
Operations.completeLegacy(copy);
|
||||||
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
|
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")
|
@Command(aliases = { "download" }, desc = "Download your clipboard")
|
||||||
|
@ -61,7 +61,6 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -356,7 +355,6 @@ public class SchematicCommands {
|
|||||||
build.append(file.getName());
|
build.append(file.getName());
|
||||||
} else {
|
} else {
|
||||||
String relative = dir.toURI().relativize(file.toURI()).getPath();
|
String relative = dir.toURI().relativize(file.toURI()).getPath();
|
||||||
String[] split = file.getPath().split(Pattern.quote(prefix + File.separator));
|
|
||||||
build.append(relative);
|
build.append(relative);
|
||||||
}
|
}
|
||||||
build.append(": ").append(format == null ? "Unknown" : format.name());
|
build.append(": ").append(format == null ? "Unknown" : format.name());
|
||||||
|
@ -89,7 +89,6 @@ public class SelectionCommands {
|
|||||||
@Logging(POSITION)
|
@Logging(POSITION)
|
||||||
@CommandPermissions("worldedit.selection.pos")
|
@CommandPermissions("worldedit.selection.pos")
|
||||||
public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
Vector pos;
|
Vector pos;
|
||||||
|
|
||||||
if (args.argsLength() == 1) {
|
if (args.argsLength() == 1) {
|
||||||
@ -122,7 +121,6 @@ public class SelectionCommands {
|
|||||||
@Logging(POSITION)
|
@Logging(POSITION)
|
||||||
@CommandPermissions("worldedit.selection.pos")
|
@CommandPermissions("worldedit.selection.pos")
|
||||||
public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
Vector pos;
|
Vector pos;
|
||||||
if (args.argsLength() == 1) {
|
if (args.argsLength() == 1) {
|
||||||
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
|
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
|
||||||
@ -156,7 +154,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.selection.hpos")
|
@CommandPermissions("worldedit.selection.hpos")
|
||||||
public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
Vector pos = player.getBlockTrace(300);
|
Vector pos = player.getBlockTrace(300);
|
||||||
|
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
@ -181,7 +178,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.selection.hpos")
|
@CommandPermissions("worldedit.selection.hpos")
|
||||||
public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
Vector pos = player.getBlockTrace(300);
|
Vector pos = player.getBlockTrace(300);
|
||||||
|
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
@ -275,7 +271,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.wand")
|
@CommandPermissions("worldedit.wand")
|
||||||
public void wand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void wand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
player.giveItem(we.getConfiguration().wandItem, 1);
|
player.giveItem(we.getConfiguration().wandItem, 1);
|
||||||
BBC.SELECTION_WAND.send(player);
|
BBC.SELECTION_WAND.send(player);
|
||||||
BBC.TIP_SEL_LIST.or(BBC.TIP_SELECT_CONNECTED, BBC.TIP_SET_POS1, BBC.TIP_FARWAND).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")
|
@CommandPermissions("worldedit.wand.toggle")
|
||||||
public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
session.setToolControl(!session.isToolControlEnabled());
|
session.setToolControl(!session.isToolControlEnabled());
|
||||||
|
|
||||||
if (session.isToolControlEnabled()) {
|
if (session.isToolControlEnabled()) {
|
||||||
@ -310,7 +304,6 @@ public class SelectionCommands {
|
|||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
@CommandPermissions("worldedit.selection.expand")
|
@CommandPermissions("worldedit.selection.expand")
|
||||||
public void expand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void expand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
// Special syntax (//expand vert) to expand the selection between
|
// Special syntax (//expand vert) to expand the selection between
|
||||||
// sky and bedrock.
|
// sky and bedrock.
|
||||||
if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) {
|
if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) {
|
||||||
@ -402,7 +395,6 @@ public class SelectionCommands {
|
|||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
@CommandPermissions("worldedit.selection.contract")
|
@CommandPermissions("worldedit.selection.contract")
|
||||||
public void contract(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void contract(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
List<Vector> dirs = new ArrayList<Vector>();
|
List<Vector> dirs = new ArrayList<Vector>();
|
||||||
int change = args.getInteger(0);
|
int change = args.getInteger(0);
|
||||||
int reverseChange = 0;
|
int reverseChange = 0;
|
||||||
@ -476,7 +468,6 @@ public class SelectionCommands {
|
|||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
@CommandPermissions("worldedit.selection.shift")
|
@CommandPermissions("worldedit.selection.shift")
|
||||||
public void shift(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void shift(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
List<Vector> dirs = new ArrayList<Vector>();
|
List<Vector> dirs = new ArrayList<Vector>();
|
||||||
int change = args.getInteger(0);
|
int change = args.getInteger(0);
|
||||||
if (args.argsLength() == 2) {
|
if (args.argsLength() == 2) {
|
||||||
@ -582,7 +573,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.selection.size")
|
@CommandPermissions("worldedit.selection.size")
|
||||||
public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
if (args.hasFlag('c')) {
|
if (args.hasFlag('c')) {
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
Clipboard clipboard = holder.getClipboard();
|
Clipboard clipboard = holder.getClipboard();
|
||||||
@ -626,7 +616,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.analysis.count")
|
@CommandPermissions("worldedit.analysis.count")
|
||||||
public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
boolean useData = args.hasFlag('d');
|
boolean useData = args.hasFlag('d');
|
||||||
if (args.getString(0).contains(":")) {
|
if (args.getString(0).contains(":")) {
|
||||||
useData = true; //override d flag, if they specified data they want it
|
useData = true; //override d flag, if they specified data they want it
|
||||||
@ -656,7 +645,6 @@ public class SelectionCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.analysis.distr")
|
@CommandPermissions("worldedit.analysis.distr")
|
||||||
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
|
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
boolean useData = args.hasFlag('d');
|
boolean useData = args.hasFlag('d');
|
||||||
List<Countable<Integer>> distribution = null;
|
List<Countable<Integer>> distribution = null;
|
||||||
|
@ -162,7 +162,7 @@ public class BundledBlockData {
|
|||||||
}
|
}
|
||||||
FaweState dir = entry.states.get("rotation");
|
FaweState dir = entry.states.get("rotation");
|
||||||
if (dir != null && dir.values != null) {
|
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(0.5, 0, -1),
|
||||||
new Vector(1, 0, -1),
|
new Vector(1, 0, -1),
|
||||||
new Vector(1, 0, -0.5),
|
new Vector(1, 0, -0.5),
|
||||||
@ -178,12 +178,9 @@ public class BundledBlockData {
|
|||||||
new Vector(-1, 0, -0.5),
|
new Vector(-1, 0, -0.5),
|
||||||
new Vector(-1, 0, -1),
|
new Vector(-1, 0, -1),
|
||||||
new Vector(-0.5, 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()) {
|
for (Map.Entry<String, FaweStateValue> valuesEntry : dir.values.entrySet()) {
|
||||||
valuesEntry.getValue().setDirection(dirs[index]);
|
int index = Integer.parseInt(valuesEntry.getKey());
|
||||||
index += increment;
|
valuesEntry.getValue().setDirection(range[index]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -194,15 +191,15 @@ public class BundledBlockData {
|
|||||||
FaweStateValue z = axis.values.get("z");
|
FaweStateValue z = axis.values.get("z");
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
x.setDirection(new Vector(1, 0, 0));
|
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) {
|
if (y != null) {
|
||||||
y.setDirection(new Vector(0, 1, 0));
|
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) {
|
if (z != null) {
|
||||||
z.setDirection(new Vector(0, 0, 1));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ public class FaweForge implements IFawe {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
try {
|
try {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Fawe.debug("Failed to inject WorldEdit classes.");
|
Fawe.debug("Failed to inject WorldEdit classes.");
|
||||||
|
@ -51,7 +51,7 @@ public class FaweForge implements IFawe {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
try {
|
try {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Fawe.debug("Failed to inject WorldEdit classes.");
|
Fawe.debug("Failed to inject WorldEdit classes.");
|
||||||
|
@ -51,7 +51,7 @@ public class FaweForge implements IFawe {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
try {
|
try {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Fawe.debug("Failed to inject WorldEdit classes.");
|
Fawe.debug("Failed to inject WorldEdit classes.");
|
||||||
|
@ -51,7 +51,7 @@ public class FaweForge implements IFawe {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
try {
|
try {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Fawe.debug("Failed to inject WorldEdit classes.");
|
Fawe.debug("Failed to inject WorldEdit classes.");
|
||||||
|
@ -51,7 +51,7 @@ public class FaweForge implements IFawe {
|
|||||||
|
|
||||||
public void setupInjector() {
|
public void setupInjector() {
|
||||||
try {
|
try {
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
com.sk89q.worldedit.forge.ForgePlayer.inject();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Fawe.debug("Failed to inject WorldEdit classes.");
|
Fawe.debug("Failed to inject WorldEdit classes.");
|
||||||
|
@ -75,7 +75,7 @@ public class NukkitWorldEdit extends PluginBase {
|
|||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
try {
|
try {
|
||||||
Fawe.set(new FaweNukkit(this));
|
Fawe.set(new FaweNukkit(this));
|
||||||
Fawe.get().setupInjector();
|
Fawe.setupInjector();
|
||||||
Settings.HISTORY.COMBINE_STAGES = false;
|
Settings.HISTORY.COMBINE_STAGES = false;
|
||||||
logger = Logger.getLogger(NukkitWorldEdit.class.getCanonicalName());
|
logger = Logger.getLogger(NukkitWorldEdit.class.getCanonicalName());
|
||||||
createDefaultConfiguration("config-basic.yml");
|
createDefaultConfiguration("config-basic.yml");
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
rootProject.name = 'FastAsyncWorldEdit'
|
rootProject.name = 'FastAsyncWorldEdit'
|
||||||
|
|
||||||
include 'core', 'bukkit', 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'favs', 'nukkit'
|
include 'core', 'bukkit', 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'favs', 'nukkit', 'sponge'
|
||||||
|
@ -11,6 +11,9 @@ buildscript {
|
|||||||
}
|
}
|
||||||
maven {url = "https://oss.sonatype.org/content/repositories/snapshots/"}
|
maven {url = "https://oss.sonatype.org/content/repositories/snapshots/"}
|
||||||
maven {url = "http://repo.minecrell.net/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 {
|
dependencies {
|
||||||
classpath 'net.minecrell:VanillaGradle:2.0.3_1'
|
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: 'net.minecrell.vanilla.server.library'
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':core')
|
compile project(':core')
|
||||||
compile 'org.spongepowered:spongeapi:4.+'
|
compile 'org.spongepowered:spongeapi:5.1.0-SNAPSHOT'
|
||||||
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
|
compile 'org.spongepowered:mixin:0.6.1-SNAPSHOT'
|
||||||
|
compile 'com.sk89q.worldedit:worldedit-forge-mc1.10.2:6.1.5'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 1.8
|
||||||
@ -45,8 +53,8 @@ repositories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
minecraft {
|
minecraft {
|
||||||
version = "1.8.9"
|
version = "1.10.2"
|
||||||
mappings = "stable_22"
|
mappings = "snapshot_20161029"
|
||||||
runDir = 'run'
|
runDir = 'run'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +71,7 @@ processResources {
|
|||||||
shadowJar {
|
shadowJar {
|
||||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||||
dependencies {
|
dependencies {
|
||||||
|
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||||
include(dependency(':core'))
|
include(dependency(':core'))
|
||||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package com.boydti.fawe;
|
package com.boydti.fawe;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.FaweCommand;
|
import com.boydti.fawe.object.FaweCommand;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import org.spongepowered.api.command.CommandCallable;
|
import org.spongepowered.api.command.CommandCallable;
|
||||||
import org.spongepowered.api.command.CommandException;
|
import org.spongepowered.api.command.CommandException;
|
||||||
import org.spongepowered.api.command.CommandResult;
|
import org.spongepowered.api.command.CommandResult;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.text.Text;
|
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.
|
* Created by Jesse on 4/2/2016.
|
||||||
@ -35,19 +37,22 @@ public class SpongeCommand implements CommandCallable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
@Override
|
||||||
public boolean testPermission(CommandSource source) {return true;}
|
public boolean testPermission(CommandSource source) {return true;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<? extends Text> getShortDescription(final CommandSource cmd) {
|
public Optional<Text> getShortDescription(CommandSource source) {
|
||||||
return Optional.of(Text.of("Various"));
|
return Optional.of(Text.of("Various"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<? extends Text> getHelp(final CommandSource cmd) {
|
public Optional<Text> getHelp(CommandSource source) {
|
||||||
return Optional.of(Text.of("/<stream|wea|select>"));
|
return Optional.of(Text.of("/" + this.cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,16 +4,12 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.IFawe;
|
import com.boydti.fawe.IFawe;
|
||||||
import com.boydti.fawe.SpongeCommand;
|
import com.boydti.fawe.SpongeCommand;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
|
||||||
import com.boydti.fawe.object.FaweCommand;
|
import com.boydti.fawe.object.FaweCommand;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.regions.FaweMaskManager;
|
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.MainUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.forge.ForgeWorldEdit;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -34,24 +30,15 @@ public class FaweSponge implements IFawe {
|
|||||||
|
|
||||||
public FaweSponge instance;
|
public FaweSponge instance;
|
||||||
|
|
||||||
private ForgeWorldEdit worldedit;
|
|
||||||
|
|
||||||
public ForgeWorldEdit getWorldEditPlugin() {
|
|
||||||
if (this.worldedit == null) {
|
|
||||||
this.worldedit = ForgeWorldEdit.inst;
|
|
||||||
}
|
|
||||||
return this.worldedit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FaweSponge(SpongeMain plugin) {
|
public FaweSponge(SpongeMain plugin) {
|
||||||
instance = this;
|
instance = this;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
try {
|
try {
|
||||||
Fawe.set(this);
|
Fawe.set(this);
|
||||||
|
Fawe.setupInjector();
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
TaskManager.IMP.later(() -> SpongeUtil.initBiomeCache(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -100,23 +87,13 @@ public class FaweSponge implements IFawe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getVersion() {
|
public FaweQueue getNewQueue(World world, boolean fast) {
|
||||||
debug("[FAWE] Checking minecraft version: Sponge: ");
|
return new com.boydti.fawe.sponge.v1_10.SpongeQueue_1_10(getWorldName(world));
|
||||||
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};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweQueue getNewQueue(String world, boolean fast) {
|
public FaweQueue getNewQueue(String world, boolean fast) {
|
||||||
if (fast || Settings.HISTORY.COMBINE_STAGES) {
|
return new com.boydti.fawe.sponge.v1_10.SpongeQueue_1_10(world);
|
||||||
try {
|
|
||||||
return new SpongeQueue_1_8(world);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
MainUtil.handleError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new SpongeQueue_ALL(world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.boydti.fawe.sponge;
|
package com.boydti.fawe.sponge;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweAPI;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@ -10,16 +9,16 @@ import org.spongepowered.api.Game;
|
|||||||
import org.spongepowered.api.Server;
|
import org.spongepowered.api.Server;
|
||||||
import org.spongepowered.api.entity.living.player.Player;
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
import org.spongepowered.api.event.Listener;
|
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.game.state.GamePreInitializationEvent;
|
||||||
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
import org.spongepowered.api.plugin.Plugin;
|
import org.spongepowered.api.plugin.Plugin;
|
||||||
import org.spongepowered.api.plugin.PluginContainer;
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
import org.spongepowered.api.profile.GameProfileManager;
|
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 {
|
public class SpongeMain {
|
||||||
|
@Inject
|
||||||
public PluginContainer plugin;
|
public PluginContainer plugin;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -46,12 +45,11 @@ public class SpongeMain {
|
|||||||
return this.resolver;
|
return this.resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Listener(order = Order.PRE)
|
||||||
@Listener
|
|
||||||
public void onGamePreInit(GamePreInitializationEvent event) {
|
public void onGamePreInit(GamePreInitializationEvent event) {
|
||||||
plugin = this.game.getPluginManager().fromInstance(this).get();
|
|
||||||
this.server = this.game.getServer();
|
this.server = this.game.getServer();
|
||||||
new FaweSponge(this);
|
new FaweSponge(this);
|
||||||
|
Settings.QUEUE.PARALLEL_THREADS = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listener
|
@Listener
|
||||||
@ -61,20 +59,4 @@ public class SpongeMain {
|
|||||||
fp.unregister();
|
fp.unregister();
|
||||||
Fawe.get().unregister(player.getName());
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ package com.boydti.fawe.sponge;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -131,7 +131,7 @@ public class SpongeMetrics {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static byte[] gzip(final String input) {
|
public static byte[] gzip(final String input) {
|
||||||
final ByteArrayOutputStream baos = new FastByteArrayOutputStream();
|
final FastByteArrayOutputStream baos = new FastByteArrayOutputStream();
|
||||||
GZIPOutputStream gzos = null;
|
GZIPOutputStream gzos = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package com.boydti.fawe.sponge;
|
package com.boydti.fawe.sponge;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.FaweLocation;
|
import com.boydti.fawe.object.FaweLocation;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
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 java.util.UUID;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
import org.spongepowered.api.entity.living.player.Player;
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
import org.spongepowered.api.text.Text;
|
import org.spongepowered.api.text.Text;
|
||||||
@ -72,6 +74,19 @@ public class SpongePlayer extends FawePlayer<Player> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public com.sk89q.worldedit.entity.Player getPlayer() {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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.FaweCache;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.example.CharFaweChunk;
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -39,7 +38,6 @@ import net.minecraft.util.LongHashMap;
|
|||||||
import net.minecraft.world.ChunkCoordIntPair;
|
import net.minecraft.world.ChunkCoordIntPair;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
import net.minecraft.world.chunk.IChunkProvider;
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
import net.minecraft.world.chunk.NibbleArray;
|
|
||||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
import net.minecraft.world.gen.ChunkProviderServer;
|
import net.minecraft.world.gen.ChunkProviderServer;
|
||||||
import org.spongepowered.api.Sponge;
|
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.MutableBlockVolumeWorker;
|
||||||
import org.spongepowered.api.world.extent.worker.procedure.BlockVolumeMapper;
|
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;
|
private Method methodToNative;
|
||||||
|
|
||||||
public SpongeQueue_ALL(String world) {
|
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
|
@Override
|
||||||
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) {
|
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) {
|
||||||
if (!nmsChunk.isLoaded()) {
|
if (!nmsChunk.isLoaded()) {
|
||||||
@ -189,9 +192,8 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
|||||||
return provider.chunkExists(x, z);
|
return provider.chunkExists(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean regenerateChunk(World world, int x, int z) {
|
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||||
try {
|
try {
|
||||||
net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world;
|
net.minecraft.world.World nmsWorld = (net.minecraft.world.World) world;
|
||||||
IChunkProvider provider = nmsWorld.getChunkProvider();
|
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");
|
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
|
@Override
|
||||||
public boolean loadChunk(World world, int x, int z, boolean generate) {
|
public boolean loadChunk(World world, int x, int z, boolean generate) {
|
||||||
return getCachedSections(world, x, z) != null;
|
return getCachedSections(world, x, z) != 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<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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user