Set command optimizations

This commit is contained in:
Jesse Boyd 2016-04-27 05:51:22 +10:00
parent 9a3daaa383
commit aec27d0e09
25 changed files with 475 additions and 78 deletions

View File

@ -10,7 +10,7 @@ buildscript {
}
group = 'com.boydti.fawe'
version = '3.4.0'
version = '3.4.1'
description = """FastAsyncWorldEdit"""
subprojects {

View File

@ -1,6 +1,6 @@
name: FastAsyncWorldEdit
main: com.boydti.fawe.bukkit.FaweBukkit
version: 3.4.0
version: 3.4.1
description: Fast Async WorldEdit plugin
authors: [Empire92]
loadbefore: [WorldEdit]

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v1_8;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.util.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.Arrays;
import org.bukkit.Bukkit;
@ -12,9 +13,9 @@ public class BukkitChunk_1_8 extends FaweChunk<Chunk> {
private char[][] ids;
private final short[] count;
private final short[] air;
private final short[] relight;
private short[] count;
private short[] air;
private short[] relight;
private int[][] biomes;
public Chunk chunk;
@ -224,4 +225,25 @@ public class BukkitChunk_1_8 extends FaweChunk<Chunk> {
}
index[z] = biome.getId();
}
@Override
public FaweChunk<Chunk> copy(boolean shallow) {
BukkitChunk_1_8 copy = new BukkitChunk_1_8(getParent(), getX(), getZ());
if (shallow) {
copy.ids = ids;
copy.air = air;
copy.biomes = biomes;
copy.chunk = chunk;
copy.count = count;
copy.relight = relight;
} else {
copy.ids = (char[][]) MainUtil.copyNd(ids);
copy.air = air.clone();
copy.biomes = biomes.clone();
copy.chunk = chunk;
copy.count = count.clone();
copy.relight = relight.clone();
}
return copy;
}
}

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v1_9;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.util.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.Arrays;
import org.bukkit.Bukkit;
@ -12,9 +13,9 @@ public class BukkitChunk_1_9 extends FaweChunk<Chunk> {
private int[][] ids;
private final short[] count;
private final short[] air;
private final short[] relight;
private short[] count;
private short[] air;
private short[] relight;
public int[][] biomes;
public Chunk chunk;
@ -224,4 +225,25 @@ public class BukkitChunk_1_9 extends FaweChunk<Chunk> {
}
index[z] = biome.getId();
}
@Override
public FaweChunk<Chunk> copy(boolean shallow) {
BukkitChunk_1_9 copy = new BukkitChunk_1_9(getParent(), getX(), getZ());
if (shallow) {
copy.ids = ids;
copy.air = air;
copy.biomes = biomes;
copy.chunk = chunk;
copy.count = count;
copy.relight = relight;
} else {
copy.ids = (int[][]) MainUtil.copyNd(ids);
copy.air = air.clone();
copy.biomes = biomes.clone();
copy.chunk = chunk;
copy.count = count.clone();
copy.relight = relight.clone();
}
return copy;
}
}

View File

@ -1,6 +1,6 @@
name: FastAsyncWorldEdit
main: com.boydti.fawe.bukkit.FaweBukkit
version: 3.4.0
version: 3.4.1
description: Fast Async WorldEdit plugin
authors: [Empire92]
loadbefore: [WorldEdit]

View File

