mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 05:35:37 +01:00
Forge/Sponge 3.5.0
This commit is contained in:
parent
00c685cd93
commit
0bc703e1b9
@ -6,7 +6,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath 'org.ajoberstar:grgit:1.1.0'
|
||||
classpath 'org.ajoberstar:grgit:1.7.0'
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,7 +17,7 @@ clean { delete "target" }
|
||||
group = 'com.boydti.fawe'
|
||||
def revision = ""
|
||||
ext {
|
||||
git = org.ajoberstar.grgit.Grgit.open(file(".git/"))
|
||||
git = org.ajoberstar.grgit.Grgit.open(file(".git"))
|
||||
revision = "-${git.head().abbreviatedId}"
|
||||
}
|
||||
version = "3.5.0${revision}"
|
||||
|
@ -13,14 +13,4 @@ dependencies {
|
||||
compile 'com.worldcretornica:plotme_core:0.16.3'
|
||||
compile 'junit:junit:4.11'
|
||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.1-SNAPSHOT'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'plugin.yml'
|
||||
expand(
|
||||
name: project.parent.name,
|
||||
version: project.parent.version
|
||||
)
|
||||
}
|
||||
}
|
@ -3,6 +3,16 @@ dependencies {
|
||||
compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'plugin.yml'
|
||||
expand(
|
||||
name: project.parent.name,
|
||||
version: project.parent.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
// We only want the shadow jar produced
|
||||
jar.enabled = false
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: FastAsyncWorldEdit
|
||||
main: com.boydti.fawe.bukkit.v1_8.BukkitMain_18
|
||||
version: 3.4.3
|
||||
version: ${version}
|
||||
description: Fast Async WorldEdit plugin
|
||||
authors: [Empire92]
|
||||
loadbefore: [WorldEdit]
|
||||
|
@ -3,8 +3,17 @@ dependencies {
|
||||
compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4'
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'plugin.yml'
|
||||
expand(
|
||||
name: project.parent.name,
|
||||
version: project.parent.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
// We only want the shadow jar produced
|
||||
jar.enabled = false
|
||||
shadowJar {
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: FastAsyncWorldEdit
|
||||
name: ${name}
|
||||
main: com.boydti.fawe.bukkit.v1_9.BukkitMain_19
|
||||
version: 3.4.3
|
||||
version: ${version}
|
||||
description: Fast Async WorldEdit plugin
|
||||
authors: [Empire92]
|
||||
loadbefore: [WorldEdit]
|
||||
|
@ -226,46 +226,46 @@ public class Fawe {
|
||||
* - LocalSession supports VirtualPlayers and undo on disk
|
||||
*/
|
||||
try {
|
||||
EditSession.inject();
|
||||
LocalSession.inject();
|
||||
EditSession.inject(); // Custom block placer + optimizations
|
||||
LocalSession.inject(); // Add remember order / queue flushing
|
||||
// Commands
|
||||
BrushCommands.inject();
|
||||
ClipboardCommands.inject();
|
||||
SchematicCommands.inject();
|
||||
ScriptingCommands.inject();
|
||||
SelectionCommand.inject();
|
||||
RegionCommands.inject();
|
||||
HistoryCommands.inject();
|
||||
BrushCommands.inject(); // Translations + heightmap
|
||||
ClipboardCommands.inject(); // Translations + lazycopy + paste optimizations
|
||||
SchematicCommands.inject(); // Translations
|
||||
ScriptingCommands.inject(); // Translations
|
||||
SelectionCommand.inject(); // Translations + set optimizations
|
||||
RegionCommands.inject(); // Translations
|
||||
HistoryCommands.inject(); // Translations
|
||||
// Brushes
|
||||
GravityBrush.inject();
|
||||
GravityBrush.inject(); // Fix for instant placement assumption
|
||||
// Selectors
|
||||
CuboidRegionSelector.inject();
|
||||
CuboidRegionSelector.inject(); // Translations
|
||||
// Visitors
|
||||
BreadthFirstSearch.inject();
|
||||
DownwardVisitor.inject();
|
||||
EntityVisitor.inject();
|
||||
FlatRegionVisitor.inject();
|
||||
LayerVisitor.inject();
|
||||
NonRisingVisitor.inject();
|
||||
RecursiveVisitor.inject();
|
||||
RegionVisitor.inject();
|
||||
BreadthFirstSearch.inject(); // Translations + Optimizations
|
||||
DownwardVisitor.inject(); // Optimizations
|
||||
EntityVisitor.inject(); // Translations + Optimizations
|
||||
FlatRegionVisitor.inject(); // Translations + Optimizations
|
||||
LayerVisitor.inject(); // Optimizations
|
||||
NonRisingVisitor.inject(); // Optimizations
|
||||
RecursiveVisitor.inject(); // Optimizations
|
||||
RegionVisitor.inject(); // Translations + Optimizations
|
||||
// Entity create/remove
|
||||
EntityCreate.inject();
|
||||
EntityRemove.inject();
|
||||
EntityCreate.inject(); // Optimizations
|
||||
EntityRemove.inject(); // Optimizations
|
||||
// Clipboards
|
||||
BlockArrayClipboard.inject();
|
||||
CuboidClipboard.inject();
|
||||
BlockArrayClipboard.inject(); // Optimizations + disk
|
||||
CuboidClipboard.inject(); // Optimizations
|
||||
// Regions
|
||||
CuboidRegion.inject();
|
||||
CuboidRegion.inject(); // Optimizations
|
||||
// Extents
|
||||
BlockTransformExtent.inject();
|
||||
BlockTransformExtent.inject(); // Fix for cache not being mutable
|
||||
// Vector
|
||||
Vector.inject();
|
||||
Vector.inject(); // Optimizations
|
||||
// Operations
|
||||
Operations.inject();
|
||||
Operations.inject(); // Optimizations
|
||||
try {
|
||||
CommandManager.inject();
|
||||
PlatformManager.inject();
|
||||
CommandManager.inject(); // Async commands
|
||||
PlatformManager.inject(); // Async brushes / tools
|
||||
} catch (Throwable e) {
|
||||
debug("====== UPDATE WORLDEDIT TO 6.1.1 ======");
|
||||
e.printStackTrace();
|
||||
@ -284,6 +284,7 @@ public class Fawe {
|
||||
e.printStackTrace();
|
||||
debug("=======================================");
|
||||
debug("Things to check: ");
|
||||
debug(" - Using WorldEdit 6.1.1");
|
||||
debug(" - AsyncWorldEdit/WorldEditRegions isn't installed");
|
||||
debug(" - Any other errors in the startup log");
|
||||
debug(" - Contact Empire92 for assistance!");
|
||||
|
@ -188,10 +188,8 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
char[] vs = this.ids[i];
|
||||
if (vs == null) {
|
||||
vs = this.ids[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
}
|
||||
this.count[i]++;
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
@ -277,11 +275,7 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
// if (data < 2) {
|
||||
// data = 2;
|
||||
// }
|
||||
|
||||
case 68: // removed
|
||||
default:
|
||||
vs[j] = (char) ((id << 4) + data);
|
||||
return;
|
||||
|
@ -109,9 +109,9 @@ public abstract class FawePlayer<T> {
|
||||
}
|
||||
|
||||
public void loadClipboardFromDisk() {
|
||||
File file = new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + getUUID());
|
||||
try {
|
||||
File file = new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + getUUID());
|
||||
if (file.exists()) {
|
||||
if (file.exists() && file.length() > 5) {
|
||||
DiskOptimizedClipboard doc = new DiskOptimizedClipboard(file);
|
||||
Player player = getPlayer();
|
||||
LocalSession session = getSession();
|
||||
@ -128,8 +128,13 @@ public abstract class FawePlayer<T> {
|
||||
getSession().setClipboard(holder);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception ignore) {
|
||||
Fawe.debug("====== INVALID CLIPBOARD ======");
|
||||
ignore.printStackTrace();
|
||||
Fawe.debug("===============---=============");
|
||||
Fawe.debug("This shouldn't result in any failure");
|
||||
Fawe.debug("File: " + file.getName() + " (len:" + file.length() + ")");
|
||||
Fawe.debug("===============---=============");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,17 +108,29 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
|
||||
@Override
|
||||
public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException {
|
||||
final short id = (short) block.getId();
|
||||
byte data = (byte) block.getData();
|
||||
final int x = location.getBlockX();
|
||||
final int y = location.getBlockY();
|
||||
final int z = location.getBlockZ();
|
||||
switch (id) {
|
||||
case 68: {
|
||||
if (data == 0) {
|
||||
data = 2;
|
||||
}
|
||||
}
|
||||
case 63:
|
||||
case 68:
|
||||
if (block.hasNbtData() && !MainUtil.isValidSign(block.getNbtData())) {
|
||||
queue.setBlock(x, y, z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0);
|
||||
return true;
|
||||
}
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
{
|
||||
if (data == 0) {
|
||||
data = 2;
|
||||
}
|
||||
}
|
||||
case 130:
|
||||
case 142:
|
||||
case 27:
|
||||
@ -138,10 +150,8 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
|
||||
case 28:
|
||||
case 66:
|
||||
case 157:
|
||||
case 61:
|
||||
case 62:
|
||||
case 140:
|
||||
case 146:
|
||||
case 149:
|
||||
case 150:
|
||||
case 158:
|
||||
@ -157,11 +167,16 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
|
||||
MainUtil.setPosition(nbt, x, y, z);
|
||||
queue.setTile(x, y, z, nbt);
|
||||
}
|
||||
queue.setBlock(x, y, z, id, (byte) block.getData());
|
||||
queue.setBlock(x, y, z, id, data);
|
||||
return true;
|
||||
}
|
||||
case 65: {
|
||||
if (data == 0) {
|
||||
data = 2;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
queue.setBlock(x, y, z, id, (byte) block.getData());
|
||||
queue.setBlock(x, y, z, id, data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class DefaultProgressTracker extends RunnableVal2<FaweQueue.ProgressType, Integer> {
|
||||
|
||||
@ -63,7 +62,7 @@ public class DefaultProgressTracker extends RunnableVal2<FaweQueue.ProgressType,
|
||||
TaskManager.IMP.task(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long currentTick = Bukkit.getServer().getWorlds().get(0).getFullTime();
|
||||
long currentTick = System.currentTimeMillis() / 50;
|
||||
if (currentTick > lastTick + Settings.DISPLAY_PROGRESS_INTERVAL) {
|
||||
lastTick = currentTick;
|
||||
String queue = StringMan.padRight("" + amountQueue, 3);
|
||||
|
@ -97,6 +97,7 @@ public abstract class FaweQueue {
|
||||
public void endSet(boolean parallel) {}
|
||||
|
||||
public int cancel() {
|
||||
clear();
|
||||
int count = 0;
|
||||
for (EditSession session : sessions) {
|
||||
if (session.cancel()) {
|
||||
|
@ -204,7 +204,7 @@ public class LocalSession {
|
||||
}
|
||||
|
||||
public void remember(final EditSession editSession, final boolean append, final boolean sendMessage) {
|
||||
if (editSession == null) {
|
||||
if (editSession == null || editSession.getChangeSet() == null) {
|
||||
return;
|
||||
}
|
||||
if (Settings.STORE_HISTORY_ON_DISK) {
|
||||
|
@ -20,8 +20,6 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
@ -162,41 +160,31 @@ public class SchematicCommands {
|
||||
target = clipboard;
|
||||
}
|
||||
|
||||
SetQueue.IMP.addTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Closer closer = Closer.create();
|
||||
try {
|
||||
// Create parent directories
|
||||
final File parent = f.getParentFile();
|
||||
if ((parent != null) && !parent.exists()) {
|
||||
if (!parent.mkdirs()) {
|
||||
log.info("Could not create folder for schematics!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final FileOutputStream fos = closer.register(new FileOutputStream(f));
|
||||
final BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
||||
final ClipboardWriter writer = closer.register(format.getWriter(bos));
|
||||
writer.write(target, holder.getWorldData());
|
||||
log.info(player.getName() + " saved " + f.getCanonicalPath());
|
||||
BBC.SCHEMATIC_SAVED.send(player, filename);
|
||||
} catch (final IOException e) {
|
||||
player.printError("Schematic could not written: " + e.getMessage());
|
||||
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
|
||||
} finally {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (final IOException ignored) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
final Closer closer = Closer.create();
|
||||
try {
|
||||
// Create parent directories
|
||||
final File parent = f.getParentFile();
|
||||
if ((parent != null) && !parent.exists()) {
|
||||
if (!parent.mkdirs()) {
|
||||
log.info("Could not create folder for schematics!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final FileOutputStream fos = closer.register(new FileOutputStream(f));
|
||||
final BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
||||
final ClipboardWriter writer = closer.register(format.getWriter(bos));
|
||||
writer.write(target, holder.getWorldData());
|
||||
log.info(player.getName() + " saved " + f.getCanonicalPath());
|
||||
BBC.SCHEMATIC_SAVED.send(player, filename);
|
||||
} catch (final IOException e) {
|
||||
player.printError("Schematic could not written: " + e.getMessage());
|
||||
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
|
||||
} finally {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (final IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = { "delete", "d" }, usage = "<filename>", desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1)
|
||||
@ -207,22 +195,15 @@ public class SchematicCommands {
|
||||
|
||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, "schematic", "schematic");
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!f.exists()) {
|
||||
player.printError("Schematic " + filename + " does not exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!f.delete()) {
|
||||
player.printError("Deletion of " + filename + " failed! Maybe it is read-only.");
|
||||
return;
|
||||
}
|
||||
|
||||
BBC.SCHEMATIC_DELETE.send(player, filename);
|
||||
}
|
||||
});
|
||||
if (!f.exists()) {
|
||||
player.printError("Schematic " + filename + " does not exist!");
|
||||
return;
|
||||
}
|
||||
if (!f.delete()) {
|
||||
player.printError("Deletion of " + filename + " failed! Maybe it is read-only.");
|
||||
return;
|
||||
}
|
||||
BBC.SCHEMATIC_DELETE.send(player, filename);
|
||||
}
|
||||
|
||||
@Command(aliases = { "formats", "listformats", "f" }, desc = "List available formats", max = 0)
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
@ -69,21 +67,11 @@ public class ScriptingCommands {
|
||||
|
||||
final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir);
|
||||
final File f = this.worldEdit.getSafeOpenFile(player, dir, name, "js", "js");
|
||||
SetQueue.IMP.addTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs);
|
||||
} catch (final WorldEditException ex) {
|
||||
player.printError("Error while executing CraftScript.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
try {
|
||||
ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs);
|
||||
} catch (final WorldEditException ex) {
|
||||
player.printError("Error while executing CraftScript.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = { ".s" }, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1)
|
||||
@ -107,21 +95,11 @@ public class ScriptingCommands {
|
||||
final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir);
|
||||
final File f = this.worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
|
||||
|
||||
SetQueue.IMP.addTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs);
|
||||
} catch (final WorldEditException ex) {
|
||||
player.printError("Error while executing CraftScript.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
try {
|
||||
ScriptingCommands.this.worldEdit.runScript(player, f, scriptArgs);
|
||||
} catch (final WorldEditException ex) {
|
||||
player.printError("Error while executing CraftScript.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -125,7 +125,7 @@ public class FaweForge implements IFawe {
|
||||
@Override
|
||||
public void startMetrics() {
|
||||
try {
|
||||
ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.3");
|
||||
ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.5.0");
|
||||
metrics.start();
|
||||
debug("[FAWE] &6Metrics enabled.");
|
||||
} catch (Throwable e) {
|
||||
|
@ -19,7 +19,7 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.3", acceptableRemoteVersions = "*")
|
||||
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.5.0", acceptableRemoteVersions = "*")
|
||||
public class ForgeMain {
|
||||
private static FaweForge IMP;
|
||||
private Logger logger;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.boydti.fawe.forge;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLocation;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
@ -16,6 +17,16 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(String head, String sub) { // Not supported
|
||||
Settings.DISPLAY_PROGRESS = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTitle() { // Not supported
|
||||
Settings.DISPLAY_PROGRESS = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return parent.getCommandSenderName();
|
||||
|
@ -1,105 +1,32 @@
|
||||
package com.boydti.fawe.forge.v0;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
|
||||
public class ForgeChunk_All extends FaweChunk<Chunk> {
|
||||
public class ForgeChunk_All extends CharFaweChunk<Chunk> {
|
||||
|
||||
public byte[][] ids;
|
||||
public byte[][] byteIds;
|
||||
public NibbleArray[] datas;
|
||||
|
||||
public short[] count;
|
||||
public short[] air;
|
||||
public short[] relight;
|
||||
public byte[][] biomes;
|
||||
public Chunk chunk;
|
||||
|
||||
public ForgeChunk_All(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
this.ids = new byte[16][];
|
||||
this.byteIds = new byte[16][];
|
||||
this.datas = new NibbleArray[16];
|
||||
this.count = new short[16];
|
||||
this.air = new short[16];
|
||||
this.relight = new short[16];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Chunk getChunk() {
|
||||
if (this.chunk == null) {
|
||||
World world = ((ForgeQueue_All) getParent()).getWorld();
|
||||
this.chunk = world.getChunkProvider().provideChunk(getX(), getZ());
|
||||
}
|
||||
return this.chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoc(final FaweQueue parent, int x, int z) {
|
||||
super.setLoc(parent, x, z);
|
||||
this.chunk = null;
|
||||
public Chunk getNewChunk() {
|
||||
World world = ((ForgeQueue_All) getParent()).getWorld();
|
||||
return world.getChunkProvider().provideChunk(getX(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of block changes in a specified section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public int getCount(int i) {
|
||||
return this.count[i];
|
||||
}
|
||||
|
||||
public int getAir(int i) {
|
||||
return this.air[i];
|
||||
}
|
||||
|
||||
public void setCount(int i, short value) {
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of block changes in a specified section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public int getRelight(int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if (getTotalCount() == 0) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw data for a section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public byte[] getIdArray(int i) {
|
||||
return this.ids[i];
|
||||
public byte[] getByteIdArray(int i) {
|
||||
return this.byteIds[i];
|
||||
}
|
||||
|
||||
public NibbleArray getDataArray(int i) {
|
||||
@ -110,17 +37,20 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
|
||||
public void setBlock(int x, int y, int z, int id, byte data) {
|
||||
int i = FaweCache.CACHE_I[y][x][z];
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
byte[] vs = this.ids[i];
|
||||
if (vs == null) {
|
||||
vs = this.ids[i] = new byte[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
byte[] vs = this.byteIds[i];
|
||||
char[] vs2 = this.ids[i];
|
||||
if (vs2 == null) {
|
||||
vs2 = this.ids[i] = new char[4096];
|
||||
}
|
||||
if (vs == null) {
|
||||
vs = this.byteIds[i] = new byte[4096];
|
||||
}
|
||||
this.count[i]++;
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = -1;
|
||||
vs2[j] = (char) 1;
|
||||
return;
|
||||
case 10:
|
||||
case 11:
|
||||
@ -193,6 +123,7 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
|
||||
case 191:
|
||||
case 192:
|
||||
vs[j] = (byte) (id);
|
||||
vs2[j] = (char) (id << 4);
|
||||
return;
|
||||
case 130:
|
||||
case 76:
|
||||
@ -203,38 +134,26 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
// if (data < 2) {
|
||||
// data = 2;
|
||||
// }
|
||||
case 68: // removed
|
||||
default:
|
||||
vs2[j] = (char) ((id << 4) + data);
|
||||
vs[j] = (byte) id;
|
||||
NibbleArray dataArray = datas[i];
|
||||
if (dataArray == null) {
|
||||
datas[i] = dataArray = new NibbleArray(4096, 4);
|
||||
if (data != 0) {
|
||||
NibbleArray dataArray = datas[i];
|
||||
if (dataArray == null) {
|
||||
datas[i] = dataArray = new NibbleArray(4096, 4);
|
||||
}
|
||||
dataArray.set(x, y & 15, z, data);
|
||||
}
|
||||
dataArray.set(x, y & 15, z, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, BaseBiome biome) {
|
||||
if (this.biomes == null) {
|
||||
this.biomes = new byte[16][];
|
||||
}
|
||||
byte[] index = this.biomes[x];
|
||||
if (index == null) {
|
||||
index = this.biomes[x] = new byte[16];
|
||||
}
|
||||
index[z] = (byte) biome.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk<Chunk> copy(boolean shallow) {
|
||||
public CharFaweChunk<Chunk> copy(boolean shallow) {
|
||||
ForgeChunk_All copy = new ForgeChunk_All(getParent(), getX(), getZ());
|
||||
if (shallow) {
|
||||
copy.ids = ids;
|
||||
copy.byteIds = byteIds;
|
||||
copy.datas = datas;
|
||||
copy.air = air;
|
||||
copy.biomes = biomes;
|
||||
@ -242,7 +161,7 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
|
||||
copy.count = count;
|
||||
copy.relight = relight;
|
||||
} else {
|
||||
copy.ids = (byte[][]) MainUtil.copyNd(ids);
|
||||
copy.byteIds = (byte[][]) MainUtil.copyNd(byteIds);
|
||||
copy.datas = datas.clone();
|
||||
copy.air = air.clone();
|
||||
copy.biomes = biomes.clone();
|
||||
|
@ -2,20 +2,38 @@ package com.boydti.fawe.forge.v0;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.IntegerPair;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraft.network.play.server.S21PacketChunkData;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@ -32,10 +50,22 @@ import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
|
||||
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, ExtendedBlockStorage> {
|
||||
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
|
||||
|
||||
public ForgeQueue_All(final String world) {
|
||||
private Method methodFromNative;
|
||||
private Method methodToNative;
|
||||
|
||||
public ForgeQueue_All(String world) {
|
||||
super(world);
|
||||
try {
|
||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||
this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||
this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||
methodFromNative.setAccessible(true);
|
||||
methodToNative.setAccessible(true);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -44,12 +74,17 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
public ExtendedBlockStorage[] getCachedChunk(World world, int cx, int cz) {
|
||||
Chunk chunk = world.getChunkProvider().provideChunk(cx, cz);
|
||||
if (chunk != null && !chunk.isChunkLoaded) {
|
||||
chunk.onChunkLoad();
|
||||
}
|
||||
return chunk;
|
||||
return chunk != null ? chunk.getBlockStorageArray() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedBlockStorage getCachedSection(ExtendedBlockStorage[] extendedBlockStorages, int cy) {
|
||||
return extendedBlockStorages[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -186,16 +221,75 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setComponents(FaweChunk fc) {
|
||||
@Override
|
||||
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
|
||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||
Chunk forgeChunk = fs.getChunk();
|
||||
net.minecraft.world.World nmsWorld = forgeChunk.worldObj;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.worldObj;
|
||||
try {
|
||||
boolean flag = !nmsWorld.provider.hasNoSky;
|
||||
// Sections
|
||||
ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray();
|
||||
Map<ChunkPosition, TileEntity> tiles = forgeChunk.chunkTileEntityMap;
|
||||
List[] entities = forgeChunk.entityLists;
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
Map<ChunkPosition, TileEntity> tiles = nmsChunk.chunkTileEntityMap;
|
||||
List<Entity>[] entities = nmsChunk.entityLists;
|
||||
|
||||
// Remove entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int count = fs.getCount(i);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
entities[i].clear();
|
||||
} else {
|
||||
char[] array = fs.getIdArray(i);
|
||||
Collection<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;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 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<ChunkPosition, TileEntity>> entryset = tiles.entrySet();
|
||||
Iterator<Map.Entry<ChunkPosition, TileEntity>> iterator = entryset.iterator();
|
||||
@ -206,21 +300,33 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
int ly = pos.chunkPosY;
|
||||
int lz = pos.chunkPosZ & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
byte[] array = fs.getIdArray(j);
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
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++) {
|
||||
if (fs.getCount(j) == 0) {
|
||||
continue;
|
||||
}
|
||||
byte[] newIdArray = fs.getIdArray(j);
|
||||
byte[] newIdArray = fs.getByteIdArray(j);
|
||||
if (newIdArray == null) {
|
||||
continue;
|
||||
}
|
||||
@ -232,8 +338,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
section.setBlockMetadataArray(newDataArray);
|
||||
continue;
|
||||
}
|
||||
// id + data << 8
|
||||
|
||||
byte[] currentIdArray = section.getBlockLSBArray();
|
||||
NibbleArray currentDataArray = section.getMetadataArray();
|
||||
boolean data = currentDataArray != null;
|
||||
@ -241,6 +345,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
section.setBlockMetadataArray(newDataArray);
|
||||
}
|
||||
boolean fill = true;
|
||||
int solid = 0;
|
||||
for (int k = 0; k < newIdArray.length; k++) {
|
||||
byte n = newIdArray[k];
|
||||
switch (n) {
|
||||
@ -249,9 +354,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
continue;
|
||||
case -1:
|
||||
fill = false;
|
||||
if (currentIdArray[k] != 0) {
|
||||
solid++;
|
||||
}
|
||||
currentIdArray[k] = 0;
|
||||
continue;
|
||||
default:
|
||||
solid++;
|
||||
currentIdArray[k] = n;
|
||||
if (data) {
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
@ -266,81 +375,212 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
continue;
|
||||
}
|
||||
}
|
||||
setCount(0, solid, section);
|
||||
if (fill) {
|
||||
fs.setCount(j, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
// // Clear
|
||||
|
||||
// Set biomes
|
||||
int[][] biomes = fs.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<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();
|
||||
int x = MathMan.unpair16x(pair.pair[0]) + bx;
|
||||
int y = pair.pair[1] & 0xFF;
|
||||
int z = MathMan.unpair16y(pair.pair[0]) + bz;
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(x, y, z);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag);
|
||||
tileEntity.readFromNBT(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
byte[][] biomes = fs.biomes;
|
||||
int[][] biomes = fs.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
byte[] array = biomes[x];
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
byte biome = array[z];
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
forgeChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = biome;
|
||||
nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
sendChunk(fs);
|
||||
sendChunk(fs, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ExtendedBlockStorage section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ExtendedBlockStorage> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("field_76683_c"); // tickRefCount
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("field_76682_b"); // blockRefCount
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<ChunkPosition, TileEntity> tiles = (Map<ChunkPosition, TileEntity>) tilesGeneric;
|
||||
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||
CharFaweChunk previous = (CharFaweChunk) getChunk(fs.getX(), fs.getZ());
|
||||
char[][] idPrevious = new char[16][];
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ExtendedBlockStorage section = sections[layer];
|
||||
if (section != null) {
|
||||
byte[] currentIdArray = section.getBlockLSBArray();
|
||||
NibbleArray currentDataArray = section.getMetadataArray();
|
||||
char[] array = new char[4096];
|
||||
for (int j = 0; j < currentIdArray.length; j++) {
|
||||
int x = FaweCache.CACHE_X[layer][j];
|
||||
int y = FaweCache.CACHE_Y[layer][j];
|
||||
int z = FaweCache.CACHE_Z[layer][j];
|
||||
int id = currentIdArray[j] & 0xFF;
|
||||
byte data = (byte) currentDataArray.get(x, y & 15, z);
|
||||
previous.setBlock(x, y, z, id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
previous.ids = idPrevious;
|
||||
if (tiles != null) {
|
||||
for (Map.Entry<ChunkPosition, TileEntity> entry : tiles.entrySet()) {
|
||||
TileEntity tile = entry.getValue();
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tile.readFromNBT(tag); // readTileEntityIntoTag
|
||||
ChunkPosition pos = entry.getKey();
|
||||
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag);
|
||||
previous.setTile(pos.chunkPosX, pos.chunkPosY, pos.chunkPosZ, nativeTag);
|
||||
}
|
||||
}
|
||||
if (entities != null) {
|
||||
for (Collection<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][x][z];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = ent.getEntityData(); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
previous.setEntity(nativeTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getChunk(int x, int z) {
|
||||
return new ForgeChunk_All(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixLighting(FaweChunk chunk, boolean fixAll) {
|
||||
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
|
||||
if (mode == RelightMode.NONE) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
ForgeChunk_All fc = (ForgeChunk_All) chunk;
|
||||
Chunk forgeChunk = fc.getChunk();
|
||||
if (!forgeChunk.isChunkLoaded) {
|
||||
forgeChunk.onChunkLoad();
|
||||
ForgeChunk_All bc = (ForgeChunk_All) fc;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk();
|
||||
if (!nmsChunk.isChunkLoaded) {
|
||||
return false;
|
||||
}
|
||||
forgeChunk.generateSkylightMap();
|
||||
if (fc.getTotalRelight() == 0 && !fixAll) {
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section != null) {
|
||||
section.setSkylightArray(new NibbleArray(4096, 4));
|
||||
section.setBlocklightArray(new NibbleArray(4096, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
nmsChunk.generateSkylightMap();
|
||||
if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) {
|
||||
return true;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray();
|
||||
net.minecraft.world.World nmsWorld = forgeChunk.worldObj;
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.worldObj;
|
||||
|
||||
int X = fc.getX() << 4;
|
||||
int Z = fc.getZ() << 4;
|
||||
|
||||
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((fc.getRelight(j) == 0 && !fixAll) || fc.getCount(j) == 0 || (fc.getCount(j) >= 4096 && fc.getAir(j) == 0)) {
|
||||
if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
|
||||
continue;
|
||||
}
|
||||
byte[] array = section.getBlockLSBArray();
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int x = FaweCache.CACHE_X[j][k];
|
||||
final int y = FaweCache.CACHE_Y[j][k];
|
||||
final int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
nmsWorld.func_147451_t(X + x, y, Z + z);
|
||||
}
|
||||
short id = (short) (i);
|
||||
continue;
|
||||
}
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int i = array[k];
|
||||
final short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
case 0:
|
||||
continue;
|
||||
default:
|
||||
if (!fixAll) {
|
||||
if (mode == RelightMode.MINIMAL) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
if (PseudoRandom.random.random(3) != 0) {
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
@ -358,9 +598,9 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, Exte
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
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;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"modid": "com.boydti.fawe",
|
||||
"name": "FastAsyncWorldEdit",
|
||||
"description": "Extreme WorldEdit optimizations, no lag, low memory usage, area + tile + entity limits, block logging + rollback",
|
||||
"version": "3.4.3",
|
||||
"version": "3.5.0",
|
||||
"mcVersion": "1.7.10",
|
||||
"dependencies": [
|
||||
"WorldEdit"
|
||||
|
@ -126,7 +126,7 @@ public class FaweForge implements IFawe {
|
||||
@Override
|
||||
public void startMetrics() {
|
||||
try {
|
||||
com.boydti.fawe.forge.ForgeMetrics metrics = new com.boydti.fawe.forge.ForgeMetrics("FastAsyncWorldEdit", "3.4.3");
|
||||
com.boydti.fawe.forge.ForgeMetrics metrics = new com.boydti.fawe.forge.ForgeMetrics("FastAsyncWorldEdit", "3.5.0");
|
||||
metrics.start();
|
||||
debug("[FAWE] &6Metrics enabled.");
|
||||
} catch (Throwable e) {
|
||||
|
@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.3", acceptableRemoteVersions = "*")
|
||||
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.5.0", acceptableRemoteVersions = "*")
|
||||
public class ForgeMain {
|
||||
private static com.boydti.fawe.forge.FaweForge IMP;
|
||||
private Logger logger;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.boydti.fawe.forge;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLocation;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
@ -16,6 +17,16 @@ public class ForgePlayer extends FawePlayer<EntityPlayerMP> {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(String head, String sub) { // Not supported
|
||||
Settings.DISPLAY_PROGRESS = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTitle() { // Not supported
|
||||
Settings.DISPLAY_PROGRESS = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return parent.getName();
|
||||
|
@ -2,18 +2,36 @@ package com.boydti.fawe.forge.v0;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.forge.ForgePlayer;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraft.network.play.server.S21PacketChunkData;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@ -25,13 +43,26 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
|
||||
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char[]> {
|
||||
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], char[]> {
|
||||
|
||||
public ForgeQueue_All(final String world) {
|
||||
private Method methodFromNative;
|
||||
private Method methodToNative;
|
||||
|
||||
public ForgeQueue_All(String world) {
|
||||
super(world);
|
||||
try {
|
||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||
this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||
this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||
methodFromNative.setAccessible(true);
|
||||
methodToNative.setAccessible(true);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -89,12 +120,18 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getCachedChunk(World world, int x, int z) {
|
||||
public ExtendedBlockStorage[] getCachedChunk(World world, int x, int z) {
|
||||
Chunk chunk = world.getChunkProvider().provideChunk(x, z);
|
||||
if (chunk != null && !chunk.isLoaded()) {
|
||||
chunk.onChunkLoad();
|
||||
}
|
||||
return chunk;
|
||||
return chunk == null ? null : chunk.getBlockStorageArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getCachedSection(ExtendedBlockStorage[] chunk, int cy) {
|
||||
ExtendedBlockStorage value = chunk[cy];
|
||||
return value == null ? null : value.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -107,17 +144,251 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
return world.getChunkProvider().chunkExists(x, z);
|
||||
}
|
||||
|
||||
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 boolean setComponents(FaweChunk fc) {
|
||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||
Chunk forgeChunk = fs.getChunk();
|
||||
net.minecraft.world.World nmsWorld = forgeChunk.getWorld();
|
||||
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
|
||||
if (mode == RelightMode.NONE) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
CharFaweChunk<Chunk> bc = (CharFaweChunk) fc;
|
||||
Chunk nmsChunk = bc.getChunk();
|
||||
if (!nmsChunk.isLoaded()) {
|
||||
return false;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section != null) {
|
||||
section.setSkylightArray(new NibbleArray());
|
||||
section.setBlocklightArray(new NibbleArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
nmsChunk.generateSkylightMap();
|
||||
if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) {
|
||||
return true;
|
||||
}
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
|
||||
int X = fc.getX() << 4;
|
||||
int Z = fc.getZ() << 4;
|
||||
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
|
||||
continue;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int x = FaweCache.CACHE_X[j][k];
|
||||
final int y = FaweCache.CACHE_Y[j][k];
|
||||
final int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int i = array[k];
|
||||
final short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
case 0:
|
||||
continue;
|
||||
default:
|
||||
if (mode == RelightMode.MINIMAL) {
|
||||
continue;
|
||||
}
|
||||
if (PseudoRandom.random.random(3) != 0) {
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
final int x = FaweCache.CACHE_X[j][k];
|
||||
final int y = FaweCache.CACHE_Y[j][k];
|
||||
final int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
if (Thread.currentThread() == Fawe.get().getMainThread()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<BlockPos, TileEntity> tiles = (Map<BlockPos, TileEntity>) tilesGeneric;
|
||||
ClassInheritanceMultiMap<Entity>[] entities = (ClassInheritanceMultiMap<Entity>[]) entitiesGeneric;
|
||||
CharFaweChunk previous = (CharFaweChunk) getChunk(fs.getX(), fs.getZ());
|
||||
char[][] idPrevious = new char[16][];
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ExtendedBlockStorage section = sections[layer];
|
||||
if (section != null) {
|
||||
idPrevious[layer] = section.getData().clone();
|
||||
short solid = 0;
|
||||
for (int combined : idPrevious[layer]) {
|
||||
if (combined > 1) {
|
||||
solid++;
|
||||
}
|
||||
}
|
||||
previous.count[layer] = 4096;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
previous.ids = idPrevious;
|
||||
if (tiles != null) {
|
||||
for (Map.Entry<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][x][z];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = ent.getNBTTagCompound(); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag);
|
||||
Map<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) {
|
||||
CharFaweChunk<Chunk> fs = (CharFaweChunk) fc;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
try {
|
||||
boolean flag = !nmsWorld.provider.getHasNoSky();
|
||||
// Sections
|
||||
ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray();
|
||||
Map<BlockPos, TileEntity> tiles = forgeChunk.getTileEntityMap();
|
||||
ClassInheritanceMultiMap<Entity>[] entities = forgeChunk.getEntityLists();
|
||||
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;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 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();
|
||||
@ -128,24 +399,31 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();;
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
|
||||
entities[i] = new ClassInheritanceMultiMap<>(Entity.class);
|
||||
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++) {
|
||||
if (fs.getCount(j) == 0) {
|
||||
int count = fs.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] newArray = fs.getIdArray(j);
|
||||
@ -153,14 +431,20 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
continue;
|
||||
}
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if ((section == null) || (fs.getCount(j) >= 4096)) {
|
||||
|
||||
if ((section == null)) {
|
||||
section = new ExtendedBlockStorage(j << 4, flag);
|
||||
section.setData(newArray);
|
||||
sections[j] = section;
|
||||
continue;
|
||||
} else if (count >= 4096){
|
||||
section.setData(newArray);
|
||||
setCount(0, count - fs.getAir(j), section);
|
||||
continue;
|
||||
}
|
||||
char[] currentArray = section.getData();
|
||||
boolean fill = true;
|
||||
int solid = 0;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
@ -169,18 +453,55 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
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);
|
||||
}
|
||||
}
|
||||
// // Clear
|
||||
|
||||
// Set biomes
|
||||
int[][] biomes = fs.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<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(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag);
|
||||
tileEntity.readFromNBT(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -196,11 +517,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
forgeChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
nmsChunk.getBiomeArray()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
sendChunk(fs);
|
||||
sendChunk(fs, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -240,85 +561,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, Chunk, char
|
||||
return new ForgeChunk_All(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixLighting(FaweChunk chunk, boolean fixAll) {
|
||||
try {
|
||||
ForgeChunk_All fc = (ForgeChunk_All) chunk;
|
||||
Chunk forgeChunk = fc.getChunk();
|
||||
if (!forgeChunk.isLoaded()) {
|
||||
forgeChunk.onChunkLoad();
|
||||
}
|
||||
forgeChunk.generateSkylightMap();
|
||||
if (fc.getTotalRelight() == 0 && !fixAll) {
|
||||
return true;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = forgeChunk.getBlockStorageArray();
|
||||
net.minecraft.world.World nmsWorld = forgeChunk.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 ((fc.getRelight(j) == 0 && !fixAll) || fc.getCount(j) == 0 || (fc.getCount(j) >= 4096 && fc.getAir(j) == 0)) {
|
||||
continue;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
default:
|
||||
if (!fixAll) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
BlockPos pos = new BlockPos(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
if (Thread.currentThread() == Fawe.get().getMainThread()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSurrounded(ExtendedBlockStorage[] sections, int x, int y, int z) {
|
||||
return isSolid(getId(sections, x, y + 1, z))
|
||||
&& isSolid(getId(sections, x + 1, y - 1, z))
|
||||
|
2
pom.xml
2
pom.xml
@ -8,7 +8,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<artifactId>FastAsyncWorldEdit</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<version>3.5.0</version>
|
||||
<name>FastAsyncWorldEdit</name>
|
||||
<packaging>jar</packaging>
|
||||
<build>
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.IFawe;
|
||||
import com.boydti.fawe.SpongeCommand;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.EditSessionWrapper;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
@ -109,7 +110,7 @@ public class FaweSponge implements IFawe {
|
||||
|
||||
@Override
|
||||
public FaweQueue getNewQueue(String world, boolean fast) {
|
||||
if (fast) {
|
||||
if (fast || Settings.COMBINE_HISTORY_STAGE) {
|
||||
try {
|
||||
return new SpongeQueue_1_8(world);
|
||||
} catch (Throwable e) {
|
||||
|
@ -18,7 +18,7 @@ import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.profile.GameProfileManager;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
@Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.4.3", authors = "Empire92")
|
||||
@Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.5.0", authors = "Empire92")
|
||||
public class SpongeMain {
|
||||
public PluginContainer plugin;
|
||||
|
||||
|
@ -8,7 +8,9 @@ import java.util.UUID;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.text.Text;
|
||||
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||
import org.spongepowered.api.text.title.Title;
|
||||
import org.spongepowered.api.world.Location;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
@ -17,6 +19,19 @@ public class SpongePlayer extends FawePlayer<Player> {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(String head, String sub) { // Not supported
|
||||
Text headText = TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(head));
|
||||
Text subText = TextSerializers.LEGACY_FORMATTING_CODE.deserialize(BBC.color(sub));
|
||||
final Title title = Title.builder().title(headText).subtitle(subText).fadeIn(0).stay(60).fadeOut(20).build();
|
||||
parent.sendTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTitle() { // Not supported
|
||||
parent.resetTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.parent.getName();
|
||||
|
@ -2,17 +2,35 @@ package com.boydti.fawe.sponge.v1_8;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraft.network.play.server.S21PacketChunkData;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
@ -21,6 +39,7 @@ import net.minecraft.util.ClassInheritanceMultiMap;
|
||||
import net.minecraft.util.LongHashMap;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
import org.spongepowered.api.Sponge;
|
||||
@ -30,8 +49,20 @@ import org.spongepowered.api.world.Location;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
public class SpongeQueue_1_8 extends NMSMappedFaweQueue<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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -120,7 +151,71 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComponents(FaweChunk fc) {
|
||||
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) getChunk(fs.getX(), fs.getZ());
|
||||
char[][] idPrevious = new char[16][];
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ExtendedBlockStorage section = sections[layer];
|
||||
if (section != null) {
|
||||
idPrevious[layer] = section.getData().clone();
|
||||
short solid = 0;
|
||||
for (int combined : idPrevious[layer]) {
|
||||
if (combined > 1) {
|
||||
solid++;
|
||||
}
|
||||
}
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
previous.ids = idPrevious;
|
||||
if (tiles != null) {
|
||||
for (Map.Entry<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][x][z];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityList.getEntityString(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = ent.getNBTTagCompound(); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(null, tag);
|
||||
Map<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();
|
||||
@ -130,6 +225,65 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
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;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][x][z];
|
||||
if (array[j] != 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();
|
||||
@ -140,19 +294,25 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||
if (array[k] != 0) {
|
||||
tile.getValue().invalidate();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
|
||||
entities[i] = new ClassInheritanceMultiMap<>(Entity.class);
|
||||
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
|
||||
@ -204,6 +364,39 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
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(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(null, nativeTag);
|
||||
tileEntity.readFromNBT(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -223,7 +416,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
}
|
||||
}
|
||||
}
|
||||
sendChunk(fs);
|
||||
sendChunk(fs, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -244,49 +437,69 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
|
||||
|
||||
@Override
|
||||
public boolean fixLighting(FaweChunk fc, boolean fixAll) {
|
||||
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
|
||||
if (mode == RelightMode.NONE) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
SpongeChunk_1_8 bc = (SpongeChunk_1_8) fc;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk();
|
||||
if (!nmsChunk.isLoaded()) {
|
||||
if (!((Chunk) nmsChunk).loadChunk(false)) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section != null) {
|
||||
section.setSkylightArray(new NibbleArray());
|
||||
section.setBlocklightArray(new NibbleArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
nmsChunk.generateSkylightMap();
|
||||
if (bc.getTotalRelight() == 0 && !fixAll) {
|
||||
if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) {
|
||||
return true;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
|
||||
int X = bc.getX() << 4;
|
||||
int Z = bc.getZ() << 4;
|
||||
|
||||
int X = fc.getX() << 4;
|
||||
int Z = fc.getZ() << 4;
|
||||
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) {
|
||||
if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
|
||||
continue;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int x = FaweCache.CACHE_X[j][k];
|
||||
final int y = FaweCache.CACHE_Y[j][k];
|
||||
final int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
continue;
|
||||
}
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int i = array[k];
|
||||
final short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
case 0:
|
||||
continue;
|
||||
default:
|
||||
if (!fixAll) {
|
||||
if (mode == RelightMode.MINIMAL) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
if (PseudoRandom.random.random(3) != 0) {
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
@ -304,13 +517,13 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
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;
|
||||
}
|
||||
BlockPos pos = new BlockPos(X + x, y, Z + z);
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
@ -368,4 +581,6 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
public int getCombinedId4Data(char[] chars, int x, int y, int z) {
|
||||
return chars[FaweCache.CACHE_J[y][x & 15][z & 15]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,12 +2,18 @@ package com.boydti.fawe.sponge.v1_8;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import java.lang.reflect.Field;
|
||||
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.player.EntityPlayerMP;
|
||||
@ -17,6 +23,7 @@ import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.LongHashMap;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
import org.spongepowered.api.Sponge;
|
||||
@ -125,7 +132,11 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
private BlockState AIR = BlockTypes.AIR.getDefaultState();
|
||||
|
||||
@Override
|
||||
public boolean setComponents(FaweChunk fc) {
|
||||
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
|
||||
if (changeTask != null) {
|
||||
Settings.COMBINE_HISTORY_STAGE = false;
|
||||
throw new UnsupportedOperationException("Combine stages not supported");
|
||||
}
|
||||
SpongeChunk_1_8 fs = (SpongeChunk_1_8) fc;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = fs.getChunk();
|
||||
Chunk spongeChunk = (Chunk) nmsChunk;
|
||||
@ -162,7 +173,7 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
}
|
||||
}
|
||||
});
|
||||
sendChunk(fs);
|
||||
sendChunk(fs, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -181,51 +192,76 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
return new SpongeChunk_1_8(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ExtendedBlockStorage[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Settings.COMBINE_HISTORY_STAGE = false;
|
||||
throw new UnsupportedOperationException("Combine stages not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixLighting(FaweChunk fc, boolean fixAll) {
|
||||
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
|
||||
if (mode == RelightMode.NONE) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
SpongeChunk_1_8 bc = (SpongeChunk_1_8) fc;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = bc.getChunk();
|
||||
if (!nmsChunk.isLoaded()) {
|
||||
if (!((Chunk) nmsChunk).loadChunk(false)) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section != null) {
|
||||
section.setSkylightArray(new NibbleArray());
|
||||
section.setBlocklightArray(new NibbleArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
nmsChunk.generateSkylightMap();
|
||||
if (bc.getTotalRelight() == 0 && !fixAll) {
|
||||
if (bc.getTotalRelight() == 0 && mode == RelightMode.MINIMAL) {
|
||||
return true;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
|
||||
int X = bc.getX() << 4;
|
||||
int Z = bc.getZ() << 4;
|
||||
|
||||
int X = fc.getX() << 4;
|
||||
int Z = fc.getZ() << 4;
|
||||
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) {
|
||||
if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
|
||||
continue;
|
||||
}
|
||||
char[] array = section.getData();
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int x = FaweCache.CACHE_X[j][k];
|
||||
final int y = FaweCache.CACHE_Y[j][k];
|
||||
final int z = FaweCache.CACHE_Z[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
continue;
|
||||
}
|
||||
for (int k = array.length - 1; k >= 0; k--) {
|
||||
final int i = array[k];
|
||||
final short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
case 0:
|
||||
continue;
|
||||
default:
|
||||
if (!fixAll) {
|
||||
if (mode == RelightMode.MINIMAL) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
if (PseudoRandom.random.random(3) != 0) {
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
@ -243,13 +279,13 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
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;
|
||||
}
|
||||
BlockPos pos = new BlockPos(X + x, y, Z + z);
|
||||
pos.set(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user