mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2025-01-17 13:51:30 +01:00
Various
fix pom combine stages work on efficient handling tiles / entities in changeset other minor restructuring (Currently only stable for bukkit 1.8 with Settings.COMBINE_HISTORY_STAGE=true)
This commit is contained in:
parent
71da20c6c4
commit
1d5765e8cc
@ -12,6 +12,7 @@ dependencies {
|
|||||||
compile 'com.palmergames.bukkit:towny:0.84.0.9'
|
compile 'com.palmergames.bukkit:towny:0.84.0.9'
|
||||||
compile 'com.worldcretornica:plotme_core:0.16.3'
|
compile 'com.worldcretornica:plotme_core:0.16.3'
|
||||||
compile 'junit:junit:4.11'
|
compile 'junit:junit:4.11'
|
||||||
|
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.1-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -5,7 +5,7 @@ import com.boydti.fawe.util.FaweQueue;
|
|||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
public abstract class BukkitMain extends JavaPlugin {
|
public abstract class ABukkitMain extends JavaPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
@ -43,7 +43,7 @@ import org.bukkit.plugin.Plugin;
|
|||||||
|
|
||||||
public class FaweBukkit implements IFawe, Listener {
|
public class FaweBukkit implements IFawe, Listener {
|
||||||
|
|
||||||
private final BukkitMain plugin;
|
private final ABukkitMain plugin;
|
||||||
private VaultUtil vault;
|
private VaultUtil vault;
|
||||||
private WorldEditPlugin worldedit;
|
private WorldEditPlugin worldedit;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
return this.worldedit;
|
return this.worldedit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FaweBukkit(BukkitMain plugin) {
|
public FaweBukkit(ABukkitMain plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
try {
|
try {
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||||
@ -203,7 +203,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
return new BukkitQueue_All(world);
|
return new BukkitQueue_All(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BukkitMain getPlugin() {
|
public ABukkitMain getPlugin() {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@ package com.boydti.fawe.bukkit.logging;
|
|||||||
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.history.change.Change;
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import org.PrimeSoft.blocksHub.IBlocksHubApi;
|
import org.PrimeSoft.blocksHub.IBlocksHubApi;
|
||||||
@ -11,7 +10,7 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class LoggingChangeSet implements FaweChangeSet {
|
public class LoggingChangeSet extends FaweChangeSet {
|
||||||
|
|
||||||
private final FaweChangeSet parent;
|
private final FaweChangeSet parent;
|
||||||
private final IBlocksHubApi api;
|
private final IBlocksHubApi api;
|
||||||
@ -32,29 +31,6 @@ public class LoggingChangeSet implements FaweChangeSet {
|
|||||||
return parent.flush();
|
return parent.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCompressedSize() {
|
|
||||||
return parent.getCompressedSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Vector location, BaseBlock from, BaseBlock to) {
|
|
||||||
loc.setX(location.getX());
|
|
||||||
loc.setY(location.getY());
|
|
||||||
loc.setZ(location.getZ());
|
|
||||||
api.logBlock(name, world, loc, from.getId(), (byte) from.getData(), to.getId(), (byte) to.getData());
|
|
||||||
parent.add(location, from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {
|
|
||||||
loc.setX(x);
|
|
||||||
loc.setY(y);
|
|
||||||
loc.setZ(z);
|
|
||||||
api.logBlock(name, world, loc, combinedId4DataFrom >> 4, (byte) (combinedId4DataFrom & 0xF), to.getId(), (byte) to.getData());
|
|
||||||
parent.add(x, y, z, combinedId4DataFrom, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
|
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
|
||||||
loc.setX(x);
|
loc.setX(x);
|
||||||
@ -65,18 +41,28 @@ public class LoggingChangeSet implements FaweChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(Change change) {
|
public void addTileCreate(CompoundTag tag) {
|
||||||
parent.add(change);
|
parent.addTileCreate(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Change> backwardIterator() {
|
public void addTileRemove(CompoundTag tag) {
|
||||||
return parent.backwardIterator();
|
parent.addTileRemove(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Change> forwardIterator() {
|
public void addEntityRemove(CompoundTag tag) {
|
||||||
return parent.forwardIterator();
|
parent.addEntityRemove(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityCreate(CompoundTag tag) {
|
||||||
|
parent.addEntityCreate(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Change> getIterator(boolean undo) {
|
||||||
|
return parent.getIterator(undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,9 +4,12 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.boydti.fawe.example.CharFaweChunk;
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.sk89q.worldedit.LocalWorld;
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitUtil;
|
import com.sk89q.worldedit.bukkit.BukkitUtil;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -18,8 +21,32 @@ import org.bukkit.block.Block;
|
|||||||
|
|
||||||
public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMappedFaweQueue<World, CHUNK, CHUNKSECTIONS, SECTION> {
|
public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMappedFaweQueue<World, CHUNK, CHUNKSECTIONS, SECTION> {
|
||||||
|
|
||||||
|
public final BukkitImplAdapter adapter;
|
||||||
|
public Method methodToNative;
|
||||||
|
public Method methodFromNative;
|
||||||
|
|
||||||
public BukkitQueue_0(final String world) {
|
public BukkitQueue_0(final String world) {
|
||||||
super(world);
|
super(world);
|
||||||
|
try {
|
||||||
|
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||||
|
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
||||||
|
fieldAdapter.setAccessible(true);
|
||||||
|
this.adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||||
|
for (Method method : adapter.getClass().getDeclaredMethods()) {
|
||||||
|
switch (method.getName()) {
|
||||||
|
case "toNative":
|
||||||
|
methodToNative = method;
|
||||||
|
methodToNative.setAccessible(true);
|
||||||
|
break;
|
||||||
|
case "fromNative":
|
||||||
|
methodFromNative = method;
|
||||||
|
methodFromNative.setAccessible(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -85,8 +112,11 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setComponents(FaweChunk fc) {
|
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
|
||||||
try {
|
try {
|
||||||
|
// TODO track stage
|
||||||
|
// TODO set task
|
||||||
|
|
||||||
final CharFaweChunk<Chunk> fs = ((CharFaweChunk<Chunk>) fc);
|
final CharFaweChunk<Chunk> fs = ((CharFaweChunk<Chunk>) fc);
|
||||||
final Chunk chunk = fs.getChunk();
|
final Chunk chunk = fs.getChunk();
|
||||||
chunk.load(true);
|
chunk.load(true);
|
||||||
|
@ -24,15 +24,15 @@ public class ChunkListener implements Listener {
|
|||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int physicsLimit = Settings.PHYSICS_PER_TICK;
|
private int physicsLimit = Integer.MAX_VALUE;
|
||||||
private int itemLimit = Settings.ITEMS_PER_TICK;
|
private int itemLimit = Integer.MAX_VALUE;
|
||||||
public static boolean physicsFreeze = false;
|
public static boolean physicsFreeze = false;
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPhysics(BlockPhysicsEvent event) {
|
public void onPhysics(BlockPhysicsEvent event) {
|
||||||
if (physicsFreeze) {
|
if (physicsFreeze) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
} else if (--physicsLimit < 0) {
|
} else if (physicsLimit-- < 0) {
|
||||||
physicsFreeze = true;
|
physicsFreeze = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ public class ChunkListener implements Listener {
|
|||||||
public void onItemSpawn(ItemSpawnEvent event) {
|
public void onItemSpawn(ItemSpawnEvent event) {
|
||||||
if (physicsFreeze) {
|
if (physicsFreeze) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
} else if (--itemLimit < 0) {
|
} else if (itemLimit-- < 0) {
|
||||||
physicsFreeze = true;
|
physicsFreeze = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
name: FastAsyncWorldEdit
|
|
||||||
main: com.boydti.fawe.bukkit.FaweBukkit
|
|
||||||
version: 3.4.3
|
|
||||||
description: Fast Async WorldEdit plugin
|
|
||||||
authors: [Empire92]
|
|
||||||
loadbefore: [WorldEdit]
|
|
||||||
load: STARTUP
|
|
||||||
database: false
|
|
||||||
#softdepend: [WorldGuard, PlotSquared, MCore, Factions, GriefPrevention, Residence, Towny, PlotMe, PreciousStones]
|
|
||||||
commands:
|
|
||||||
wea:
|
|
||||||
description: (FAWE) Bypass WorldEdit processing and area restrictions
|
|
||||||
aliases: [weanywhere,worldeditanywhere,/wea,/weanywhere,/worldeditanywhere]
|
|
||||||
usage: "Vault is required for the toggle. Optionally, you can set the permission fawe.bypass"
|
|
||||||
fixlighting:
|
|
||||||
description: (FAWE) Fix the lighting in your current chunk
|
|
||||||
aliases: [/fixlighting]
|
|
||||||
stream:
|
|
||||||
description: (FAWE) Stream a schematic into the world
|
|
||||||
aliases: [/stream]
|
|
||||||
fawe:
|
|
||||||
description: (FAWE) Reload the plugin
|
|
||||||
aliases: [/fawe,/fawereload]
|
|
||||||
wrg:
|
|
||||||
description: (FAWE) Select your current WorldEdit Region.
|
|
||||||
aliases: [/wrg,wer,/wer,worldeditregion,/worldeditregion,/region]
|
|
||||||
frb:
|
|
||||||
description: (FAWE) Rollback an edit
|
|
||||||
aliases: [fawerollback,fawerb,/uu,/rb,/frb,/fawerollback,/fawerb]
|
|
||||||
fcancel:
|
|
||||||
description: (FAWE) Cancel your edit
|
|
||||||
aliases: [fawecancel,/fcancel,/cancel,/fawecancel]
|
|
||||||
permissions:
|
|
||||||
fawe.bypass:
|
|
||||||
default: false
|
|
||||||
fawe.admin:
|
|
||||||
default: false
|
|
||||||
fawe.stream:
|
|
||||||
default: false
|
|
||||||
fawe.fixlighting:
|
|
||||||
default: false
|
|
||||||
fawe.reload:
|
|
||||||
default: false
|
|
@ -1,11 +1,12 @@
|
|||||||
package com.boydti.fawe.bukkit.v1_8;
|
package com.boydti.fawe.bukkit.v1_8;
|
||||||
|
|
||||||
import com.boydti.fawe.bukkit.BukkitMain;
|
import com.boydti.fawe.bukkit.ABukkitMain;
|
||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
|
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
||||||
import com.boydti.fawe.object.EditSessionWrapper;
|
import com.boydti.fawe.object.EditSessionWrapper;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
|
||||||
public class BukkitMain_1_8 extends BukkitMain {
|
public class BukkitMain_18 extends ABukkitMain {
|
||||||
@Override
|
@Override
|
||||||
public BukkitQueue_0 getQueue(String world) {
|
public BukkitQueue_0 getQueue(String world) {
|
||||||
return new BukkitQueue18R3(world);
|
return new BukkitQueue18R3(world);
|
@ -5,11 +5,21 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.boydti.fawe.bukkit.BukkitPlayer;
|
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
import com.boydti.fawe.example.CharFaweChunk;
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
|
import com.boydti.fawe.object.BytePair;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.object.FaweLocation;
|
import com.boydti.fawe.object.FaweLocation;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
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 com.sk89q.worldedit.internal.Constants;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -17,6 +27,10 @@ import java.util.Set;
|
|||||||
import net.minecraft.server.v1_8_R3.BlockPosition;
|
import net.minecraft.server.v1_8_R3.BlockPosition;
|
||||||
import net.minecraft.server.v1_8_R3.ChunkCoordIntPair;
|
import net.minecraft.server.v1_8_R3.ChunkCoordIntPair;
|
||||||
import net.minecraft.server.v1_8_R3.ChunkSection;
|
import net.minecraft.server.v1_8_R3.ChunkSection;
|
||||||
|
import net.minecraft.server.v1_8_R3.Entity;
|
||||||
|
import net.minecraft.server.v1_8_R3.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_8_R3.NBTTagInt;
|
||||||
import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk;
|
import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk;
|
||||||
import net.minecraft.server.v1_8_R3.PlayerConnection;
|
import net.minecraft.server.v1_8_R3.PlayerConnection;
|
||||||
import net.minecraft.server.v1_8_R3.TileEntity;
|
import net.minecraft.server.v1_8_R3.TileEntity;
|
||||||
@ -26,6 +40,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]> {
|
public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]> {
|
||||||
|
|
||||||
@ -81,7 +96,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setComponents(FaweChunk fc) {
|
public boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
|
||||||
CharFaweChunk<Chunk> fs = (CharFaweChunk<Chunk>) fc;
|
CharFaweChunk<Chunk> fs = (CharFaweChunk<Chunk>) fc;
|
||||||
CraftChunk chunk = (CraftChunk) fs.getChunk();
|
CraftChunk chunk = (CraftChunk) fs.getChunk();
|
||||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
|
net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
|
||||||
@ -92,6 +107,55 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
|
|||||||
ChunkSection[] sections = nmsChunk.getSections();
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||||
Collection<net.minecraft.server.v1_8_R3.Entity>[] entities = nmsChunk.getEntitySlices();
|
Collection<net.minecraft.server.v1_8_R3.Entity>[] entities = nmsChunk.getEntitySlices();
|
||||||
|
|
||||||
|
// Run change task if applicable
|
||||||
|
if (changeTask != null) {
|
||||||
|
CharFaweChunk previous = (CharFaweChunk) getChunk(fc.getX(), fc.getZ());
|
||||||
|
char[][] idPrevious = new char[16][];
|
||||||
|
for (int layer = 0; layer < sections.length; layer++) {
|
||||||
|
if (fs.getCount(layer) != 0) {
|
||||||
|
ChunkSection section = sections[layer];
|
||||||
|
if (section != null) {
|
||||||
|
idPrevious[layer] = section.getIdArray().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previous.ids = idPrevious;
|
||||||
|
for (Map.Entry<BlockPosition, TileEntity> entry : tiles.entrySet()) {
|
||||||
|
TileEntity tile = entry.getValue();
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tile.b(tag); // ReadTileIntoTag
|
||||||
|
BlockPosition pos = entry.getKey();
|
||||||
|
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||||
|
previous.setTile(pos.getX(), pos.getY(), pos.getZ(), nativeTag);
|
||||||
|
}
|
||||||
|
for (Collection<Entity> entityList : entities) {
|
||||||
|
for (Entity ent : entityList) {
|
||||||
|
int x = ((int) Math.round(ent.locX) & 15);
|
||||||
|
int z = ((int) Math.round(ent.locZ) & 15);
|
||||||
|
int y = (int) Math.round(ent.locY);
|
||||||
|
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 = EntityTypes.b(ent);
|
||||||
|
if (id != null) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
ent.e(tag);
|
||||||
|
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||||
|
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||||
|
map.put("Id", new StringTag(id));
|
||||||
|
previous.setEntity(nativeTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeTask.run(previous);
|
||||||
|
}
|
||||||
|
|
||||||
// Trim tiles
|
// Trim tiles
|
||||||
Set<Map.Entry<BlockPosition, TileEntity>> entryset = tiles.entrySet();
|
Set<Map.Entry<BlockPosition, TileEntity>> entryset = tiles.entrySet();
|
||||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = entryset.iterator();
|
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = entryset.iterator();
|
||||||
@ -102,22 +166,41 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
|
|||||||
int ly = pos.getY();
|
int ly = pos.getY();
|
||||||
int lz = pos.getZ() & 15;
|
int lz = pos.getZ() & 15;
|
||||||
int j = FaweCache.CACHE_I[ly][lx][lz];
|
int j = FaweCache.CACHE_I[ly][lx][lz];
|
||||||
int k = FaweCache.CACHE_J[ly][lx][lz];
|
|
||||||
char[] array = fs.getIdArray(j);
|
char[] array = fs.getIdArray(j);
|
||||||
if (array == null) {
|
if (array == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
int k = FaweCache.CACHE_J[ly][lx][lz];
|
||||||
if (array[k] != 0) {
|
if (array[k] != 0) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Trim entities
|
// Remove entities
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
|
int count = fs.getCount(i);
|
||||||
|
if (count == 0) {
|
||||||
|
continue;
|
||||||
|
} else if (count >= 4096) {
|
||||||
entities[i].clear();
|
entities[i].clear();
|
||||||
|
} else {
|
||||||
|
char[] array = fs.getIdArray(i);
|
||||||
|
Collection<Entity> ents = new ArrayList<>(entities[i]);
|
||||||
|
for (Entity entity : ents) {
|
||||||
|
int x = ((int) Math.round(entity.locX) & 15);
|
||||||
|
int z = ((int) Math.round(entity.locZ) & 15);
|
||||||
|
int y = (int) Math.round(entity.locY);
|
||||||
|
if (array == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int j = FaweCache.CACHE_J[y][x][z];
|
||||||
|
if (array[j] != 0) {
|
||||||
|
nmsWorld.removeEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Efficiently merge sections
|
|
||||||
|
// Set blocks
|
||||||
for (int j = 0; j < sections.length; j++) {
|
for (int j = 0; j < sections.length; j++) {
|
||||||
if (fs.getCount(j) == 0) {
|
if (fs.getCount(j) == 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -142,8 +225,8 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
|
|||||||
case 1:
|
case 1:
|
||||||
if (currentArray[k] > 1) {
|
if (currentArray[k] > 1) {
|
||||||
solid++;
|
solid++;
|
||||||
|
currentArray[k] = 0;
|
||||||
}
|
}
|
||||||
currentArray[k] = 0;
|
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
solid++;
|
solid++;
|
||||||
@ -153,25 +236,75 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
|
|||||||
}
|
}
|
||||||
setCount(0, solid, section);
|
setCount(0, solid, section);
|
||||||
}
|
}
|
||||||
// // Clear
|
|
||||||
} catch (Throwable e) {
|
// Set biomes
|
||||||
e.printStackTrace();
|
int[][] biomes = fs.biomes;
|
||||||
}
|
if (biomes != null) {
|
||||||
int[][] biomes = fs.biomes;
|
for (int x = 0; x < 16; x++) {
|
||||||
if (biomes != null) {
|
int[] array = biomes[x];
|
||||||
for (int x = 0; x < 16; x++) {
|
if (array == null) {
|
||||||
int[] array = biomes[x];
|
|
||||||
if (array == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
int biome = array[z];
|
|
||||||
if (biome == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int biome = array[z];
|
||||||
|
if (biome == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set tiles
|
||||||
|
Map<BytePair, CompoundTag> tilesToSpawn = fs.getTiles();
|
||||||
|
BlockPosition.MutableBlockPosition mutablePos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||||
|
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();
|
||||||
|
mutablePos.c(MathMan.unpair16x(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos
|
||||||
|
TileEntity tileEntity = nmsWorld.getTileEntity(mutablePos);
|
||||||
|
if (tileEntity != null) {
|
||||||
|
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
|
||||||
|
tag.set("x", new NBTTagInt(mutablePos.getX()));
|
||||||
|
tag.set("y", new NBTTagInt(mutablePos.getY()));
|
||||||
|
tag.set("z", new NBTTagInt(mutablePos.getZ()));
|
||||||
|
tileEntity.a(tag); // ReadTagIntoTile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set entities
|
||||||
|
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();
|
||||||
|
Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
|
||||||
|
if (entity != null) {
|
||||||
|
if (nativeTag != null) {
|
||||||
|
NBTTagCompound tag = (NBTTagCompound)methodFromNative.invoke(adapter, nativeTag);
|
||||||
|
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||||
|
tag.remove(name);
|
||||||
|
}
|
||||||
|
entity.f(tag);
|
||||||
|
}
|
||||||
|
entity.setLocation(x, y, z, yaw, pitch);
|
||||||
|
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
sendChunk(fc);
|
sendChunk(fc);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: FastAsyncWorldEdit
|
name: FastAsyncWorldEdit
|
||||||
main: com.boydti.fawe.bukkit.v1_8.BukkitMain_1_8
|
main: com.boydti.fawe.bukkit.v1_8.BukkitMain_18
|
||||||
version: 3.4.3
|
version: 3.4.3
|
||||||
description: Fast Async WorldEdit plugin
|
description: Fast Async WorldEdit plugin
|
||||||
authors: [Empire92]
|
authors: [Empire92]
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package com.boydti.fawe.bukkit.v1_9;
|
package com.boydti.fawe.bukkit.v1_9;
|
||||||
|
|
||||||
import com.boydti.fawe.bukkit.BukkitMain;
|
import com.boydti.fawe.bukkit.ABukkitMain;
|
||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
|
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
||||||
import com.boydti.fawe.object.EditSessionWrapper;
|
import com.boydti.fawe.object.EditSessionWrapper;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
|
||||||
public class BukkitMain_1_9 extends BukkitMain {
|
public class BukkitMain_19 extends ABukkitMain {
|
||||||
@Override
|
@Override
|
||||||
public BukkitQueue_0 getQueue(String world) {
|
public BukkitQueue_0 getQueue(String world) {
|
||||||
return new BukkitQueue_1_9_R1(world);
|
return new BukkitQueue_1_9_R1(world);
|
@ -8,6 +8,7 @@ import com.boydti.fawe.object.FaweChunk;
|
|||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.IntegerPair;
|
import com.boydti.fawe.object.IntegerPair;
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
import com.boydti.fawe.object.PseudoRandom;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
@ -248,7 +249,12 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setComponents(final FaweChunk pc) {
|
public boolean setComponents(final FaweChunk pc, RunnableVal<FaweChunk> changeTask) {
|
||||||
|
// TODO change task
|
||||||
|
{
|
||||||
|
// blah, stuff
|
||||||
|
}
|
||||||
|
|
||||||
final BukkitChunk_1_9 fs = (BukkitChunk_1_9) pc;
|
final BukkitChunk_1_9 fs = (BukkitChunk_1_9) pc;
|
||||||
final Chunk chunk = (Chunk) fs.getChunk();
|
final Chunk chunk = (Chunk) fs.getChunk();
|
||||||
final World world = chunk.getWorld();
|
final World world = chunk.getWorld();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: FastAsyncWorldEdit
|
name: FastAsyncWorldEdit
|
||||||
main: com.boydti.fawe.bukkit.v1_9.BukkitMain_1_9
|
main: com.boydti.fawe.bukkit.v1_9.BukkitMain_19
|
||||||
version: 3.4.3
|
version: 3.4.3
|
||||||
description: Fast Async WorldEdit plugin
|
description: Fast Async WorldEdit plugin
|
||||||
authors: [Empire92]
|
authors: [Empire92]
|
||||||
|
@ -11,7 +11,6 @@ import com.boydti.fawe.config.BBC;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.regions.general.PlotSquaredFeature;
|
import com.boydti.fawe.regions.general.PlotSquaredFeature;
|
||||||
import com.boydti.fawe.util.Lag;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
@ -191,10 +190,6 @@ public class Fawe {
|
|||||||
*/
|
*/
|
||||||
this.setupInjector();
|
this.setupInjector();
|
||||||
this.setupMemoryListener();
|
this.setupMemoryListener();
|
||||||
|
|
||||||
// Lag
|
|
||||||
final Lag lag = new Lag();
|
|
||||||
TaskManager.IMP.repeat(lag, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupEvents() {
|
private void setupEvents() {
|
||||||
@ -336,28 +331,38 @@ public class Fawe {
|
|||||||
if (Settings.MEM_FREE < 1) {
|
if (Settings.MEM_FREE < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
|
try {
|
||||||
final NotificationEmitter ne = (NotificationEmitter) memBean;
|
final MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
|
||||||
|
final NotificationEmitter ne = (NotificationEmitter) memBean;
|
||||||
|
|
||||||
ne.addNotificationListener(new NotificationListener() {
|
ne.addNotificationListener(new NotificationListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handleNotification(final Notification notification, final Object handback) {
|
public void handleNotification(final Notification notification, final Object handback) {
|
||||||
MemUtil.memoryLimitedTask();
|
MemUtil.memoryLimitedTask();
|
||||||
}
|
|
||||||
}, null, null);
|
|
||||||
|
|
||||||
final List<MemoryPoolMXBean> memPools = ManagementFactory.getMemoryPoolMXBeans();
|
|
||||||
for (final MemoryPoolMXBean mp : memPools) {
|
|
||||||
if (mp.isUsageThresholdSupported()) {
|
|
||||||
final MemoryUsage mu = mp.getUsage();
|
|
||||||
final long max = mu.getMax();
|
|
||||||
if (max < 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
final long alert = (max * Settings.MEM_FREE) / 100;
|
}, null, null);
|
||||||
mp.setUsageThreshold(alert);
|
|
||||||
|
|
||||||
|
final List<MemoryPoolMXBean> memPools = ManagementFactory.getMemoryPoolMXBeans();
|
||||||
|
for (final MemoryPoolMXBean mp : memPools) {
|
||||||
|
if (mp.isUsageThresholdSupported()) {
|
||||||
|
final MemoryUsage mu = mp.getUsage();
|
||||||
|
final long max = mu.getMax();
|
||||||
|
if (max < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final long alert = (max * Settings.MEM_FREE) / 100;
|
||||||
|
mp.setUsageThreshold(alert);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
debug("====== MEMORY LISTENER ERROR ======");
|
||||||
|
e.printStackTrace();
|
||||||
|
debug("===================================");
|
||||||
|
debug("FAWE needs access to the JVM memory system:");
|
||||||
|
debug(" - Change your Java security settings");
|
||||||
|
debug(" - Disable this with `max-memory-percent: -1`");
|
||||||
|
debug("===================================");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,10 @@ public class Settings {
|
|||||||
public static int UNSAFE_PARALLEL_THREADS = 1;
|
public static int UNSAFE_PARALLEL_THREADS = 1;
|
||||||
public static boolean FIX_ALL_LIGHTING = true;
|
public static boolean FIX_ALL_LIGHTING = true;
|
||||||
public static boolean ASYNC_LIGHTING = true;
|
public static boolean ASYNC_LIGHTING = true;
|
||||||
public static int PHYSICS_PER_TICK = 1337;
|
public static int PHYSICS_PER_TICK = 500000;
|
||||||
public static int ITEMS_PER_TICK = 1337;
|
public static int ITEMS_PER_TICK = 50000;
|
||||||
|
|
||||||
|
public static boolean COMBINE_HISTORY_STAGE = true;
|
||||||
|
|
||||||
public static HashMap<String, FaweLimit> limits;
|
public static HashMap<String, FaweLimit> limits;
|
||||||
|
|
||||||
@ -103,6 +105,9 @@ public class Settings {
|
|||||||
options.put("extent.debug", EXTENT_DEBUG);
|
options.put("extent.debug", EXTENT_DEBUG);
|
||||||
options.put("metrics", METRICS);
|
options.put("metrics", METRICS);
|
||||||
|
|
||||||
|
if (config.getInt("tick-limiter.physics") == 1337) {
|
||||||
|
config.set("tick-limiter.physics", PHYSICS_PER_TICK);
|
||||||
|
}
|
||||||
options.put("tick-limiter.physics", PHYSICS_PER_TICK);
|
options.put("tick-limiter.physics", PHYSICS_PER_TICK);
|
||||||
options.put("tick-limiter.items", ITEMS_PER_TICK);
|
options.put("tick-limiter.items", ITEMS_PER_TICK);
|
||||||
|
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
package com.boydti.fawe.example;
|
package com.boydti.fawe.example;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.object.BytePair;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||||
|
|
||||||
@ -112,6 +119,50 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
|||||||
return this.biomes;
|
return this.biomes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashMap<BytePair, CompoundTag> tiles;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||||
|
if (tiles == null) {
|
||||||
|
tiles = new HashMap<>();
|
||||||
|
}
|
||||||
|
byte i = MathMan.pair16((byte) x, (byte) z);
|
||||||
|
byte j = (byte) y;
|
||||||
|
BytePair pair = new BytePair(i, j);
|
||||||
|
tiles.put(pair, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
|
if (tiles == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte i = MathMan.pair16((byte) x, (byte) z);
|
||||||
|
byte j = (byte) y;
|
||||||
|
BytePair pair = new BytePair(i, j);
|
||||||
|
return tiles.get(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<BytePair, CompoundTag> getTiles() {
|
||||||
|
return tiles == null ? new HashMap<BytePair, CompoundTag>() : tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return entities == null ? new HashSet<CompoundTag>() : entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet<CompoundTag> entities;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEntity(CompoundTag tag) {
|
||||||
|
if (entities == null) {
|
||||||
|
entities = new HashSet<>();
|
||||||
|
}
|
||||||
|
entities.add(tag);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(final int x, final int y, final int z, final int id, byte data) {
|
public void setBlock(final int x, final int y, final int z, final int id, byte data) {
|
||||||
final int i = FaweCache.CACHE_I[y][x][z];
|
final int i = FaweCache.CACHE_I[y][x][z];
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
package com.boydti.fawe.example;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
public abstract class IntFaweChunk<T> extends FaweChunk<T> {
|
|
||||||
|
|
||||||
private int[][] ids;
|
|
||||||
|
|
||||||
private short[] count;
|
|
||||||
private short[] air;
|
|
||||||
private short[] relight;
|
|
||||||
private int[][] biomes;
|
|
||||||
|
|
||||||
private T chunk;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
|
||||||
*
|
|
||||||
* @param parent
|
|
||||||
* @param x
|
|
||||||
* @param z
|
|
||||||
*/
|
|
||||||
public IntFaweChunk(FaweQueue parent, int x, int z) {
|
|
||||||
super(parent, x, z);
|
|
||||||
this.ids = new int[16][];
|
|
||||||
this.count = new short[16];
|
|
||||||
this.air = new short[16];
|
|
||||||
this.relight = new short[16];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T getChunk() {
|
|
||||||
if (this.chunk == null) {
|
|
||||||
this.chunk = getNewChunk();
|
|
||||||
}
|
|
||||||
return this.chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract T getNewChunk();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLoc(final FaweQueue parent, int x, int z) {
|
|
||||||
super.setLoc(parent, x, z);
|
|
||||||
this.chunk = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of block changes in a specified section
|
|
||||||
* @param i
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public int getCount(final int i) {
|
|
||||||
return this.count[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAir(final int i) {
|
|
||||||
return this.air[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCount(final int i, final short value) {
|
|
||||||
this.count[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of block changes in a specified section
|
|
||||||
* @param i
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public int getRelight(final 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 ((this.getTotalCount() == 0) && (this.biomes == null)) {
|
|
||||||
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 int[] getIdArray(final int i) {
|
|
||||||
return this.ids[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[][] getIdArrays() {
|
|
||||||
return this.ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[][] getBiomeArray() {
|
|
||||||
return this.biomes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlock(final int x, final int y, final int z, final int id, byte data) {
|
|
||||||
final int i = FaweCache.CACHE_I[y][x][z];
|
|
||||||
final int j = FaweCache.CACHE_J[y][x][z];
|
|
||||||
int[] vs = this.ids[i];
|
|
||||||
if (vs == null) {
|
|
||||||
vs = this.ids[i] = new int[4096];
|
|
||||||
this.count[i]++;
|
|
||||||
} else if (vs[j] == 0) {
|
|
||||||
this.count[i]++;
|
|
||||||
}
|
|
||||||
switch (id) {
|
|
||||||
case 0:
|
|
||||||
this.air[i]++;
|
|
||||||
vs[j] = -1;
|
|
||||||
return;
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 39:
|
|
||||||
case 40:
|
|
||||||
case 51:
|
|
||||||
case 74:
|
|
||||||
case 89:
|
|
||||||
case 122:
|
|
||||||
case 124:
|
|
||||||
case 138:
|
|
||||||
case 169:
|
|
||||||
this.relight[i]++;
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
case 14:
|
|
||||||
case 15:
|
|
||||||
case 20:
|
|
||||||
case 21:
|
|
||||||
case 22:
|
|
||||||
case 30:
|
|
||||||
case 32:
|
|
||||||
case 37:
|
|
||||||
case 41:
|
|
||||||
case 42:
|
|
||||||
case 45:
|
|
||||||
case 46:
|
|
||||||
case 47:
|
|
||||||
case 48:
|
|
||||||
case 49:
|
|
||||||
case 56:
|
|
||||||
case 57:
|
|
||||||
case 58:
|
|
||||||
case 60:
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 73:
|
|
||||||
case 78:
|
|
||||||
case 79:
|
|
||||||
case 80:
|
|
||||||
case 81:
|
|
||||||
case 82:
|
|
||||||
case 83:
|
|
||||||
case 85:
|
|
||||||
case 87:
|
|
||||||
case 88:
|
|
||||||
case 101:
|
|
||||||
case 102:
|
|
||||||
case 103:
|
|
||||||
case 110:
|
|
||||||
case 112:
|
|
||||||
case 113:
|
|
||||||
case 121:
|
|
||||||
case 129:
|
|
||||||
case 133:
|
|
||||||
case 165:
|
|
||||||
case 166:
|
|
||||||
case 170:
|
|
||||||
case 172:
|
|
||||||
case 173:
|
|
||||||
case 174:
|
|
||||||
case 181:
|
|
||||||
case 182:
|
|
||||||
case 188:
|
|
||||||
case 189:
|
|
||||||
case 190:
|
|
||||||
case 191:
|
|
||||||
case 192:
|
|
||||||
vs[j] = (id);
|
|
||||||
return;
|
|
||||||
case 130:
|
|
||||||
case 50:
|
|
||||||
case 76:
|
|
||||||
case 62:
|
|
||||||
this.relight[i]++;
|
|
||||||
case 54:
|
|
||||||
case 146:
|
|
||||||
case 61:
|
|
||||||
case 65:
|
|
||||||
case 68:
|
|
||||||
// if (data < 2) {
|
|
||||||
// data = 2;
|
|
||||||
// }
|
|
||||||
default:
|
|
||||||
vs[j] = id + (data << 12);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBiome(final int x, final int z, final BaseBiome biome) {
|
|
||||||
if (this.biomes == null) {
|
|
||||||
this.biomes = new int[16][];
|
|
||||||
}
|
|
||||||
int[] index = this.biomes[x];
|
|
||||||
if (index == null) {
|
|
||||||
index = this.biomes[x] = new int[16];
|
|
||||||
}
|
|
||||||
index[z] = biome.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IntFaweChunk<T> copy(boolean shallow) {
|
|
||||||
IntFaweChunk<T> copy = (IntFaweChunk<T>) getParent().getChunk(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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,8 +7,11 @@ import com.boydti.fawe.object.IntegerPair;
|
|||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
|
import com.boydti.fawe.util.SetQueue;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -23,6 +26,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
*/
|
*/
|
||||||
private ConcurrentHashMap<Long, FaweChunk> blocks = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<Long, FaweChunk> blocks = new ConcurrentHashMap<>();
|
||||||
private LinkedBlockingDeque<FaweChunk> chunks = new LinkedBlockingDeque<>();
|
private LinkedBlockingDeque<FaweChunk> chunks = new LinkedBlockingDeque<>();
|
||||||
|
private ArrayDeque<Runnable> tasks = new ArrayDeque<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void optimize() {
|
public void optimize() {
|
||||||
@ -46,6 +50,11 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotifyTask(Runnable runnable) {
|
||||||
|
this.tasks.add(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
public MappedFaweQueue(final String world) {
|
public MappedFaweQueue(final String world) {
|
||||||
super(world);
|
super(world);
|
||||||
}
|
}
|
||||||
@ -58,7 +67,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
|
|
||||||
public abstract void sendChunk(FaweChunk chunk);
|
public abstract void sendChunk(FaweChunk chunk);
|
||||||
|
|
||||||
public abstract boolean setComponents(FaweChunk fc);
|
public abstract boolean setComponents(FaweChunk fc, RunnableVal<FaweChunk> changeTask);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract FaweChunk getChunk(int x, int z);
|
public abstract FaweChunk getChunk(int x, int z);
|
||||||
@ -88,12 +97,12 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addTask(int x, int z, Runnable runnable) {
|
public void addNotifyTask(int x, int z, Runnable runnable) {
|
||||||
long pair = (long) (x) << 32 | (z) & 0xFFFFFFFFL;
|
long pair = (long) (x) << 32 | (z) & 0xFFFFFFFFL;
|
||||||
FaweChunk result = this.blocks.get(pair);
|
FaweChunk result = this.blocks.get(pair);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = this.getChunk(x, z);
|
result = this.getChunk(x, z);
|
||||||
result.addTask(runnable);
|
result.addNotifyTask(runnable);
|
||||||
FaweChunk previous = this.blocks.put(pair, result);
|
FaweChunk previous = this.blocks.put(pair, result);
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
chunks.add(result);
|
chunks.add(result);
|
||||||
@ -102,9 +111,11 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
this.blocks.put(pair, previous);
|
this.blocks.put(pair, previous);
|
||||||
result = previous;
|
result = previous;
|
||||||
}
|
}
|
||||||
result.addTask(runnable);
|
result.addNotifyTask(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private FaweChunk lastWrappedChunk;
|
private FaweChunk lastWrappedChunk;
|
||||||
private int lastX = Integer.MIN_VALUE;
|
private int lastX = Integer.MIN_VALUE;
|
||||||
private int lastZ = Integer.MIN_VALUE;
|
private int lastZ = Integer.MIN_VALUE;
|
||||||
@ -137,6 +148,60 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTile(int x, int y, int z, CompoundTag tag) {
|
||||||
|
if ((y > 255) || (y < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int cx = x >> 4;
|
||||||
|
int cz = z >> 4;
|
||||||
|
if (cx != lastX || cz != lastZ) {
|
||||||
|
lastX = cx;
|
||||||
|
lastZ = cz;
|
||||||
|
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||||
|
lastWrappedChunk = this.blocks.get(pair);
|
||||||
|
if (lastWrappedChunk == null) {
|
||||||
|
lastWrappedChunk = this.getChunk(x >> 4, z >> 4);
|
||||||
|
lastWrappedChunk.setTile(x & 15, y, z & 15, tag);
|
||||||
|
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||||
|
if (previous == null) {
|
||||||
|
chunks.add(lastWrappedChunk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.blocks.put(pair, previous);
|
||||||
|
lastWrappedChunk = previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastWrappedChunk.setTile(x & 15, y, z & 15, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEntity(int x, int y, int z, CompoundTag tag) {
|
||||||
|
if ((y > 255) || (y < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int cx = x >> 4;
|
||||||
|
int cz = z >> 4;
|
||||||
|
if (cx != lastX || cz != lastZ) {
|
||||||
|
lastX = cx;
|
||||||
|
lastZ = cz;
|
||||||
|
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||||
|
lastWrappedChunk = this.blocks.get(pair);
|
||||||
|
if (lastWrappedChunk == null) {
|
||||||
|
lastWrappedChunk = this.getChunk(x >> 4, z >> 4);
|
||||||
|
lastWrappedChunk.setEntity(tag);
|
||||||
|
FaweChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||||
|
if (previous == null) {
|
||||||
|
chunks.add(lastWrappedChunk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.blocks.put(pair, previous);
|
||||||
|
lastWrappedChunk = previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastWrappedChunk.setEntity(tag);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int z, BaseBiome biome) {
|
public boolean setBiome(int x, int z, BaseBiome biome) {
|
||||||
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
|
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
|
||||||
@ -177,22 +242,41 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void runTasks() {
|
||||||
|
for (Runnable run : tasks) {
|
||||||
|
run.run();
|
||||||
|
}
|
||||||
|
tasks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
|
if (chunks.size() == 0 && SetQueue.IMP.isStage(this, SetQueue.QueueStage.ACTIVE)) {
|
||||||
|
runTasks();
|
||||||
|
}
|
||||||
return chunks.size();
|
return chunks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkedBlockingDeque<FaweChunk> toUpdate = new LinkedBlockingDeque<>();
|
private LinkedBlockingDeque<FaweChunk> toUpdate = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
public boolean execute(FaweChunk fc) {
|
public boolean execute(final FaweChunk fc) {
|
||||||
if (fc == null) {
|
if (fc == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set blocks / entities / biome
|
// Set blocks / entities / biome
|
||||||
if (!this.setComponents(fc)) {
|
if (getChangeTask() != null) {
|
||||||
|
if (!this.setComponents(fc, new RunnableVal<FaweChunk>() {
|
||||||
|
@Override
|
||||||
|
public void run(FaweChunk before) {
|
||||||
|
getChangeTask().run(before, fc);
|
||||||
|
}
|
||||||
|
})) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!this.setComponents(fc, null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fc.executeTasks();
|
fc.executeNotifyTasks();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +31,6 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
|||||||
|
|
||||||
public abstract void refreshChunk(WORLD world, CHUNK chunk);
|
public abstract void refreshChunk(WORLD world, CHUNK chunk);
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract boolean setComponents(FaweChunk fc);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract boolean fixLighting(FaweChunk fc, boolean fixAll);
|
public abstract boolean fixLighting(FaweChunk fc, boolean fixAll);
|
||||||
}
|
}
|
||||||
|
33
core/src/main/java/com/boydti/fawe/object/BytePair.java
Normal file
33
core/src/main/java/com/boydti/fawe/object/BytePair.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.boydti.fawe.object;
|
||||||
|
|
||||||
|
public class BytePair {
|
||||||
|
public byte[] pair;
|
||||||
|
|
||||||
|
public BytePair(final byte x, final byte z) {
|
||||||
|
this.pair = new byte[] { x, z};
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return pair[0] + (pair[1] << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return pair[0] + "," + pair[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((obj == null) || (this.hashCode() != obj.hashCode()) || (this.getClass() != obj.getClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final BytePair other = (BytePair) obj;
|
||||||
|
return pair[0] == other.pair[0] && pair[1] == other.pair[1];
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,11 @@ package com.boydti.fawe.object;
|
|||||||
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class FaweChunk<T> {
|
public abstract class FaweChunk<T> {
|
||||||
|
|
||||||
@ -56,6 +59,8 @@ public abstract class FaweChunk<T> {
|
|||||||
parent.fixLighting(this, Settings.FIX_ALL_LIGHTING);
|
parent.fixLighting(this, Settings.FIX_ALL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract char[][] getIdArrays();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill this chunk with a block
|
* Fill this chunk with a block
|
||||||
* @param id
|
* @param id
|
||||||
@ -86,13 +91,17 @@ public abstract class FaweChunk<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTask(Runnable run) {
|
public void addNotifyTask(Runnable run) {
|
||||||
if (run != null) {
|
if (run != null) {
|
||||||
tasks.add(run);
|
tasks.add(run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeTasks() {
|
public boolean hasNotifyTasks() {
|
||||||
|
return tasks.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeNotifyTasks() {
|
||||||
for (Runnable task : tasks) {
|
for (Runnable task : tasks) {
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
@ -101,8 +110,18 @@ public abstract class FaweChunk<T> {
|
|||||||
|
|
||||||
public abstract T getChunk();
|
public abstract T getChunk();
|
||||||
|
|
||||||
|
public abstract void setTile(int x, int y, int z, CompoundTag tile);
|
||||||
|
|
||||||
|
public abstract void setEntity(CompoundTag entity);
|
||||||
|
|
||||||
public abstract void setBlock(final int x, final int y, final int z, final int id, final byte data);
|
public abstract void setBlock(final int x, final int y, final int z, final int id, final byte data);
|
||||||
|
|
||||||
|
public abstract CompoundTag getTile(int x, int y, int z);
|
||||||
|
|
||||||
|
public abstract Set<CompoundTag> getEntities();
|
||||||
|
|
||||||
|
public abstract Map<BytePair, CompoundTag> getTiles();
|
||||||
|
|
||||||
public abstract void setBiome(final int x, final int z, final BaseBiome biome);
|
public abstract void setBiome(final int x, final int z, final BaseBiome biome);
|
||||||
|
|
||||||
public void optimize() {}
|
public void optimize() {}
|
||||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.FaweAPI;
|
|||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||||
|
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.boydti.fawe.util.WEManager;
|
import com.boydti.fawe.util.WEManager;
|
||||||
@ -169,7 +170,7 @@ public abstract class FawePlayer<T> {
|
|||||||
Collections.sort(editIds);
|
Collections.sort(editIds);
|
||||||
for (int i = editIds.size() - 1; i >= 0; i--) {
|
for (int i = editIds.size() - 1; i >= 0; i--) {
|
||||||
int index = editIds.get(i);
|
int index = editIds.get(i);
|
||||||
DiskStorageHistory set = new DiskStorageHistory(world, uuid, index);
|
FaweStreamChangeSet set = new DiskStorageHistory(world, uuid, index);
|
||||||
EditSession edit = set.toEditSession(getPlayer());
|
EditSession edit = set.toEditSession(getPlayer());
|
||||||
if (world.equals(getWorld())) {
|
if (world.equals(getWorld())) {
|
||||||
session.remember(edit, false);
|
session.remember(edit, false);
|
||||||
|
@ -41,9 +41,9 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
|||||||
*/
|
*/
|
||||||
public HistoryExtent(final EditSession session, FaweLimit limit, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) {
|
public HistoryExtent(final EditSession session, FaweLimit limit, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) {
|
||||||
super(extent);
|
super(extent);
|
||||||
|
checkNotNull(changeSet);
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
checkNotNull(changeSet);
|
|
||||||
this.changeSet = changeSet;
|
this.changeSet = changeSet;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,44 @@
|
|||||||
package com.boydti.fawe.object;
|
package com.boydti.fawe.object;
|
||||||
|
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.history.change.Change;
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public class NullChangeSet implements FaweChangeSet {
|
public class NullChangeSet extends FaweChangeSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(Change change) {}
|
public boolean flush() {
|
||||||
|
return false;
|
||||||
@Override
|
|
||||||
public Iterator<Change> backwardIterator() {
|
|
||||||
return new ArrayList<Change>().iterator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Change> forwardIterator() {
|
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTileCreate(CompoundTag tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTileRemove(CompoundTag tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityRemove(CompoundTag tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityCreate(CompoundTag tag) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Change> getIterator(boolean undo) {
|
||||||
return new ArrayList<Change>().iterator();
|
return new ArrayList<Change>().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,23 +46,4 @@ public class NullChangeSet implements FaweChangeSet {
|
|||||||
public int size() {
|
public int size() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean flush() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCompressedSize() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Vector location, BaseBlock from, BaseBlock to) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.boydti.fawe.object.change;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.history.UndoContext;
|
||||||
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
|
|
||||||
|
public class MutableBlockChange implements Change {
|
||||||
|
|
||||||
|
public int z;
|
||||||
|
public int y;
|
||||||
|
public int x;
|
||||||
|
public short id;
|
||||||
|
public byte data;
|
||||||
|
|
||||||
|
|
||||||
|
public MutableBlockChange(int x, int y, int z, short id, byte data) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo(UndoContext context) throws WorldEditException {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo(UndoContext context) throws WorldEditException {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(UndoContext context) {
|
||||||
|
Extent extent = context.getExtent();
|
||||||
|
if (extent.getClass() == FastWorldEditExtent.class) {
|
||||||
|
FastWorldEditExtent fwee = (FastWorldEditExtent) extent;
|
||||||
|
fwee.getQueue().setBlock(x, y, z, id, data);
|
||||||
|
} else {
|
||||||
|
Fawe.debug("FAWE doesn't support: " + extent + " for " + getClass() + " (bug Empire92)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.boydti.fawe.object.change;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.DoubleTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.history.UndoContext;
|
||||||
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MutableEntityChange implements Change {
|
||||||
|
|
||||||
|
public CompoundTag tag;
|
||||||
|
public boolean create;
|
||||||
|
|
||||||
|
public MutableEntityChange(CompoundTag tag, boolean create) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.create = create;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo(UndoContext context) throws WorldEditException {
|
||||||
|
if (!create) {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo(UndoContext context) throws WorldEditException {
|
||||||
|
if (create) {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(UndoContext context) {
|
||||||
|
Extent extent = context.getExtent();
|
||||||
|
if (extent.getClass() == FastWorldEditExtent.class) {
|
||||||
|
FastWorldEditExtent fwee = (FastWorldEditExtent) extent;
|
||||||
|
Map<String, Tag> map = tag.getValue();
|
||||||
|
List<DoubleTag> pos = (List<DoubleTag>) map.get("Pos").getValue();
|
||||||
|
int x = (int) Math.round(pos.get(0).getValue());
|
||||||
|
int y = (int) Math.round(pos.get(1).getValue());
|
||||||
|
int z = (int) Math.round(pos.get(2).getValue());
|
||||||
|
fwee.getQueue().setEntity(x, y, z, tag);
|
||||||
|
} else {
|
||||||
|
Fawe.debug("FAWE doesn't support: " + context + " for " + getClass() + " (bug Empire92)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.boydti.fawe.object.change;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.history.UndoContext;
|
||||||
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MutableTileChange implements Change {
|
||||||
|
|
||||||
|
public CompoundTag tag;
|
||||||
|
public boolean create;
|
||||||
|
|
||||||
|
public MutableTileChange(CompoundTag tag, boolean create) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.create = create;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo(UndoContext context) throws WorldEditException {
|
||||||
|
if (!create) {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo(UndoContext context) throws WorldEditException {
|
||||||
|
if (create) {
|
||||||
|
create(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(UndoContext context) {
|
||||||
|
Extent extent = context.getExtent();
|
||||||
|
if (extent.getClass() == FastWorldEditExtent.class) {
|
||||||
|
FastWorldEditExtent fwee = (FastWorldEditExtent) extent;
|
||||||
|
Map<String, Tag> map = tag.getValue();
|
||||||
|
int x = ((IntTag) map.get("x")).getValue();
|
||||||
|
int y = ((IntTag) map.get("y")).getValue();
|
||||||
|
int z = ((IntTag) map.get("z")).getValue();
|
||||||
|
fwee.getQueue().setTile(x, y, z, tag);
|
||||||
|
} else {
|
||||||
|
Fawe.debug("FAWE doesn't support: " + context + " for " + getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,11 @@
|
|||||||
package com.boydti.fawe.object.changeset;
|
package com.boydti.fawe.object.changeset;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.IntegerPair;
|
import com.boydti.fawe.object.IntegerPair;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.IntTag;
|
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.sk89q.jnbt.NamedTag;
|
|
||||||
import com.sk89q.jnbt.Tag;
|
|
||||||
import com.sk89q.worldedit.BlockVector;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.EditSessionFactory;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
|
||||||
import com.sk89q.worldedit.history.change.BlockChange;
|
|
||||||
import com.sk89q.worldedit.history.change.Change;
|
|
||||||
import com.sk89q.worldedit.history.change.EntityCreate;
|
|
||||||
import com.sk89q.worldedit.history.change.EntityRemove;
|
|
||||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -32,18 +13,14 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
import net.jpountz.lz4.LZ4Compressor;
|
import net.jpountz.lz4.LZ4Compressor;
|
||||||
import net.jpountz.lz4.LZ4Factory;
|
import net.jpountz.lz4.LZ4Factory;
|
||||||
import net.jpountz.lz4.LZ4InputStream;
|
import net.jpountz.lz4.LZ4InputStream;
|
||||||
import net.jpountz.lz4.LZ4OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the change on disk
|
* Store the change on disk
|
||||||
@ -52,7 +29,7 @@ import net.jpountz.lz4.LZ4OutputStream;
|
|||||||
* - Minimal memory usage
|
* - Minimal memory usage
|
||||||
* - Slow
|
* - Slow
|
||||||
*/
|
*/
|
||||||
public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||||
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
private File bdFile;
|
private File bdFile;
|
||||||
@ -61,6 +38,11 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
private File entfFile;
|
private File entfFile;
|
||||||
private File enttFile;
|
private File enttFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Summary of this change (not accurate for larger edits)
|
||||||
|
*/
|
||||||
|
private DiskStorageSummary summary;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Block data
|
* Block data
|
||||||
*
|
*
|
||||||
@ -80,22 +62,15 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
// NBT To
|
// NBT To
|
||||||
private NBTOutputStream osNBTT;
|
private NBTOutputStream osNBTT;
|
||||||
private GZIPOutputStream osNBTTG;
|
private GZIPOutputStream osNBTTG;
|
||||||
private AtomicInteger osNBTTI;
|
|
||||||
|
|
||||||
// Entity From
|
// Entity Create From
|
||||||
private NBTOutputStream osENTF;
|
private NBTOutputStream osENTCF;
|
||||||
private GZIPOutputStream osENTFG;
|
private GZIPOutputStream osENTCFG;
|
||||||
private AtomicInteger osENTFI;
|
|
||||||
|
|
||||||
// Entity To
|
// Entity Create To
|
||||||
private NBTOutputStream osENTT;
|
private NBTOutputStream osENTCT;
|
||||||
private GZIPOutputStream osENTTG;
|
private GZIPOutputStream osENTCTG;
|
||||||
private AtomicInteger osENTTI;
|
|
||||||
|
|
||||||
private int ox;
|
|
||||||
private int oz;
|
|
||||||
|
|
||||||
private int size;
|
|
||||||
private World world;
|
private World world;
|
||||||
|
|
||||||
public void deleteFiles() {
|
public void deleteFiles() {
|
||||||
@ -148,23 +123,6 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
return bdFile;
|
return bdFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditSession toEditSession(Player player) {
|
|
||||||
EditSessionFactory factory = WorldEdit.getInstance().getEditSessionFactory();
|
|
||||||
EditSession edit = factory.getEditSession(world, -1, null, player);
|
|
||||||
edit.setChangeSet(this);
|
|
||||||
edit.dequeue();
|
|
||||||
return edit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Change change) {
|
|
||||||
if ((change instanceof BlockChange)) {
|
|
||||||
add((BlockChange) change);
|
|
||||||
} else {
|
|
||||||
Fawe.debug("Does not support " + change + " yet! (Please bug Empire92)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean flush() {
|
public boolean flush() {
|
||||||
boolean flushed = false;
|
boolean flushed = false;
|
||||||
@ -201,123 +159,63 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
public OutputStream getBlockOS(int x, int y, int z) throws IOException {
|
||||||
size++;
|
|
||||||
try {
|
|
||||||
OutputStream stream = getBAOS(x, y, z);
|
|
||||||
//x
|
|
||||||
x-=ox;
|
|
||||||
stream.write((x) & 0xff);
|
|
||||||
stream.write(((x) >> 8) & 0xff);
|
|
||||||
//z
|
|
||||||
z-=oz;
|
|
||||||
stream.write((z) & 0xff);
|
|
||||||
stream.write(((z) >> 8) & 0xff);
|
|
||||||
//y
|
|
||||||
stream.write((byte) y);
|
|
||||||
//from
|
|
||||||
stream.write((combinedFrom) & 0xff);
|
|
||||||
stream.write(((combinedFrom) >> 8) & 0xff);
|
|
||||||
//to
|
|
||||||
stream.write((combinedTo) & 0xff);
|
|
||||||
stream.write(((combinedTo) >> 8) & 0xff);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {
|
|
||||||
int idTo = to.getId();
|
|
||||||
int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4));
|
|
||||||
CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null;
|
|
||||||
add(x, y, z, combinedId4DataFrom, combinedTo);
|
|
||||||
if (nbtTo != null && MainUtil.isValidTag(nbtTo)) {
|
|
||||||
try {
|
|
||||||
Map<String, Tag> value = ReflectionUtils.getMap(nbtTo.getValue());
|
|
||||||
value.put("x", new IntTag(x));
|
|
||||||
value.put("y", new IntTag(y));
|
|
||||||
value.put("z", new IntTag(z));
|
|
||||||
NBTOutputStream nbtos = getNBTTOS(x, y, z);
|
|
||||||
nbtos.writeNamedTag(osNBTTI.getAndIncrement() + "", nbtTo);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Vector loc, BaseBlock from, BaseBlock to) {
|
|
||||||
int x = loc.getBlockX();
|
|
||||||
int y = loc.getBlockY();
|
|
||||||
int z = loc.getBlockZ();
|
|
||||||
try {
|
|
||||||
int idfrom = from.getId();
|
|
||||||
int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4));
|
|
||||||
CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null;
|
|
||||||
|
|
||||||
if (nbtFrom != null && MainUtil.isValidTag(nbtFrom)) {
|
|
||||||
Map<String, Tag> value = ReflectionUtils.getMap(nbtFrom.getValue());
|
|
||||||
value.put("x", new IntTag(x));
|
|
||||||
value.put("y", new IntTag(y));
|
|
||||||
value.put("z", new IntTag(z));
|
|
||||||
NBTOutputStream nbtos = getNBTFOS(x, y, z);
|
|
||||||
nbtos.writeNamedTag(osNBTFI.getAndIncrement() + "", nbtFrom);
|
|
||||||
}
|
|
||||||
add(x, y, z, combinedFrom, to);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(EntityCreate change) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(EntityRemove change) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(BlockChange change) {
|
|
||||||
try {
|
|
||||||
BlockVector loc = change.getPosition();
|
|
||||||
BaseBlock from = change.getPrevious();
|
|
||||||
BaseBlock to = change.getCurrent();
|
|
||||||
add(loc, from, to);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private OutputStream getBAOS(int x, int y, int z) throws IOException {
|
|
||||||
if (osBD != null) {
|
if (osBD != null) {
|
||||||
return osBD;
|
return osBD;
|
||||||
}
|
}
|
||||||
bdFile.getParentFile().mkdirs();
|
bdFile.getParentFile().mkdirs();
|
||||||
bdFile.createNewFile();
|
bdFile.createNewFile();
|
||||||
FileOutputStream stream = new FileOutputStream(bdFile);
|
osBD = getCompressedOS(new FileOutputStream(bdFile));
|
||||||
LZ4Factory factory = LZ4Factory.fastestInstance();
|
setOrigin(x, z);
|
||||||
LZ4Compressor compressor = factory.fastCompressor();
|
osBD.write((byte) (x >> 24));
|
||||||
osBD = new LZ4OutputStream(stream, Settings.BUFFER_SIZE, factory.fastCompressor());
|
osBD.write((byte) (x >> 16));
|
||||||
if (Settings.COMPRESSION_LEVEL > 0) {
|
osBD.write((byte) (x >> 8));
|
||||||
osBD = new LZ4OutputStream(osBD, Settings.BUFFER_SIZE, factory.highCompressor());
|
osBD.write((byte) (x));
|
||||||
}
|
osBD.write((byte) (z >> 24));
|
||||||
ox = x;
|
osBD.write((byte) (z >> 16));
|
||||||
oz = z;
|
osBD.write((byte) (z >> 8));
|
||||||
osBD.write((byte) (ox >> 24));
|
osBD.write((byte) (z));
|
||||||
osBD.write((byte) (ox >> 16));
|
|
||||||
osBD.write((byte) (ox >> 8));
|
|
||||||
osBD.write((byte) (ox));
|
|
||||||
osBD.write((byte) (oz >> 24));
|
|
||||||
osBD.write((byte) (oz >> 16));
|
|
||||||
osBD.write((byte) (oz >> 8));
|
|
||||||
osBD.write((byte) (oz));
|
|
||||||
return osBD;
|
return osBD;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTOutputStream getNBTFOS(int x, int y, int z) throws IOException {
|
@Override
|
||||||
|
public NBTOutputStream getEntityCreateOS() throws IOException {
|
||||||
|
if (osENTCT != null) {
|
||||||
|
return osENTCT;
|
||||||
|
}
|
||||||
|
enttFile.getParentFile().mkdirs();
|
||||||
|
enttFile.createNewFile();
|
||||||
|
osENTCTG = new GZIPOutputStream(new FileOutputStream(enttFile), true);
|
||||||
|
osENTCT = new NBTOutputStream(osENTCTG);
|
||||||
|
return osENTCT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getEntityRemoveOS() throws IOException {
|
||||||
|
if (osENTCF != null) {
|
||||||
|
return osENTCF;
|
||||||
|
}
|
||||||
|
entfFile.getParentFile().mkdirs();
|
||||||
|
entfFile.createNewFile();
|
||||||
|
osENTCFG = new GZIPOutputStream(new FileOutputStream(entfFile), true);
|
||||||
|
osENTCF = new NBTOutputStream(osENTCFG);
|
||||||
|
return osENTCF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getTileCreateOS() throws IOException {
|
||||||
|
if (osNBTT != null) {
|
||||||
|
return osNBTT;
|
||||||
|
}
|
||||||
|
nbttFile.getParentFile().mkdirs();
|
||||||
|
nbttFile.createNewFile();
|
||||||
|
osNBTTG = new GZIPOutputStream(new FileOutputStream(nbttFile), true);
|
||||||
|
osNBTT = new NBTOutputStream(osNBTTG);
|
||||||
|
return osNBTT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getTileRemoveOS() throws IOException {
|
||||||
if (osNBTF != null) {
|
if (osNBTF != null) {
|
||||||
return osNBTF;
|
return osNBTF;
|
||||||
}
|
}
|
||||||
@ -329,50 +227,57 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
return osNBTF;
|
return osNBTF;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTOutputStream getNBTTOS(int x, int y, int z) throws IOException {
|
@Override
|
||||||
if (osNBTT != null) {
|
public InputStream getBlockIS() throws IOException {
|
||||||
return osNBTT;
|
if (!bdFile.exists()) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
nbttFile.getParentFile().mkdirs();
|
InputStream is = getCompressedIS(new FileInputStream(bdFile));
|
||||||
nbttFile.createNewFile();
|
int x = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0));
|
||||||
osNBTTG = new GZIPOutputStream(new FileOutputStream(nbttFile), true);
|
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0));
|
||||||
osNBTT = new NBTOutputStream(osNBTTG);
|
setOrigin(x, z);
|
||||||
osNBTTI = new AtomicInteger();
|
return is;
|
||||||
return osNBTT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTOutputStream getENTFOS(int x, int y, int z) throws IOException {
|
@Override
|
||||||
if (osNBTF != null) {
|
public NBTInputStream getEntityCreateIS() throws IOException {
|
||||||
return osNBTF;
|
if (!enttFile.exists()) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
entfFile.getParentFile().mkdirs();
|
return new NBTInputStream(getCompressedIS(new FileInputStream(enttFile)));
|
||||||
entfFile.createNewFile();
|
|
||||||
osENTFG = new GZIPOutputStream(new FileOutputStream(entfFile), true);
|
|
||||||
osENTF = new NBTOutputStream(osENTFG);
|
|
||||||
osENTFI = new AtomicInteger();
|
|
||||||
return osENTF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTOutputStream getENTTOS(int x, int y, int z) throws IOException {
|
@Override
|
||||||
if (osENTT != null) {
|
public NBTInputStream getEntityRemoveIS() throws IOException {
|
||||||
return osENTT;
|
if (!entfFile.exists()) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
enttFile.getParentFile().mkdirs();
|
return new NBTInputStream(getCompressedIS(new FileInputStream(entfFile)));
|
||||||
enttFile.createNewFile();
|
|
||||||
osENTTG = new GZIPOutputStream(new FileOutputStream(enttFile), true);
|
|
||||||
osENTT = new NBTOutputStream(osENTTG);
|
|
||||||
osENTTI = new AtomicInteger();
|
|
||||||
return osENTT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTInputStream getTileCreateIS() throws IOException {
|
||||||
|
if (!nbttFile.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new NBTInputStream(getCompressedIS(new FileInputStream(nbttFile)));
|
||||||
|
}
|
||||||
|
|
||||||
private DiskStorageSummary summary;
|
@Override
|
||||||
|
public NBTInputStream getTileRemoveIS() throws IOException {
|
||||||
|
if (!nbtfFile.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new NBTInputStream(getCompressedIS(new FileInputStream(nbtfFile)));
|
||||||
|
}
|
||||||
|
|
||||||
public DiskStorageSummary summarize(RegionWrapper requiredRegion, boolean shallow) {
|
public DiskStorageSummary summarize(RegionWrapper requiredRegion, boolean shallow) {
|
||||||
if (summary != null) {
|
if (summary != null) {
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
if (bdFile.exists()) {
|
if (bdFile.exists()) {
|
||||||
|
int ox = getOriginX();
|
||||||
|
int oz = getOriginZ();
|
||||||
if ((ox != 0 || oz != 0) && !requiredRegion.isIn(ox, oz)) {
|
if ((ox != 0 || oz != 0) && !requiredRegion.isIn(ox, oz)) {
|
||||||
return summary = new DiskStorageSummary(ox, oz);
|
return summary = new DiskStorageSummary(ox, oz);
|
||||||
}
|
}
|
||||||
@ -387,6 +292,7 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
}
|
}
|
||||||
ox = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
ox = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
||||||
oz = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
oz = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
||||||
|
setOrigin(ox, oz);
|
||||||
summary = new DiskStorageSummary(ox, oz);
|
summary = new DiskStorageSummary(ox, oz);
|
||||||
if (!requiredRegion.isIn(ox, oz)) {
|
if (!requiredRegion.isIn(ox, oz)) {
|
||||||
fis.close();
|
fis.close();
|
||||||
@ -415,6 +321,8 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IntegerPair readHeader() {
|
public IntegerPair readHeader() {
|
||||||
|
int ox = getOriginX();
|
||||||
|
int oz = getOriginZ();
|
||||||
if (ox == 0 && oz == 0 && bdFile.exists()) {
|
if (ox == 0 && oz == 0 && bdFile.exists()) {
|
||||||
try {
|
try {
|
||||||
FileInputStream fis = new FileInputStream(bdFile);
|
FileInputStream fis = new FileInputStream(bdFile);
|
||||||
@ -428,6 +336,7 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
}
|
}
|
||||||
ox = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
ox = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
||||||
oz = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
oz = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
||||||
|
setOrigin(ox, oz);
|
||||||
fis.close();
|
fis.close();
|
||||||
gis.close();
|
gis.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -437,129 +346,6 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
|||||||
return new IntegerPair(ox, oz);
|
return new IntegerPair(ox, oz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public Iterator<Change> getIterator(final boolean dir) {
|
|
||||||
flush();
|
|
||||||
try {
|
|
||||||
if (bdFile.exists()) {
|
|
||||||
final NBTInputStream nbtf = nbtfFile.exists() ? new NBTInputStream(new GZIPInputStream(new FileInputStream(nbtfFile))) : null;
|
|
||||||
final NBTInputStream nbtt = nbttFile.exists() ? new NBTInputStream(new GZIPInputStream(new FileInputStream(nbttFile))) : null;
|
|
||||||
|
|
||||||
FileInputStream fis = new FileInputStream(bdFile);
|
|
||||||
LZ4Factory factory = LZ4Factory.fastestInstance();
|
|
||||||
LZ4Compressor compressor = factory.fastCompressor();
|
|
||||||
final InputStream gis;
|
|
||||||
if (Settings.COMPRESSION_LEVEL > 0) {
|
|
||||||
gis = new LZ4InputStream(new LZ4InputStream(fis));
|
|
||||||
} else {
|
|
||||||
gis = new LZ4InputStream(fis);
|
|
||||||
}
|
|
||||||
ox = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
|
||||||
oz = ((gis.read() << 24) + (gis.read() << 16) + (gis.read() << 8) + (gis.read() << 0));
|
|
||||||
return new Iterator<Change>() {
|
|
||||||
|
|
||||||
private CompoundTag lastFrom = read(nbtf);
|
|
||||||
private CompoundTag lastTo = read(nbtt);
|
|
||||||
private Change last = read();
|
|
||||||
|
|
||||||
public CompoundTag read(NBTInputStream stream) {
|
|
||||||
if (stream != null) {
|
|
||||||
try {
|
|
||||||
NamedTag nt = stream.readNamedTag();
|
|
||||||
return nt != null ? ((CompoundTag) nt.getTag()) : null;
|
|
||||||
} catch (IOException ignore) {}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Change read() {
|
|
||||||
try {
|
|
||||||
int x = ((byte) gis.read() & 0xFF) + ((byte) gis.read() << 8) + ox;
|
|
||||||
int z = ((byte) gis.read() & 0xFF) + ((byte) gis.read() << 8) + oz;
|
|
||||||
int y = gis.read() & 0xff;
|
|
||||||
int from1 = gis.read();
|
|
||||||
int from2 = gis.read();
|
|
||||||
BaseBlock from = FaweCache.getBlock(((from2 << 4) + (from1 >> 4)), (from1 & 0xf));
|
|
||||||
if (lastFrom != null && FaweCache.hasNBT(from.getId())) {
|
|
||||||
Map<String, Tag> t = lastFrom.getValue();
|
|
||||||
if (((IntTag) t.get("x")).getValue() == x && ((IntTag) t.get("z")).getValue() == z && ((IntTag) t.get("y")).getValue() == y) {
|
|
||||||
from = new BaseBlock(from.getId(), from.getData());
|
|
||||||
from.setNbtData(lastFrom);
|
|
||||||
lastFrom = read(nbtf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int to1 = gis.read();
|
|
||||||
int to2 = gis.read();
|
|
||||||
BaseBlock to = FaweCache.getBlock(((to2 << 4) + (to1 >> 4)), (to1 & 0xf));
|
|
||||||
if (lastTo != null && FaweCache.hasNBT(to.getId())) {
|
|
||||||
Map<String, Tag> t = lastTo.getValue();
|
|
||||||
if (((IntTag) t.get("x")).getValue() == x && ((IntTag) t.get("z")).getValue() == z && ((IntTag) t.get("y")).getValue() == y) {
|
|
||||||
to = new BaseBlock(to.getId(), to.getData());
|
|
||||||
to.setNbtData(lastTo);
|
|
||||||
lastTo = read(nbtt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockVector position = new BlockVector(x, y, z);
|
|
||||||
return dir ? new BlockChange(position, to, from) : new BlockChange(position, from, to);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
if (last != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
gis.close();
|
|
||||||
if (nbtf != null) {
|
|
||||||
nbtf.close();
|
|
||||||
}
|
|
||||||
if (nbtt != null) {
|
|
||||||
nbtt.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Change next() {
|
|
||||||
Change tmp = last;
|
|
||||||
last = read();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new IllegalArgumentException("CANNOT REMOVE");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return new ArrayList<Change>().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Change> backwardIterator() {
|
|
||||||
return getIterator(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Change> forwardIterator() {
|
|
||||||
return getIterator(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
flush();
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DiskStorageSummary {
|
public static class DiskStorageSummary {
|
||||||
|
|
||||||
private final int z;
|
private final int z;
|
||||||
|
@ -1,17 +1,222 @@
|
|||||||
package com.boydti.fawe.object.changeset;
|
package com.boydti.fawe.object.changeset;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.object.BytePair;
|
||||||
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.EditSessionFactory;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.history.change.BlockChange;
|
||||||
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
|
import com.sk89q.worldedit.history.change.EntityCreate;
|
||||||
|
import com.sk89q.worldedit.history.change.EntityRemove;
|
||||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface FaweChangeSet extends ChangeSet {
|
public abstract class FaweChangeSet implements ChangeSet {
|
||||||
boolean flush();
|
public abstract boolean flush();
|
||||||
|
|
||||||
int getCompressedSize();
|
public abstract void add(int x, int y, int z, int combinedFrom, int combinedTo);
|
||||||
|
|
||||||
void add(Vector location, BaseBlock from, BaseBlock to);
|
@Override
|
||||||
|
public Iterator<Change> backwardIterator() {
|
||||||
|
return getIterator(false);
|
||||||
|
}
|
||||||
|
|
||||||
void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to);
|
@Override
|
||||||
|
public Iterator<Change> forwardIterator() {
|
||||||
|
return getIterator(true);
|
||||||
|
}
|
||||||
|
|
||||||
void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo);
|
public abstract void addTileCreate(CompoundTag tag);
|
||||||
|
public abstract void addTileRemove(CompoundTag tag);
|
||||||
|
public abstract void addEntityRemove(CompoundTag tag);
|
||||||
|
public abstract void addEntityCreate(CompoundTag tag);
|
||||||
|
public abstract Iterator<Change> getIterator(boolean redo);
|
||||||
|
|
||||||
|
public EditSession toEditSession(Player player) {
|
||||||
|
EditSessionFactory factory = WorldEdit.getInstance().getEditSessionFactory();
|
||||||
|
EditSession edit = factory.getEditSession(player.getWorld(), -1, null, player);
|
||||||
|
edit.setChangeSet(this);
|
||||||
|
edit.dequeue();
|
||||||
|
return edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EntityCreate change) {
|
||||||
|
CompoundTag tag = change.state.getNbtData();
|
||||||
|
MainUtil.setEntityInfo(tag, change.entity);
|
||||||
|
addEntityCreate(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EntityRemove change) {
|
||||||
|
CompoundTag tag = change.state.getNbtData();
|
||||||
|
MainUtil.setEntityInfo(tag, change.entity);
|
||||||
|
addEntityRemove(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Change change) {
|
||||||
|
if (change.getClass() == BlockChange.class) {
|
||||||
|
add((BlockChange) change);
|
||||||
|
} else if (change.getClass() == EntityCreate.class) {
|
||||||
|
add((EntityCreate) change);
|
||||||
|
} else if (change.getClass() == EntityRemove.class) {
|
||||||
|
add((EntityRemove) change);
|
||||||
|
} else {
|
||||||
|
Fawe.debug("Unknown change: " + change.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(BlockChange change) {
|
||||||
|
try {
|
||||||
|
BlockVector loc = change.getPosition();
|
||||||
|
BaseBlock from = change.getPrevious();
|
||||||
|
BaseBlock to = change.getCurrent();
|
||||||
|
add(loc, from, to);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Vector loc, BaseBlock from, BaseBlock to) {
|
||||||
|
int x = loc.getBlockX();
|
||||||
|
int y = loc.getBlockY();
|
||||||
|
int z = loc.getBlockZ();
|
||||||
|
add(x, y, z, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int x, int y, int z, BaseBlock from, BaseBlock to) {
|
||||||
|
try {
|
||||||
|
if (from.hasNbtData()) {
|
||||||
|
CompoundTag nbt = from.getNbtData();
|
||||||
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
|
addTileRemove(nbt);
|
||||||
|
}
|
||||||
|
if (to.hasNbtData()) {
|
||||||
|
CompoundTag nbt = to.getNbtData();
|
||||||
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
|
addTileRemove(nbt);
|
||||||
|
}
|
||||||
|
int combinedFrom = (from.getId() << 4) + from.getData();
|
||||||
|
int combinedTo = (to.getId() << 4) + to.getData();
|
||||||
|
add(x, y, z, combinedFrom, combinedTo);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int x, int y, int z, int combinedFrom, BaseBlock to) {
|
||||||
|
try {
|
||||||
|
if (to.hasNbtData()) {
|
||||||
|
CompoundTag nbt = to.getNbtData();
|
||||||
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
|
addTileRemove(nbt);
|
||||||
|
}
|
||||||
|
int combinedTo = (to.getId() << 4) + to.getData();
|
||||||
|
add(x, y, z, combinedFrom, combinedTo);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChangeTask(FaweQueue queue) {
|
||||||
|
queue.setChangeTask(new RunnableVal2<FaweChunk, FaweChunk>() {
|
||||||
|
@Override
|
||||||
|
public void run(final FaweChunk previous, FaweChunk next) {
|
||||||
|
/**
|
||||||
|
* TODO cache NBT
|
||||||
|
* - Counter variable for nbt changes
|
||||||
|
* - Record biome changes
|
||||||
|
*/
|
||||||
|
int cx = previous.getX();
|
||||||
|
int cz = previous.getZ();
|
||||||
|
int bx = cx << 4;
|
||||||
|
int bz = cz << 4;
|
||||||
|
|
||||||
|
// Biome changes
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block changes
|
||||||
|
{
|
||||||
|
// Current blocks
|
||||||
|
char[][] currentIds = next.getIdArrays();
|
||||||
|
// Previous blocks in modified sections (i.e. we skip sections that weren't modified)
|
||||||
|
char[][] previousIds = previous.getIdArrays();
|
||||||
|
for (int layer = 0; layer < currentIds.length; layer++) {
|
||||||
|
char[] currentLayer = currentIds[layer];
|
||||||
|
char[] previousLayer = previousIds[layer];
|
||||||
|
if (currentLayer == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int startY = layer << 4;
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
short[][] i1 = FaweCache.CACHE_J[y];
|
||||||
|
int yy = y + startY;
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int xx = x + bx;
|
||||||
|
short[] i2 = i1[x];
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int zz = z + bz;
|
||||||
|
int index = i2[z];
|
||||||
|
int combinedIdCurrent = currentLayer[index];
|
||||||
|
switch (combinedIdCurrent) {
|
||||||
|
case 0:
|
||||||
|
continue;
|
||||||
|
case 1:
|
||||||
|
combinedIdCurrent = 0;
|
||||||
|
default:
|
||||||
|
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
|
||||||
|
if (combinedIdCurrent != combinedIdPrevious) {
|
||||||
|
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tile changes
|
||||||
|
{
|
||||||
|
// Tiles created
|
||||||
|
Map<BytePair, CompoundTag> tiles = next.getTiles();
|
||||||
|
for (Map.Entry<BytePair, CompoundTag> entry : tiles.entrySet()) {
|
||||||
|
addTileCreate(entry.getValue());
|
||||||
|
}
|
||||||
|
// Tiles removed
|
||||||
|
tiles = previous.getTiles();
|
||||||
|
for (Map.Entry<BytePair, CompoundTag> entry : tiles.entrySet()) {
|
||||||
|
addTileRemove(entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Entity changes
|
||||||
|
{
|
||||||
|
// Entities created
|
||||||
|
Set<CompoundTag> entities = next.getEntities();
|
||||||
|
for (CompoundTag entityTag : entities) {
|
||||||
|
addEntityCreate(entityTag);
|
||||||
|
}
|
||||||
|
// Entities removed
|
||||||
|
entities = previous.getEntities();
|
||||||
|
for (CompoundTag entityTag : entities) {
|
||||||
|
addEntityRemove(entityTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,363 @@
|
|||||||
|
package com.boydti.fawe.object.changeset;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
|
import com.boydti.fawe.object.change.MutableBlockChange;
|
||||||
|
import com.boydti.fawe.object.change.MutableEntityChange;
|
||||||
|
import com.boydti.fawe.object.change.MutableTileChange;
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import net.jpountz.lz4.LZ4Compressor;
|
||||||
|
import net.jpountz.lz4.LZ4Factory;
|
||||||
|
import net.jpountz.lz4.LZ4InputStream;
|
||||||
|
import net.jpountz.lz4.LZ4OutputStream;
|
||||||
|
|
||||||
|
public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
System.out.println("SIZE: " + blockSize);
|
||||||
|
// Flush so we can accurately get the size
|
||||||
|
flush();
|
||||||
|
return blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int getCompressedSize();
|
||||||
|
|
||||||
|
public abstract OutputStream getBlockOS(int x, int y, int z) throws IOException;
|
||||||
|
public abstract NBTOutputStream getEntityCreateOS() throws IOException;
|
||||||
|
public abstract NBTOutputStream getEntityRemoveOS() throws IOException;
|
||||||
|
public abstract NBTOutputStream getTileCreateOS() throws IOException;
|
||||||
|
public abstract NBTOutputStream getTileRemoveOS() throws IOException;
|
||||||
|
|
||||||
|
public abstract InputStream getBlockIS() throws IOException;
|
||||||
|
public abstract NBTInputStream getEntityCreateIS() throws IOException;
|
||||||
|
public abstract NBTInputStream getEntityRemoveIS() throws IOException;
|
||||||
|
public abstract NBTInputStream getTileCreateIS() throws IOException;
|
||||||
|
public abstract NBTInputStream getTileRemoveIS() throws IOException;
|
||||||
|
|
||||||
|
public int blockSize;
|
||||||
|
public int entityCreateSize;
|
||||||
|
public int entityRemoveSize;
|
||||||
|
public int tileCreateSize;
|
||||||
|
public int tileRemoveSize;
|
||||||
|
|
||||||
|
private int originX;
|
||||||
|
private int originZ;
|
||||||
|
|
||||||
|
public void setOrigin(int x, int z) {
|
||||||
|
originX = x;
|
||||||
|
originZ = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOriginX() {
|
||||||
|
return originX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOriginZ() {
|
||||||
|
return originZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getCompressedIS(InputStream is) {
|
||||||
|
if (Settings.COMPRESSION_LEVEL > 0) {
|
||||||
|
is = new LZ4InputStream(new LZ4InputStream(is));
|
||||||
|
} else {
|
||||||
|
is = new LZ4InputStream(is);
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutputStream getCompressedOS(OutputStream os) throws IOException {
|
||||||
|
LZ4Factory factory = LZ4Factory.fastestInstance();
|
||||||
|
LZ4Compressor compressor = factory.fastCompressor();
|
||||||
|
os = new LZ4OutputStream(os, Settings.BUFFER_SIZE, factory.fastCompressor());
|
||||||
|
if (Settings.COMPRESSION_LEVEL > 0) {
|
||||||
|
os = new LZ4OutputStream(os, Settings.BUFFER_SIZE, factory.highCompressor());
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
||||||
|
blockSize++;
|
||||||
|
try {
|
||||||
|
OutputStream stream = getBlockOS(x, y, z);
|
||||||
|
//x
|
||||||
|
x-=originX;
|
||||||
|
stream.write((x) & 0xff);
|
||||||
|
stream.write(((x) >> 8) & 0xff);
|
||||||
|
//z
|
||||||
|
z-=originZ;
|
||||||
|
stream.write((z) & 0xff);
|
||||||
|
stream.write(((z) >> 8) & 0xff);
|
||||||
|
//y
|
||||||
|
stream.write((byte) y);
|
||||||
|
//from
|
||||||
|
stream.write((combinedFrom) & 0xff);
|
||||||
|
stream.write(((combinedFrom) >> 8) & 0xff);
|
||||||
|
//to
|
||||||
|
stream.write((combinedTo) & 0xff);
|
||||||
|
stream.write(((combinedTo) >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTileCreate(CompoundTag tag) {
|
||||||
|
if (tag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NBTOutputStream nbtos = getTileCreateOS();
|
||||||
|
nbtos.writeNamedTag(tileCreateSize++ + "", tag);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTileRemove(CompoundTag tag) {
|
||||||
|
if (tag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NBTOutputStream nbtos = getTileRemoveOS();
|
||||||
|
nbtos.writeNamedTag(tileRemoveSize++ + "", tag);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntityRemove(CompoundTag tag) {
|
||||||
|
if (tag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NBTOutputStream nbtos = getEntityRemoveOS();
|
||||||
|
nbtos.writeNamedTag(entityRemoveSize++ + "", tag);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntityCreate(CompoundTag tag) {
|
||||||
|
if (tag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NBTOutputStream nbtos = getEntityCreateOS();
|
||||||
|
nbtos.writeNamedTag(entityCreateSize++ + "", tag);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<MutableBlockChange> getBlockIterator(final boolean dir) throws IOException {
|
||||||
|
final InputStream is = getBlockIS();
|
||||||
|
if (is == null) {
|
||||||
|
return new ArrayList<MutableBlockChange>().iterator();
|
||||||
|
}
|
||||||
|
final MutableBlockChange change = new MutableBlockChange(0, 0, 0, (short) 0, (byte) 0);
|
||||||
|
return new Iterator<MutableBlockChange>() {
|
||||||
|
private MutableBlockChange last = read();
|
||||||
|
public MutableBlockChange read() {
|
||||||
|
try {
|
||||||
|
int read0 = is.read();
|
||||||
|
if (read0 == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
System.out.println("r0: " + read0);
|
||||||
|
int x = ((byte) read0 & 0xFF) + ((byte) is.read() << 8) + originX;
|
||||||
|
int z = ((byte) is.read() & 0xFF) + ((byte) is.read() << 8) + originZ;
|
||||||
|
int y = is.read() & 0xff;
|
||||||
|
change.x = x;
|
||||||
|
change.y = y;
|
||||||
|
change.z = z;
|
||||||
|
if (dir) {
|
||||||
|
is.skip(2);
|
||||||
|
int to1 = is.read();
|
||||||
|
int to2 = is.read();
|
||||||
|
change.id = (short) ((to2 << 4) + (to1 >> 4));
|
||||||
|
change.data = (byte) (to1 & 0xf);
|
||||||
|
} else {
|
||||||
|
int from1 = is.read();
|
||||||
|
int from2 = is.read();
|
||||||
|
is.skip(2);
|
||||||
|
change.id = (short) ((from2 << 4) + (from1 >> 4));
|
||||||
|
change.data = (byte) (from1 & 0xf);
|
||||||
|
}
|
||||||
|
System.out.println("CHANGE: " + change.id);
|
||||||
|
return change;
|
||||||
|
} catch (Exception ignoreEOF) {
|
||||||
|
ignoreEOF.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (last == null) {
|
||||||
|
last = read();
|
||||||
|
}
|
||||||
|
if (last != null) {
|
||||||
|
System.out.println("HAS NEXT!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
System.out.println("NO NEXT");
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutableBlockChange next() {
|
||||||
|
MutableBlockChange tmp = last;
|
||||||
|
last = null;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new IllegalArgumentException("CANNOT REMOVE");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<MutableEntityChange> getEntityIterator(final NBTInputStream is, final boolean create, final boolean dir) {
|
||||||
|
if (is == null) {
|
||||||
|
return new ArrayList<MutableEntityChange>().iterator();
|
||||||
|
}
|
||||||
|
final MutableEntityChange change = new MutableEntityChange(null, create);
|
||||||
|
try {
|
||||||
|
return new Iterator<MutableEntityChange>() {
|
||||||
|
private CompoundTag last = read();
|
||||||
|
|
||||||
|
public CompoundTag read() {
|
||||||
|
try {
|
||||||
|
return (CompoundTag) is.readNamedTag().getTag();
|
||||||
|
} catch (Exception ignoreEOS) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (last == null) {
|
||||||
|
last = read();
|
||||||
|
}
|
||||||
|
if (last != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutableEntityChange next() {
|
||||||
|
change.tag = last;
|
||||||
|
last = null;
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new IllegalArgumentException("CANNOT REMOVE");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<MutableTileChange> getTileIterator(final NBTInputStream is, final boolean create, final boolean dir) {
|
||||||
|
if (is == null) {
|
||||||
|
return new ArrayList<MutableTileChange>().iterator();
|
||||||
|
}
|
||||||
|
final MutableTileChange change = new MutableTileChange(null, create);
|
||||||
|
try {
|
||||||
|
return new Iterator<MutableTileChange>() {
|
||||||
|
private CompoundTag last = read();
|
||||||
|
|
||||||
|
public CompoundTag read() {
|
||||||
|
try {
|
||||||
|
return (CompoundTag) is.readNamedTag().getTag();
|
||||||
|
} catch (Exception ignoreEOS) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (last == null) {
|
||||||
|
last = read();
|
||||||
|
}
|
||||||
|
if (last != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutableTileChange next() {
|
||||||
|
change.tag = last;
|
||||||
|
last = null;
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new IllegalArgumentException("CANNOT REMOVE");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Change> getIterator(final boolean dir) {
|
||||||
|
System.out.println("GET ITERATOR: " + dir);
|
||||||
|
flush();
|
||||||
|
try {
|
||||||
|
Iterator<MutableTileChange> tileCreate = getTileIterator(getTileCreateIS(), true, dir);
|
||||||
|
Iterator<MutableTileChange> tileRemove = getTileIterator(getTileRemoveIS(), false, dir);
|
||||||
|
|
||||||
|
Iterator<MutableEntityChange> entityCreate = getEntityIterator(getEntityCreateIS(), true, dir);
|
||||||
|
Iterator<MutableEntityChange> entityRemove = getEntityIterator(getEntityRemoveIS(), false, dir);
|
||||||
|
|
||||||
|
Iterator<MutableBlockChange> blockChange = getBlockIterator(dir);
|
||||||
|
|
||||||
|
return Iterators.concat(tileCreate, tileRemove, entityCreate, entityRemove, blockChange);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return new ArrayList<Change>().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Change> backwardIterator() {
|
||||||
|
return getIterator(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Change> forwardIterator() {
|
||||||
|
return getIterator(true);
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,14 @@
|
|||||||
package com.boydti.fawe.object.changeset;
|
package com.boydti.fawe.object.changeset;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.google.common.collect.Iterators;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.IntTag;
|
|
||||||
import com.sk89q.jnbt.Tag;
|
|
||||||
import com.sk89q.worldedit.BlockVector;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.history.change.BlockChange;
|
|
||||||
import com.sk89q.worldedit.history.change.Change;
|
|
||||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import net.jpountz.lz4.LZ4Factory;
|
import net.jpountz.lz4.LZ4Factory;
|
||||||
import net.jpountz.lz4.LZ4InputStream;
|
import net.jpountz.lz4.LZ4InputStream;
|
||||||
import net.jpountz.lz4.LZ4OutputStream;
|
import net.jpountz.lz4.LZ4OutputStream;
|
||||||
@ -34,250 +19,14 @@ import net.jpountz.lz4.LZ4OutputStream;
|
|||||||
* - High CPU usage
|
* - High CPU usage
|
||||||
* - Low memory usage
|
* - Low memory usage
|
||||||
*/
|
*/
|
||||||
public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet {
|
public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
||||||
|
|
||||||
private final Actor actor;
|
private final Actor actor;
|
||||||
private ArrayDeque<CompoundTag> fromTags;
|
|
||||||
private ArrayDeque<CompoundTag> toTags;
|
|
||||||
|
|
||||||
private byte[] ids;
|
|
||||||
private Object lock;
|
|
||||||
private int decompressedLength;
|
|
||||||
|
|
||||||
private FastByteArrayOutputStream idsStream;
|
|
||||||
private OutputStream idsStreamZip;
|
|
||||||
|
|
||||||
private ArrayDeque<Change> entities;
|
|
||||||
|
|
||||||
int ox;
|
|
||||||
int oz;
|
|
||||||
|
|
||||||
private int size;
|
|
||||||
|
|
||||||
public MemoryOptimizedHistory(Actor actor) {
|
public MemoryOptimizedHistory(Actor actor) {
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
|
||||||
size++;
|
|
||||||
try {
|
|
||||||
OutputStream stream = getBAOS(x, y, z);
|
|
||||||
//x
|
|
||||||
x -= ox;
|
|
||||||
z -= oz;
|
|
||||||
stream.write((x & 0xff));
|
|
||||||
stream.write(((x >> 8) & 0xff));
|
|
||||||
//z
|
|
||||||
stream.write((z & 0xff));
|
|
||||||
stream.write( ((z >> 8) & 0xff));
|
|
||||||
//y
|
|
||||||
stream.write((byte) y);
|
|
||||||
//from
|
|
||||||
stream.write((combinedFrom) & 0xff);
|
|
||||||
stream.write(((combinedFrom) >> 8) & 0xff);
|
|
||||||
//to
|
|
||||||
stream.write((combinedTo) & 0xff);
|
|
||||||
stream.write(((combinedTo) >> 8) & 0xff);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {
|
|
||||||
int idTo = to.getId();
|
|
||||||
int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4));
|
|
||||||
CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null;
|
|
||||||
add(x, y, z, combinedId4DataFrom, combinedTo);
|
|
||||||
if (nbtTo != null && MainUtil.isValidTag(nbtTo)) {
|
|
||||||
Map<String, Tag> value = ReflectionUtils.getMap(nbtTo.getValue());
|
|
||||||
value.put("x", new IntTag(x));
|
|
||||||
value.put("y", new IntTag(y));
|
|
||||||
value.put("z", new IntTag(z));
|
|
||||||
if (toTags == null) {
|
|
||||||
toTags = new ArrayDeque<>();
|
|
||||||
}
|
|
||||||
toTags.add(nbtTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Vector loc, BaseBlock from, BaseBlock to) {
|
|
||||||
try {
|
|
||||||
int x = loc.getBlockX();
|
|
||||||
int y = loc.getBlockY();
|
|
||||||
int z = loc.getBlockZ();
|
|
||||||
|
|
||||||
int idfrom = from.getId();
|
|
||||||
int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4));
|
|
||||||
CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null;
|
|
||||||
if (nbtFrom != null && MainUtil.isValidTag(nbtFrom)) {
|
|
||||||
Map<String, Tag> value = ReflectionUtils.getMap(nbtFrom.getValue());
|
|
||||||
value.put("x", new IntTag(x));
|
|
||||||
value.put("y", new IntTag(y));
|
|
||||||
value.put("z", new IntTag(z));
|
|
||||||
if (fromTags == null) {
|
|
||||||
fromTags = new ArrayDeque<>();
|
|
||||||
}
|
|
||||||
fromTags.add(nbtFrom);
|
|
||||||
}
|
|
||||||
add(x, y, z, combinedFrom, to);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(Change arg) {
|
|
||||||
if ((arg instanceof BlockChange)) {
|
|
||||||
BlockChange change = (BlockChange) arg;
|
|
||||||
BlockVector loc = change.getPosition();
|
|
||||||
BaseBlock from = change.getPrevious();
|
|
||||||
BaseBlock to = change.getCurrent();
|
|
||||||
add(loc, from, to);
|
|
||||||
} else {
|
|
||||||
if (entities == null) {
|
|
||||||
entities = new ArrayDeque<>();
|
|
||||||
}
|
|
||||||
entities.add(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private OutputStream getBAOS(int x, int y, int z) throws IOException {
|
|
||||||
if (idsStreamZip != null) {
|
|
||||||
return idsStreamZip;
|
|
||||||
}
|
|
||||||
LZ4Factory factory = LZ4Factory.fastestInstance();
|
|
||||||
idsStream = new FastByteArrayOutputStream(Settings.BUFFER_SIZE);
|
|
||||||
idsStreamZip = new LZ4OutputStream(idsStream, Settings.BUFFER_SIZE, factory.fastCompressor());
|
|
||||||
if (Settings.COMPRESSION_LEVEL > 0) {
|
|
||||||
idsStreamZip = new LZ4OutputStream(idsStreamZip, Settings.BUFFER_SIZE, factory.highCompressor());
|
|
||||||
}
|
|
||||||
ox = x;
|
|
||||||
oz = z;
|
|
||||||
return idsStreamZip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public Iterator<Change> getIterator(final boolean dir) {
|
|
||||||
flush();
|
|
||||||
if (lock != null) {
|
|
||||||
try {
|
|
||||||
lock.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Iterator<Change> idsIterator;
|
|
||||||
Iterator<Change> entsIterator = entities != null ? entities.iterator() : new ArrayList().iterator();
|
|
||||||
if (ids == null) {
|
|
||||||
idsIterator = new ArrayList().iterator();
|
|
||||||
} else {
|
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(ids);
|
|
||||||
final InputStream gis;
|
|
||||||
if (Settings.COMPRESSION_LEVEL > 0) {
|
|
||||||
gis = new LZ4InputStream(new LZ4InputStream(bais));
|
|
||||||
} else {
|
|
||||||
gis = new LZ4InputStream(bais);
|
|
||||||
}
|
|
||||||
idsIterator = new Iterator<Change>() {
|
|
||||||
private final Iterator<CompoundTag> lastFromIter = fromTags != null ? fromTags.iterator() : null;
|
|
||||||
private final Iterator<CompoundTag> lastToIter = toTags != null ? toTags.iterator() : null;
|
|
||||||
private CompoundTag lastFrom = read(lastFromIter);
|
|
||||||
private CompoundTag lastTo = read(lastToIter);
|
|
||||||
private Change last = read();
|
|
||||||
|
|
||||||
public CompoundTag read(Iterator<CompoundTag> tags) {
|
|
||||||
if (tags != null && tags.hasNext()) {
|
|
||||||
return tags.next();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Change read() {
|
|
||||||
try {
|
|
||||||
int x = ((byte) gis.read() & 0xFF) + ((byte) gis.read() << 8) + ox;
|
|
||||||
int z = ((byte) gis.read() & 0xFF) + ((byte) gis.read() << 8) + oz;
|
|
||||||
int y = gis.read() & 0xff;
|
|
||||||
int from1 = gis.read();
|
|
||||||
int from2 = gis.read();
|
|
||||||
BaseBlock from = FaweCache.getBlock(((from2 << 4) + (from1 >> 4)), (from1 & 0xf));
|
|
||||||
if (lastFrom != null && FaweCache.hasNBT(from.getId())) {
|
|
||||||
Map<String, Tag> t = lastFrom.getValue();
|
|
||||||
if (((IntTag) t.get("x")).getValue() == x && ((IntTag) t.get("z")).getValue() == z && ((IntTag) t.get("y")).getValue() == y) {
|
|
||||||
from = new BaseBlock(from.getId(), from.getData());
|
|
||||||
from.setNbtData(lastFrom);
|
|
||||||
lastFrom = read(lastFromIter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int to1 = gis.read();
|
|
||||||
int to2 = gis.read();
|
|
||||||
BaseBlock to = FaweCache.getBlock(((to2 << 4) + (to1 >> 4)), (to1 & 0xf));
|
|
||||||
if (lastTo != null && FaweCache.hasNBT(to.getId())) {
|
|
||||||
Map<String, Tag> t = lastTo.getValue();
|
|
||||||
if (((IntTag) t.get("x")).getValue() == x && ((IntTag) t.get("z")).getValue() == z && ((IntTag) t.get("y")).getValue() == y) {
|
|
||||||
to = new BaseBlock(to.getId(), to.getData());
|
|
||||||
to.setNbtData(lastTo);
|
|
||||||
lastTo = read(lastToIter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockVector position = new BlockVector(x, y, z);
|
|
||||||
return dir ? new BlockChange(position, to, from) : new BlockChange(position, from, to);
|
|
||||||
} catch (Exception ignore) {}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
if (last != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
gis.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Change next() {
|
|
||||||
Change tmp = last;
|
|
||||||
last = read();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new IllegalArgumentException("CANNOT REMOVE");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return Iterators.concat(idsIterator, entsIterator);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return new ArrayList<Change>().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Change> backwardIterator() {
|
|
||||||
return getIterator(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Change> forwardIterator() {
|
|
||||||
return getIterator(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean flush() {
|
public boolean flush() {
|
||||||
if (idsStreamZip != null) {
|
if (idsStreamZip != null) {
|
||||||
@ -285,7 +34,7 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet {
|
|||||||
idsStream.flush();
|
idsStream.flush();
|
||||||
idsStreamZip.flush();
|
idsStreamZip.flush();
|
||||||
idsStreamZip.close();
|
idsStreamZip.close();
|
||||||
ids = idsStream.toByteArray();
|
ids = idsStream.toByteArray(true);
|
||||||
idsStream = null;
|
idsStream = null;
|
||||||
idsStreamZip = null;
|
idsStreamZip = null;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -301,4 +50,75 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet {
|
|||||||
return ids == null ? 0 : ids.length;
|
return ids == null ? 0 : ids.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] ids;
|
||||||
|
private FastByteArrayOutputStream idsStream;
|
||||||
|
private OutputStream idsStreamZip;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getBlockOS(int x, int y, int z) throws IOException {
|
||||||
|
if (idsStreamZip != null) {
|
||||||
|
return idsStreamZip;
|
||||||
|
}
|
||||||
|
LZ4Factory factory = LZ4Factory.fastestInstance();
|
||||||
|
idsStream = new FastByteArrayOutputStream(Settings.BUFFER_SIZE);
|
||||||
|
idsStreamZip = new LZ4OutputStream(idsStream, Settings.BUFFER_SIZE, factory.fastCompressor());
|
||||||
|
if (Settings.COMPRESSION_LEVEL > 0) {
|
||||||
|
idsStreamZip = new LZ4OutputStream(idsStreamZip, Settings.BUFFER_SIZE, factory.highCompressor());
|
||||||
|
}
|
||||||
|
setOrigin(x, z);
|
||||||
|
return idsStreamZip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getEntityCreateOS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getEntityRemoveOS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getTileCreateOS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTOutputStream getTileRemoveOS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBlockIS() {
|
||||||
|
if (ids == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
InputStream is = new ByteArrayInputStream(ids);
|
||||||
|
is = new LZ4InputStream(is);
|
||||||
|
if (Settings.COMPRESSION_LEVEL > 0) {
|
||||||
|
is = new LZ4InputStream(is);
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTInputStream getEntityCreateIS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTInputStream getEntityRemoveIS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTInputStream getTileCreateIS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTInputStream getTileRemoveIS() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,12 @@ package com.boydti.fawe.object.extent;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.DoubleTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.BlockVector;
|
import com.sk89q.worldedit.BlockVector;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
@ -18,6 +23,7 @@ import com.sk89q.worldedit.util.Location;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class FastWorldEditExtent extends AbstractDelegateExtent {
|
public class FastWorldEditExtent extends AbstractDelegateExtent {
|
||||||
|
|
||||||
@ -28,15 +34,24 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
|
|||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FaweQueue getQueue() {
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity createEntity(final Location location, final BaseEntity entity) {
|
public Entity createEntity(final Location loc, final BaseEntity entity) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
TaskManager.IMP.task(new Runnable() {
|
CompoundTag tag = entity.getNbtData();
|
||||||
@Override
|
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
|
||||||
public void run() {
|
map.put("Id", new StringTag(entity.getTypeId()));
|
||||||
FastWorldEditExtent.super.createEntity(location, entity);
|
ListTag pos = (ListTag) map.get("Pos");
|
||||||
}
|
if (pos != null) {
|
||||||
});
|
List<Tag> posList = ReflectionUtils.getList(pos.getValue());
|
||||||
|
posList.set(0, new DoubleTag(loc.getX()));
|
||||||
|
posList.set(1, new DoubleTag(loc.getY()));
|
||||||
|
posList.set(2, new DoubleTag(loc.getZ()));
|
||||||
|
}
|
||||||
|
queue.setEntity(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), tag);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -138,89 +153,10 @@ public class FastWorldEditExtent extends AbstractDelegateExtent {
|
|||||||
case 151:
|
case 151:
|
||||||
case 178: {
|
case 178: {
|
||||||
if (block.hasNbtData()) {
|
if (block.hasNbtData()) {
|
||||||
final Vector loc = new Vector(location.x, location.y, location.z);
|
CompoundTag nbt = block.getNbtData();
|
||||||
queue.addTask(x >> 4, z >> 4, new Runnable() {
|
queue.setTile(x, y, z, nbt);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
FastWorldEditExtent.super.setBlock(loc, block);
|
|
||||||
} catch (WorldEditException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
queue.setBlock(x, y, z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0);
|
queue.setBlock(x, y, z, id, (byte) block.getData());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
case 14:
|
|
||||||
case 15:
|
|
||||||
case 20:
|
|
||||||
case 21:
|
|
||||||
case 22:
|
|
||||||
case 30:
|
|
||||||
case 32:
|
|
||||||
case 37:
|
|
||||||
case 39:
|
|
||||||
case 40:
|
|
||||||
case 41:
|
|
||||||
case 42:
|
|
||||||
case 45:
|
|
||||||
case 46:
|
|
||||||
case 47:
|
|
||||||
case 48:
|
|
||||||
case 49:
|
|
||||||
case 51:
|
|
||||||
case 56:
|
|
||||||
case 57:
|
|
||||||
case 58:
|
|
||||||
case 60:
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
case 10:
|
|
||||||
case 11:
|
|
||||||
case 73:
|
|
||||||
case 74:
|
|
||||||
case 78:
|
|
||||||
case 79:
|
|
||||||
case 80:
|
|
||||||
case 81:
|
|
||||||
case 82:
|
|
||||||
case 83:
|
|
||||||
case 85:
|
|
||||||
case 87:
|
|
||||||
case 88:
|
|
||||||
case 101:
|
|
||||||
case 102:
|
|
||||||
case 103:
|
|
||||||
case 110:
|
|
||||||
case 112:
|
|
||||||
case 113:
|
|
||||||
case 121:
|
|
||||||
case 122:
|
|
||||||
case 129:
|
|
||||||
case 133:
|
|
||||||
case 165:
|
|
||||||
case 166:
|
|
||||||
case 169:
|
|
||||||
case 170:
|
|
||||||
case 172:
|
|
||||||
case 173:
|
|
||||||
case 174:
|
|
||||||
case 181:
|
|
||||||
case 182:
|
|
||||||
case 188:
|
|
||||||
case 189:
|
|
||||||
case 190:
|
|
||||||
case 191:
|
|
||||||
case 192: {
|
|
||||||
queue.setBlock(x, y, z, id, (byte) 0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -73,16 +73,23 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toByteArray() {
|
public byte[] toByteArray() {
|
||||||
|
return toByteArray(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray(boolean delete) {
|
||||||
byte[] data = new byte[getSize()];
|
byte[] data = new byte[getSize()];
|
||||||
|
|
||||||
// Check if we have a list of buffers
|
// Check if we have a list of buffers
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
buffer = null;
|
||||||
if (buffers != null) {
|
if (buffers != null) {
|
||||||
Iterator iter = buffers.iterator();
|
Iterator iter = buffers.iterator();
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
byte[] bytes = (byte[])iter.next();
|
byte[] bytes = (byte[])iter.next();
|
||||||
|
if (delete) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
System.arraycopy(bytes, 0, data, pos, blockSize);
|
System.arraycopy(bytes, 0, data, pos, blockSize);
|
||||||
pos += blockSize;
|
pos += blockSize;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ package com.boydti.fawe.util;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.FaweChunk;
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -15,6 +17,7 @@ public abstract class FaweQueue {
|
|||||||
public final String world;
|
public final String world;
|
||||||
public LinkedBlockingDeque<EditSession> sessions;
|
public LinkedBlockingDeque<EditSession> sessions;
|
||||||
public long modified = System.currentTimeMillis();
|
public long modified = System.currentTimeMillis();
|
||||||
|
public RunnableVal2<FaweChunk, FaweChunk> changeTask;
|
||||||
|
|
||||||
public FaweQueue(String world) {
|
public FaweQueue(String world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
@ -34,10 +37,22 @@ public abstract class FaweQueue {
|
|||||||
return sessions == null ? new HashSet<EditSession>() : new HashSet<>(sessions);
|
return sessions == null ? new HashSet<EditSession>() : new HashSet<>(sessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChangeTask(RunnableVal2<FaweChunk, FaweChunk> changeTask) {
|
||||||
|
this.changeTask = changeTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RunnableVal2<FaweChunk, FaweChunk> getChangeTask() {
|
||||||
|
return changeTask;
|
||||||
|
}
|
||||||
|
|
||||||
public void optimize() {}
|
public void optimize() {}
|
||||||
|
|
||||||
public abstract boolean setBlock(final int x, final int y, final int z, final short id, final byte data);
|
public abstract boolean setBlock(final int x, final int y, final int z, final short id, final byte data);
|
||||||
|
|
||||||
|
public abstract void setTile(int x, int y, int z, CompoundTag tag);
|
||||||
|
|
||||||
|
public abstract void setEntity(int x, int y, int z, CompoundTag tag);
|
||||||
|
|
||||||
public abstract boolean setBiome(final int x, final int z, final BaseBiome biome);
|
public abstract boolean setBiome(final int x, final int z, final BaseBiome biome);
|
||||||
|
|
||||||
public abstract FaweChunk<?> getChunk(int x, int z);
|
public abstract FaweChunk<?> getChunk(int x, int z);
|
||||||
@ -88,7 +103,9 @@ public abstract class FaweQueue {
|
|||||||
*/
|
*/
|
||||||
public abstract void clear();
|
public abstract void clear();
|
||||||
|
|
||||||
public abstract void addTask(int x, int z, Runnable runnable);
|
public abstract void addNotifyTask(int x, int z, Runnable runnable);
|
||||||
|
|
||||||
|
public abstract void addNotifyTask(Runnable runnable);
|
||||||
|
|
||||||
public abstract int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException;
|
public abstract int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException;
|
||||||
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
package com.boydti.fawe.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TPS and Lag Checker.
|
|
||||||
*/
|
|
||||||
public class Lag implements Runnable {
|
|
||||||
/**
|
|
||||||
* Ticks
|
|
||||||
*/
|
|
||||||
public static final long[] T = new long[600];
|
|
||||||
/**
|
|
||||||
* Tick count
|
|
||||||
*/
|
|
||||||
public static int TC = 0;
|
|
||||||
/**
|
|
||||||
* something :_:
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public static long LT = 0L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the server TPS
|
|
||||||
*
|
|
||||||
* @return server tick per second
|
|
||||||
*/
|
|
||||||
public static double getTPS() {
|
|
||||||
return Math.round(getTPS(100)) > 20.0D ? 20.0D : Math.round(getTPS(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the tick per second (measured in $ticks)
|
|
||||||
*
|
|
||||||
* @param ticks Ticks
|
|
||||||
*
|
|
||||||
* @return ticks per second
|
|
||||||
*/
|
|
||||||
public static double getTPS(final int ticks) {
|
|
||||||
if (TC < ticks) {
|
|
||||||
return 20.0D;
|
|
||||||
}
|
|
||||||
final int t = (TC - 1 - ticks) % T.length;
|
|
||||||
final long e = System.currentTimeMillis() - T[t];
|
|
||||||
return ticks / (e / 1000.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get number of ticks since
|
|
||||||
*
|
|
||||||
* @param tI Ticks <
|
|
||||||
*
|
|
||||||
* @return number of ticks since $tI
|
|
||||||
*/
|
|
||||||
public static long getElapsed(final int tI) {
|
|
||||||
final long t = T[tI % T.length];
|
|
||||||
return System.currentTimeMillis() - t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get lag percentage
|
|
||||||
*
|
|
||||||
* @return lag percentage
|
|
||||||
*/
|
|
||||||
public static double getPercentage() {
|
|
||||||
return Math.round((1.0D - (Lag.getTPS() / 20.0D)) * 100.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get TPS percentage (of 20)
|
|
||||||
*
|
|
||||||
* @return TPS percentage
|
|
||||||
*/
|
|
||||||
public static double getFullPercentage() {
|
|
||||||
return getTPS() * 5.0D;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
T[TC % T.length] = System.currentTimeMillis();
|
|
||||||
TC++;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,14 +5,20 @@ import com.boydti.fawe.config.BBC;
|
|||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.DoubleTag;
|
||||||
import com.sk89q.jnbt.EndTag;
|
import com.sk89q.jnbt.EndTag;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.util.Location;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
@ -39,7 +45,27 @@ public class MainUtil {
|
|||||||
Fawe.debug(s);
|
Fawe.debug(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendCompressedMessage(FaweChangeSet set, Actor actor)
|
public static void setPosition(CompoundTag tag, int x, int y, int z) {
|
||||||
|
Map<String, Tag> value = ReflectionUtils.getMap(tag.getValue());
|
||||||
|
value.put("x", new IntTag(x));
|
||||||
|
value.put("y", new IntTag(y));
|
||||||
|
value.put("z", new IntTag(z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEntityInfo(CompoundTag tag, Entity entity) {
|
||||||
|
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
|
||||||
|
map.put("Id", new StringTag(entity.getState().getTypeId()));
|
||||||
|
ListTag pos = (ListTag) map.get("Pos");
|
||||||
|
if (pos != null) {
|
||||||
|
Location loc = entity.getLocation();
|
||||||
|
List<Tag> posList = ReflectionUtils.getList(pos.getValue());
|
||||||
|
posList.set(0, new DoubleTag(loc.getX()));
|
||||||
|
posList.set(1, new DoubleTag(loc.getY()));
|
||||||
|
posList.set(2, new DoubleTag(loc.getZ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendCompressedMessage(FaweStreamChangeSet set, Actor actor)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
int elements = set.size();
|
int elements = set.size();
|
||||||
|
@ -43,6 +43,18 @@ public class MathMan {
|
|||||||
253, 254, 254, 255
|
253, 254, 254, 255
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static byte pair16(byte x, byte y) {
|
||||||
|
return (byte) (x + (y << 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte unpair16x(byte value) {
|
||||||
|
return (byte) (value & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte unpair16y(byte value) {
|
||||||
|
return (byte) ((value >> 4) & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
public static int sqrt(int x) {
|
public static int sqrt(int x) {
|
||||||
int xn;
|
int xn;
|
||||||
|
|
||||||
|
@ -58,17 +58,29 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, V> Map<T, V> getMap(Map<T, V> map) {
|
public static <T, V> Map<T, V> getMap(Map<T, V> map) {
|
||||||
try {
|
try {
|
||||||
Class<? extends Map> clazz = map.getClass();
|
Class<? extends Map> clazz = map.getClass();
|
||||||
Field m = clazz.getDeclaredField("m");
|
Field m = clazz.getDeclaredField("m");
|
||||||
m.setAccessible(true);
|
m.setAccessible(true);
|
||||||
return (Map<T, V>) m.get(map);
|
return (Map<T, V>) m.get(map);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return map;
|
return map;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> getList(List<T> list) {
|
||||||
|
try {
|
||||||
|
Class<? extends List> clazz = (Class<? extends List>) Class.forName("java.util.Collections$UnmodifiableList");
|
||||||
|
Field m = clazz.getDeclaredField("list");
|
||||||
|
m.setAccessible(true);
|
||||||
|
return (List<T>) m.get(list);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> getNmsClass(final String name) {
|
public static Class<?> getNmsClass(final String name) {
|
||||||
final String className = "net.minecraft.server." + getVersion() + "." + name;
|
final String className = "net.minecraft.server." + getVersion() + "." + name;
|
||||||
|
@ -15,6 +15,10 @@ public class SetQueue {
|
|||||||
*/
|
*/
|
||||||
public static final SetQueue IMP = new SetQueue();
|
public static final SetQueue IMP = new SetQueue();
|
||||||
|
|
||||||
|
public static enum QueueStage {
|
||||||
|
INACTIVE, ACTIVE, NONE;
|
||||||
|
}
|
||||||
|
|
||||||
public final LinkedBlockingDeque<FaweQueue> activeQueues;
|
public final LinkedBlockingDeque<FaweQueue> activeQueues;
|
||||||
public final LinkedBlockingDeque<FaweQueue> inactiveQueues;
|
public final LinkedBlockingDeque<FaweQueue> inactiveQueues;
|
||||||
|
|
||||||
@ -113,6 +117,27 @@ public class SetQueue {
|
|||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueueStage getStage(FaweQueue queue) {
|
||||||
|
if (activeQueues.contains(queue)) {
|
||||||
|
return QueueStage.ACTIVE;
|
||||||
|
} else if (inactiveQueues.contains(queue)) {
|
||||||
|
return QueueStage.INACTIVE;
|
||||||
|
}
|
||||||
|
return QueueStage.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStage(FaweQueue queue, QueueStage stage) {
|
||||||
|
switch (stage) {
|
||||||
|
case ACTIVE:
|
||||||
|
return activeQueues.contains(queue);
|
||||||
|
case INACTIVE:
|
||||||
|
return inactiveQueues.contains(queue);
|
||||||
|
case NONE:
|
||||||
|
return !activeQueues.contains(queue) && !inactiveQueues.contains(queue);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void enqueue(FaweQueue queue) {
|
public void enqueue(FaweQueue queue) {
|
||||||
inactiveQueues.remove(queue);
|
inactiveQueues.remove(queue);
|
||||||
if (queue.size() > 0 && !activeQueues.contains(queue)) {
|
if (queue.size() > 0 && !activeQueues.contains(queue)) {
|
||||||
|
@ -304,7 +304,7 @@ public class WorldWrapper extends AbstractWorld {
|
|||||||
try {
|
try {
|
||||||
final BaseBlock block = getBlock(loc);
|
final BaseBlock block = getBlock(loc);
|
||||||
final Vector v = new Vector(loc.x, loc.y, loc.z);
|
final Vector v = new Vector(loc.x, loc.y, loc.z);
|
||||||
queue.addTask(cx, cz, new Runnable() {
|
queue.addNotifyTask(cx, cz, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
@ -327,7 +327,11 @@ public class EditSession implements Extent {
|
|||||||
|
|
||||||
// History
|
// History
|
||||||
this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, actor.getUniqueId()) : new MemoryOptimizedHistory(actor);
|
this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, actor.getUniqueId()) : new MemoryOptimizedHistory(actor);
|
||||||
extent = this.wrapper.getHistoryExtent(this, limit, extent, this.changeSet, queue, fp);
|
if (Settings.COMBINE_HISTORY_STAGE) {
|
||||||
|
changeSet.addChangeTask(queue);
|
||||||
|
} else {
|
||||||
|
extent = this.wrapper.getHistoryExtent(this, limit, extent, this.changeSet, queue, fp);
|
||||||
|
}
|
||||||
|
|
||||||
// Region restrictions if mask is not null
|
// Region restrictions if mask is not null
|
||||||
if (mask != null) {
|
if (mask != null) {
|
||||||
@ -875,7 +879,7 @@ public class EditSession implements Extent {
|
|||||||
editSession.flushQueue();
|
editSession.flushQueue();
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
editSession.changes = changes;
|
editSession.changes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -892,7 +896,7 @@ public class EditSession implements Extent {
|
|||||||
editSession.flushQueue();
|
editSession.flushQueue();
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
editSession.changes = changes;
|
editSession.changes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||||
|
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
import com.boydti.fawe.util.FaweQueue;
|
import com.boydti.fawe.util.FaweQueue;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
@ -80,7 +82,7 @@ public class LocalSession {
|
|||||||
private transient RegionSelector selector = new CuboidRegionSelector();
|
private transient RegionSelector selector = new CuboidRegionSelector();
|
||||||
private transient boolean placeAtPos1 = false;
|
private transient boolean placeAtPos1 = false;
|
||||||
private transient List<EditSession> history = Collections.synchronizedList(new LinkedList<EditSession>());
|
private transient List<EditSession> history = Collections.synchronizedList(new LinkedList<EditSession>());
|
||||||
private transient int historyPointer = 0;
|
private transient volatile int historyPointer = 0;
|
||||||
private transient ClipboardHolder clipboard;
|
private transient ClipboardHolder clipboard;
|
||||||
private transient boolean toolControl = true;
|
private transient boolean toolControl = true;
|
||||||
private transient boolean superPickaxe = false;
|
private transient boolean superPickaxe = false;
|
||||||
@ -200,7 +202,7 @@ public class LocalSession {
|
|||||||
remember(editSession, true);
|
remember(editSession, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remember(EditSession editSession, boolean append) {
|
public void remember(final EditSession editSession, final boolean append) {
|
||||||
// Enqueue it
|
// Enqueue it
|
||||||
if (editSession.getQueue() != null) {
|
if (editSession.getQueue() != null) {
|
||||||
FaweQueue queue = editSession.getQueue();
|
FaweQueue queue = editSession.getQueue();
|
||||||
@ -217,12 +219,25 @@ public class LocalSession {
|
|||||||
history.remove(historyPointer);
|
history.remove(historyPointer);
|
||||||
}
|
}
|
||||||
ChangeSet set = editSession.getChangeSet();
|
ChangeSet set = editSession.getChangeSet();
|
||||||
if (set instanceof FaweChangeSet) {
|
if (set instanceof FaweStreamChangeSet) {
|
||||||
FaweChangeSet fcs = (FaweChangeSet) set;
|
final FaweStreamChangeSet fcs = (FaweStreamChangeSet) set;
|
||||||
if (fcs.flush() && append) {
|
if (Settings.COMBINE_HISTORY_STAGE) {
|
||||||
MainUtil.sendCompressedMessage(fcs, editSession.actor);
|
editSession.getQueue().addNotifyTask(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (fcs.flush() && append) {
|
||||||
|
MainUtil.sendCompressedMessage(fcs, editSession.actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (fcs.flush() && append) {
|
||||||
|
MainUtil.sendCompressedMessage(fcs, editSession.actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (set instanceof FaweChangeSet) {
|
||||||
|
((FaweChangeSet) set).flush();
|
||||||
}
|
}
|
||||||
if (append) {
|
if (append) {
|
||||||
history.add(editSession);
|
history.add(editSession);
|
||||||
@ -232,7 +247,7 @@ public class LocalSession {
|
|||||||
while (history.size() > MAX_HISTORY_SIZE) {
|
while (history.size() > MAX_HISTORY_SIZE) {
|
||||||
history.remove(0);
|
history.remove(0);
|
||||||
}
|
}
|
||||||
historyPointer = history.size();
|
historyPointer = append ? history.size() : historyPointer + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -263,6 +278,7 @@ public class LocalSession {
|
|||||||
newEditSession.enableQueue();
|
newEditSession.enableQueue();
|
||||||
newEditSession.setFastMode(fastMode);
|
newEditSession.setFastMode(fastMode);
|
||||||
editSession.undo(newEditSession);
|
editSession.undo(newEditSession);
|
||||||
|
System.out.println("UNDO: " + historyPointer + " | " + history.size());
|
||||||
return editSession;
|
return editSession;
|
||||||
} else {
|
} else {
|
||||||
historyPointer = 0;
|
historyPointer = 0;
|
||||||
@ -290,6 +306,7 @@ public class LocalSession {
|
|||||||
*/
|
*/
|
||||||
public EditSession redo(@Nullable BlockBag newBlockBag, Player player) {
|
public EditSession redo(@Nullable BlockBag newBlockBag, Player player) {
|
||||||
checkNotNull(player);
|
checkNotNull(player);
|
||||||
|
System.out.println("CHECK REDO: " + historyPointer + " | " + history.size());
|
||||||
if (historyPointer < history.size()) {
|
if (historyPointer < history.size()) {
|
||||||
EditSession editSession = history.get(historyPointer);
|
EditSession editSession = history.get(historyPointer);
|
||||||
EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
|
EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
|
||||||
@ -298,7 +315,10 @@ public class LocalSession {
|
|||||||
newEditSession.setFastMode(fastMode);
|
newEditSession.setFastMode(fastMode);
|
||||||
editSession.redo(newEditSession);
|
editSession.redo(newEditSession);
|
||||||
++historyPointer;
|
++historyPointer;
|
||||||
|
System.out.println("CAN REDO");
|
||||||
return editSession;
|
return editSession;
|
||||||
|
} else {
|
||||||
|
System.out.println("POINTER");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -224,6 +224,7 @@ public final class CommandManager {
|
|||||||
TaskManager.IMP.async(new Runnable() {
|
TaskManager.IMP.async(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
System.out.println("COMMAND START!");
|
||||||
final Actor actor = platformManager.createProxyActor(event.getActor());
|
final Actor actor = platformManager.createProxyActor(event.getActor());
|
||||||
String[] split = commandDetection(event.getArguments().split(" "));
|
String[] split = commandDetection(event.getArguments().split(" "));
|
||||||
|
|
||||||
@ -284,6 +285,7 @@ public final class CommandManager {
|
|||||||
log.log(Level.SEVERE, "An unknown error occurred", e);
|
log.log(Level.SEVERE, "An unknown error occurred", e);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
System.out.println("DONE!");
|
||||||
if (fp != null) {
|
if (fp != null) {
|
||||||
fp.deleteMeta("fawe_action");
|
fp.deleteMeta("fawe_action");
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ public class ChangeSetExecutor implements Operation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Operation resume(RunContext run) throws WorldEditException {
|
public Operation resume(RunContext run) throws WorldEditException {
|
||||||
int size = 0;
|
|
||||||
if (type == Type.UNDO) {
|
if (type == Type.UNDO) {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
iterator.next().undo(context);
|
iterator.next().undo(context);
|
||||||
|
144
pom.xml
144
pom.xml
@ -12,53 +12,94 @@
|
|||||||
<name>FastAsyncWorldEdit</name>
|
<name>FastAsyncWorldEdit</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<build>
|
<build>
|
||||||
<finalName>FastAsyncWorldEdit-Bukkit-${project.version}</finalName>
|
<finalName>FastAsyncWorldEdit-UBER-${project.version}</finalName>
|
||||||
<sourceDirectory>Bukkit/src/main/java</sourceDirectory>
|
<sourceDirectory>core/src/main/java</sourceDirectory>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<filtering>true</filtering>
|
<filtering>false</filtering>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*.*</include>
|
<include>**/*.*</include>
|
||||||
</includes>
|
</includes>
|
||||||
<directory>bukkit/src/main/resources/</directory>
|
<directory>bukkit19/src/main/resources/</directory>
|
||||||
</resource>
|
</resource>
|
||||||
<resource>
|
<resource>
|
||||||
<filtering>false</filtering>
|
<filtering>false</filtering>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*.*</include>
|
<include>**/*.*</include>
|
||||||
</includes>
|
</includes>
|
||||||
<directory>core/src/main/resources/</directory>
|
<directory>bukkit18/src/main/resources/</directory>
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<version>2.3.2</version>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<configuration>
|
<version>2.6</version>
|
||||||
<excludes>
|
<executions>
|
||||||
<exclude>**/forge/src/main/**/*.*</exclude>
|
<execution>
|
||||||
</excludes>
|
<goals>
|
||||||
<source>1.7</source>
|
<goal>jar</goal>
|
||||||
<target>1.7</target>
|
</goals>
|
||||||
</configuration>
|
<id>Bukkit19</id>
|
||||||
</plugin>
|
<configuration>
|
||||||
<plugin>
|
<finalName>FastAsyncWorldEdit-Bukkit19-${project.version}</finalName>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<excludes>
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
<exclude>**/forge180/src/main/**/*.*</exclude>
|
||||||
<executions>
|
<exclude>**/forge1710/src/main/**/*.*</exclude>
|
||||||
<execution>
|
<exclude>com/boydti/fawe/bukkit/v1_8/**/*.*</exclude>
|
||||||
<phase>generate-sources</phase>
|
</excludes>
|
||||||
<goals>
|
</configuration>
|
||||||
<goal>add-source</goal>
|
</execution>
|
||||||
</goals>
|
<execution>
|
||||||
<configuration>
|
<goals>
|
||||||
<sources>
|
<goal>jar</goal>
|
||||||
<source>core/src/main/java</source>
|
</goals>
|
||||||
</sources>
|
<id>Bukkit18</id>
|
||||||
</configuration>
|
<configuration>
|
||||||
</execution>
|
<finalName>FastAsyncWorldEdit-Bukkit18-${project.version}</finalName>
|
||||||
</executions>
|
<excludes>
|
||||||
</plugin>
|
<exclude>**/forge180/src/main/**/*.*</exclude>
|
||||||
|
<exclude>**/forge1710/src/main/**/*.*</exclude>
|
||||||
|
<exclude>com/boydti/fawe/bukkit/v1_9/**/*.*</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>2.3.2</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.7</source>
|
||||||
|
<target>1.7</target>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/forge180/src/main/**/*.*</exclude>
|
||||||
|
<exclude>**/forge1710/src/main/**/*.*</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-source</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>add-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>bukkit0/src/main/java</source>
|
||||||
|
<source>bukkit18/src/main/java</source>
|
||||||
|
<source>bukkit19/src/main/java</source>
|
||||||
|
</sources>
|
||||||
|
<compilerArgument>-proc:none</compilerArgument>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -114,6 +155,16 @@
|
|||||||
<artifactId>bukkit</artifactId>
|
<artifactId>bukkit</artifactId>
|
||||||
<version>1.9-R0.1-SNAPSHOT</version>
|
<version>1.9-R0.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit.craftbukkit.v1_8</groupId>
|
||||||
|
<artifactId>craftbukkitv1_8</artifactId>
|
||||||
|
<version>1.8.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bukkit.craftbukkit</groupId>
|
||||||
|
<artifactId>CraftBukkit</artifactId>
|
||||||
|
<version>1.9.2</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.PrimeSoft</groupId>
|
<groupId>org.PrimeSoft</groupId>
|
||||||
<artifactId>blockshub</artifactId>
|
<artifactId>blockshub</artifactId>
|
||||||
@ -129,6 +180,11 @@
|
|||||||
<artifactId>factions</artifactId>
|
<artifactId>factions</artifactId>
|
||||||
<version>1.6.9.5</version>
|
<version>1.6.9.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.factionsone</groupId>
|
||||||
|
<artifactId>FactionsOne</artifactId>
|
||||||
|
<version>1.2.2</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.ryanhamshire</groupId>
|
<groupId>me.ryanhamshire</groupId>
|
||||||
<artifactId>GriefPrevention</artifactId>
|
<artifactId>GriefPrevention</artifactId>
|
||||||
|
Loading…
Reference in New Issue
Block a user