@ -3,6 +3,7 @@ dependencies {
compile 'org.yaml:snakeyaml:1.16'
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.PrimeSoft:blockshub:1.2'
compile 'net.fabiozumbi12:redprotect:1.9.6'
}
task deleteTarget {

View File

@ -26,6 +26,7 @@ import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.composition.SelectionCommand;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
@ -222,12 +223,23 @@ public class Fawe {
}
private void setupInjector() {
/*
* Modify the sessions
* - EditSession supports custom queue and a lot of optimizations
* - LocalSession supports VirtualPlayers and undo on disk
*/
EditSession.inject();
Operations.inject();
LocalSession.inject();
// Commands
/*
*
*/
BrushCommands.inject();
ClipboardCommands.inject();
SchematicCommands.inject();
ScriptingCommands.inject();
SelectionCommand.inject();
// Visitors
BreadthFirstSearch.inject();
DownwardVisitor.inject();
EntityVisitor.inject();
@ -236,14 +248,20 @@ public class Fawe {
NonRisingVisitor.inject();
RecursiveVisitor.inject();
RegionVisitor.inject();
// Entity create/remove
EntityCreate.inject();
EntityRemove.inject();
LocalSession.inject();
// Clipboards
BlockArrayClipboard.inject();
CuboidRegion.inject();
CuboidClipboard.inject();
// Regions
CuboidRegion.inject();
// Extents
BlockTransformExtent.inject();
// Vector
Vector.inject();
// Operations
Operations.inject();
try {
CommandManager.inject();
PlatformManager.inject();

View File

@ -143,6 +143,10 @@ public class FaweAPI {
} catch (WorldEditException ignore) {}
}
public static void addMaskManager(FaweMaskManager maskMan) {
WEManager.IMP.managers.add(maskMan);
}
/**
* Get the DiskStorageHistory object representing a File
* @param file

View File

@ -56,11 +56,31 @@ public abstract class FaweChunk<T> {
parent.fixLighting(this, Settings.FIX_ALL_LIGHTING);
}
public void fill(final int id, final byte data) {
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 256; y++) {
for (int z = 0; z < 16; z++) {
this.setBlock(x, y, z, id, data);
/**
* Fill this chunk with a block
* @param id
* @param data
*/
public void fill(int id, byte data) {
fillCuboid(0, 15, 0, 255, 0, 15, id, data);
}
/**
* Fill a cuboid in this chunk with a block
* @param x1
* @param x2
* @param y1
* @param y2
* @param z1
* @param z2
* @param id
* @param data
*/
public void fillCuboid(int x1, int x2, int y1, int y2, int z1, int z2, int id, byte data) {
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
for (int z = z1; z <= z2; z++) {
setBlock(x, y, z, id, data);
}
}
}
@ -92,4 +112,6 @@ public abstract class FaweChunk<T> {
}
return longHash() != ((FaweChunk) obj).longHash();
}
public abstract FaweChunk<T> copy(boolean shallow);
}

View File

@ -81,4 +81,8 @@ public class RegionWrapper {
public Vector getTopVector() {
return new Vector(this.maxX, 255, this.maxZ);
}
public boolean contains(RegionWrapper current) {
return current.minX >= minX && current.maxX <= maxX && current.minZ >= minZ && current.maxZ <= maxZ;
}
}

View File

@ -61,7 +61,7 @@ public class DiskOptimizedClipboard extends FaweClipboard {
try {
this.raf = new BufferedRandomAccessFile(file, "rw", Settings.BUFFER_SIZE);
raf.setLength(file.length());
long size = (raf.length() - HEADER_SIZE) / 2;
long size = (raf.length() - HEADER_SIZE) >> 1;
raf.seek(0);
last = -1;
raf.read(buffer);
@ -101,6 +101,26 @@ public class DiskOptimizedClipboard extends FaweClipboard {
return null;
}
public DiskOptimizedClipboard(int width, int height, int length, File file) {
nbtMap = new HashMap<>();
entities = new HashSet<>();
this.file = file;
this.buffer = new byte[2];
this.lastAccessed = System.currentTimeMillis();
this.width = width;
this.height = height;
this.length = length;
this.area = width * length;
try {
if (!file.exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void setOrigin(Vector offset) {
try {
@ -122,26 +142,6 @@ public class DiskOptimizedClipboard extends FaweClipboard {
}
}
public DiskOptimizedClipboard(int width, int height, int length, File file) {
nbtMap = new HashMap<>();
entities = new HashSet<>();
this.file = file;
this.buffer = new byte[2];
this.lastAccessed = System.currentTimeMillis();
this.width = width;
this.height = height;
this.length = length;
this.area = width * length;
try {
if (!file.exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
public void flush() {
try {
raf.close();

View File

@ -0,0 +1,16 @@
package com.boydti.fawe.regions.general;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.FaweMask;
import com.boydti.fawe.regions.FaweMaskManager;
public class RedProtectFeature extends FaweMaskManager {
public RedProtectFeature(String plugin) {
super(plugin);
}
@Override
public FaweMask getMask(FawePlayer player) {
return null;
}
}

View File

@ -3,12 +3,14 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.Tag;
import java.io.File;
import java.lang.reflect.Array;
import java.util.Map;
import java.util.Map.Entry;
@ -68,6 +70,65 @@ public class MainUtil {
}
}
/**
* The int[] will be in the form: [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] and will represent the bottom and top parts of the chunk
*/
public static void chunkTaskSync(RegionWrapper region, final RunnableVal<int[]> task) {
final int p1x = region.minX;
final int p1z = region.minZ;
final int p2x = region.maxX;
final int p2z = region.maxZ;
final int bcx = p1x >> 4;
final int bcz = p1z >> 4;
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
task.value = new int[7];
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
task.value[0] = x;
task.value[1] = z;
task.value[2] = task.value[0] << 4;
task.value[3] = task.value[1] << 4;
task.value[4] = task.value[2] + 15;
task.value[5] = task.value[3] + 15;
task.value[6] = 0;
if (task.value[0] == bcx) {
task.value[2] = p1x;
task.value[6] = 1;
}
if (task.value[0] == tcx) {
task.value[4] = p2x;
task.value[6] = 1;
}
if (task.value[1] == bcz) {
task.value[3] = p1z;
task.value[6] = 1;
}
if (task.value[1] == tcz) {
task.value[5] = p2z;
task.value[6] = 1;
}
task.run();
}
}
}
public static Object copyNd(Object arr) {
if (arr.getClass().isArray()) {
int innerArrayLength = Array.getLength(arr);
Class component = arr.getClass().getComponentType();
Object newInnerArray = Array.newInstance(component, innerArrayLength);
//copy each elem of the array
for (int i = 0; i < innerArrayLength; i++) {
Object elem = copyNd(Array.get(arr, i));
Array.set(newInnerArray, i, elem);
}
return newInnerArray;
} else {
return arr;//cant deep copy an opac object??
}
}
public static String secToTime(long time) {
StringBuilder toreturn = new StringBuilder();
if (time>=33868800) {
@ -202,6 +263,11 @@ public class MainUtil {
public static boolean isValidSign(CompoundTag tag) {
Map<String, Tag> values = tag.getValue();
return values.size() > 4 && values.containsKey("Text1");
if (values.size() > 4 && values.containsKey("Text1")) {
Tag text1 = values.get("Text1");
Object value = text1.getValue();
return value != null && value instanceof String && ((String) value).length() > 0;
}
return false;
}
}

View File

@ -0,0 +1,190 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.composition;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.WEManager;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
public class SelectionCommand extends SimpleCommand<Operation> {
private final CommandExecutor<Contextual<? extends Operation>> delegate;
private final String permission;
public SelectionCommand(CommandExecutor<Contextual<? extends Operation>> delegate, String permission) {
checkNotNull(delegate, "delegate");
checkNotNull(permission, "permission");
this.delegate = delegate;
this.permission = permission;
addParameter(delegate);
}
@Override
public Operation call(CommandArgs args, CommandLocals locals) throws CommandException {
if (!testPermission(locals)) {
throw new CommandPermissionsException();
}
Contextual<? extends Operation> operationFactory = delegate.call(args, locals);
Actor actor = locals.get(Actor.class);
if (actor instanceof Player) {
try {
Player player = (Player) actor;
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
Region selection = session.getSelection(player.getWorld());
EditSession editSession = session.createEditSession(player);
editSession.enableQueue();
locals.put(EditSession.class, editSession);
session.tellVersion(player);
EditContext editContext = new EditContext();
editContext.setDestination(locals.get(EditSession.class));
editContext.setRegion(selection);
Operation operation = operationFactory.createFromContext(editContext);
// Shortcut
if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) {
CuboidRegion cuboid = (CuboidRegion) selection;
RegionFunction function = ((RegionVisitor) operation).function;
RegionWrapper current = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint());
FawePlayer fp = FawePlayer.wrap(player);
HashSet<RegionWrapper> mask = WEManager.IMP.getMask(fp);
if (function instanceof BlockReplace && mask.size() == 1 && mask.iterator().next().contains(current)) {
try {
BlockReplace replace = ((BlockReplace) function);
Field field = replace.getClass().getDeclaredField("pattern");
field.setAccessible(true);
Pattern pattern = (Pattern) field.get(replace);
if (pattern instanceof BlockPattern) {
BaseBlock block = ((BlockPattern) pattern).getBlock();
final FaweQueue queue = editSession.getQueue();
final int minY = cuboid.getMinimumY();
final int maxY = cuboid.getMaximumY();
final int id = block.getId();
final byte data = (byte) block.getData();
final FaweChunk<?> fc = queue.getChunk(0, 0);
fc.fillCuboid(0, 15, minY, maxY, 0, 15, id, data);
int bcx = (current.minX) >> 4;
int bcz = (current.minZ) >> 4;
int tcx = (current.maxX) >> 4;
int tcz = (current.maxZ) >> 4;
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
MainUtil.chunkTaskSync(current, new RunnableVal<int[]>() {
@Override
public void run(int[] value) {
FaweChunk newChunk;
if (value[6] == 0) {
newChunk = fc.copy(true);
newChunk.setLoc(queue, value[0], value[1]);
} else {
newChunk = queue.getChunk(value[0], value[1]);
newChunk.fillCuboid(value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data);
}
newChunk.addToQueue();
}
});
queue.enqueue();
editSession.setChangeSet(new NullChangeSet());
actor.print("[FAWE] Finished queueing " + cuboid.getArea() + " blocks.");
return null;
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Operations.completeBlindly(operation);
List<String> messages = Lists.newArrayList();
operation.addStatusMessages(messages);
if (messages.isEmpty()) {
actor.print("Operation completed.");
} else {
actor.print("Operation completed (" + Joiner.on(", ").join(messages) + ").");
}
return operation;
} catch (IncompleteRegionException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
return null;
}
} else {
throw new CommandException("This command can only be used by players.");
}
}
@Override
public String getDescription() {
return delegate.getDescription();
}
@Override
public boolean testPermission0(CommandLocals locals) {
return locals.get(Actor.class).hasPermission(permission);
}
public static Class<?> inject() {
return SelectionCommand.class;
}
}

View File

@ -33,9 +33,9 @@ import java.util.List;
*/
public class RegionVisitor implements Operation {
private final Region region;
private final RegionFunction function;
private int affected = 0;
public final Region region;
public final RegionFunction function;
public int affected = 0;
public RegionVisitor(Region region, RegionFunction function) {
this.region = region;

View File

@ -130,7 +130,7 @@ public class FaweForge implements IFawe {
@Override
public void startMetrics() {
try {
ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.0");
ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.1");
metrics.start();
debug("[FAWE] &6Metrics enabled.");
} catch (Throwable e) {

View File

@ -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.0", acceptableRemoteVersions = "*")
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.1", acceptableRemoteVersions = "*")
public class ForgeMain {
private static FaweForge IMP;
private Logger logger;

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.forge.v0;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
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;
@ -229,25 +230,25 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
}
@Override
public FaweChunk clone() {
ForgeChunk_All toReturn = new ForgeChunk_All(getParent(), getX(), getZ());
toReturn.air = this.air.clone();
toReturn.count = this.count.clone();
toReturn.relight = this.relight.clone();
toReturn.ids = new byte[this.ids.length][];
for (int i = 0; i < this.ids.length; i++) {
byte[] matrix = this.ids[i];
if (matrix != null) {
toReturn.ids[i] = new byte[matrix.length];
System.arraycopy(matrix, 0, toReturn.ids[i], 0, matrix.length);
}
public FaweChunk<Chunk> copy(boolean shallow) {
ForgeChunk_All copy = new ForgeChunk_All(getParent(), getX(), getZ());
if (shallow) {
copy.ids = ids;
copy.datas = datas;
copy.air = air;
copy.biomes = biomes;
copy.chunk = chunk;
copy.count = count;
copy.relight = relight;
} else {
copy.ids = (byte[][]) MainUtil.copyNd(ids);
copy.datas = datas.clone();
copy.air = air.clone();
copy.biomes = biomes.clone();
copy.chunk = chunk;
copy.count = count.clone();
copy.relight = relight.clone();
}
toReturn.datas = new NibbleArray[16];
for (int i = 0; i < this.datas.length; i++) {
if (datas[i] != null) {
toReturn.datas[i] = datas[i];
}
}
return toReturn;
return copy;
}
}

View File

@ -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.0",
"version": "3.4.1",
"mcVersion": "1.7.10",
"dependencies": [
"WorldEdit"

View File

@ -131,7 +131,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.0");
com.boydti.fawe.forge.ForgeMetrics metrics = new com.boydti.fawe.forge.ForgeMetrics("FastAsyncWorldEdit", "3.4.1");
metrics.start();
debug("[FAWE] &6Metrics enabled.");
} catch (Throwable e) {

View File

@ -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.0", acceptableRemoteVersions = "*")
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.1", acceptableRemoteVersions = "*")
public class ForgeMain {
private static com.boydti.fawe.forge.FaweForge IMP;
private Logger logger;

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.forge.v0;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
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;
@ -231,4 +232,25 @@ public class ForgeChunk_All extends FaweChunk<Chunk> {
}
return toReturn;
}
@Override
public FaweChunk<Chunk> copy(boolean shallow) {
ForgeChunk_All copy = new ForgeChunk_All(getParent(), getX(), getZ());
if (shallow) {
copy.ids = ids;
copy.air = air;
copy.biomes = biomes;
copy.chunk = chunk;
copy.count = count;
copy.relight = relight;
} else {
copy.ids = (char[][]) MainUtil.copyNd(ids);
copy.air = air.clone();
copy.biomes = biomes.clone();
copy.chunk = chunk;
copy.count = count.clone();
copy.relight = relight.clone();
}
return copy;
}
}

View File

@ -8,7 +8,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<artifactId>FastAsyncWorldEdit</artifactId>
<version>3.4.0</version>
<version>3.4.1</version>
<name>FastAsyncWorldEdit</name>
<packaging>jar</packaging>
<build>

View File

@ -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.0", 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.4.1", authors = "Empire92")
public class SpongeMain {
public PluginContainer plugin;

View File

@ -217,17 +217,26 @@ public class SpongeChunk_1_8 extends FaweChunk<Chunk> {
}
@Override
public FaweChunk clone() {
public FaweChunk<Chunk> copy(boolean shallow) {
SpongeChunk_1_8 toReturn = new SpongeChunk_1_8(getParent(), getX(), getZ());
toReturn.air = this.air.clone();
toReturn.count = this.count.clone();
toReturn.relight = this.relight.clone();
toReturn.ids = new char[this.ids.length][];
for (int i = 0; i < this.ids.length; i++) {
char[] matrix = this.ids[i];
if (matrix != null) {
toReturn.ids[i] = new char[matrix.length];
System.arraycopy(matrix, 0, toReturn.ids[i], 0, matrix.length);
if (shallow) {
toReturn.ids = ids;
toReturn.air = air;
toReturn.biomes = biomes;
toReturn.chunk = chunk;
toReturn.count = count;
toReturn.relight = relight;
} else {
toReturn.air = this.air.clone();
toReturn.count = this.count.clone();
toReturn.relight = this.relight.clone();
toReturn.ids = new char[this.ids.length][];
for (int i = 0; i < this.ids.length; i++) {
char[] matrix = this.ids[i];
if (matrix != null) {
toReturn.ids[i] = new char[matrix.length];
System.arraycopy(matrix, 0, toReturn.ids[i], 0, matrix.length);
}
}
}
return toReturn;