Various fixes

Fix undo
Fix blockshub hook
API improvements
Added worldedit from console
Fixed async world loading for paperspigot
Some minor optimizations
Added some extra translations
This commit is contained in:
Jesse Boyd 2016-07-12 17:54:00 +10:00
parent 9ed6880d1d
commit 87f79f9fa6
42 changed files with 558 additions and 679 deletions

View File

@ -38,6 +38,7 @@ subprojects {
}
compile 'com.sk89q:worldguard:6.0.0-SNAPSHOT'
compile 'com.plotsquared:PlotSquared:3.4.1-SNAPSHOT'
compile 'org.primesoft:BlocksHub:2.0'
}
repositories {

View File

@ -1,11 +1,9 @@
package com.boydti.fawe.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.sk89q.worldedit.EditSession;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Sniper;
import org.bukkit.Bukkit;
@ -54,6 +52,4 @@ public abstract class ABukkitMain extends JavaPlugin {
}
public abstract FaweQueue getQueue(String world);
public abstract EditSessionWrapper getEditSessionWrapper(EditSession session);
}

View File

@ -15,16 +15,14 @@ import com.boydti.fawe.bukkit.regions.Worldguard;
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
import com.boydti.fawe.bukkit.v0.ChunkListener;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.world.World;
import java.io.File;
@ -41,6 +39,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import org.primesoft.blockshub.BlocksHubBukkit;
public class FaweBukkit implements IFawe, Listener {
@ -220,14 +219,6 @@ public class FaweBukkit implements IFawe, Listener {
return world.getName();
}
/**
* The EditSessionWrapper should have the same functionality as the normal EditSessionWrapper but with some optimizations
*/
@Override
public EditSessionWrapper getEditSessionWrapper(final EditSession session) {
return plugin.getEditSessionWrapper(session);
}
/**
* A mask manager handles region restrictions e.g. PlotSquared plots / WorldGuard regions
*/
@ -343,4 +334,19 @@ public class FaweBukkit implements IFawe, Listener {
public String getName(UUID uuid) {
return Bukkit.getOfflinePlayer(uuid).getName();
}
private boolean enabledBlocksHub = true;
@Override
public Object getBlocksHubApi() {
if (!enabledBlocksHub) {
return null;
}
Plugin blocksHubPlugin = Bukkit.getPluginManager().getPlugin("BlocksHub");
if (blocksHubPlugin == null) {
enabledBlocksHub = false;
return null;
}
return ((BlocksHubBukkit) blocksHubPlugin).getApi();
}
}

View File

@ -1,22 +0,0 @@
package com.boydti.fawe.bukkit.logging;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import org.PrimeSoft.blocksHub.BlocksHub;
import org.PrimeSoft.blocksHub.IBlocksHubApi;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class BlocksHubHook {
private final BlocksHub hub;
private final IBlocksHubApi api;
public BlocksHubHook() {
this.hub = (BlocksHub) Bukkit.getServer().getPluginManager().getPlugin("BlocksHub");
this.api = this.hub.getApi();
}
public FaweChangeSet getLoggingChangeSet(FaweChangeSet set, FawePlayer<?> player) {
return new LoggingChangeSet((FawePlayer<Player>) player, set, api);
}
}

View File

@ -1,73 +0,0 @@
package com.boydti.fawe.bukkit.logging;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.history.change.Change;
import java.util.Iterator;
import org.PrimeSoft.blocksHub.IBlocksHubApi;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
public class LoggingChangeSet extends FaweChangeSet {
private final FaweChangeSet parent;
private final IBlocksHubApi api;
private final World world;
private final Location loc;
private final String name;
public LoggingChangeSet(FawePlayer<Player> player, FaweChangeSet parent, IBlocksHubApi api) {
super(parent.getWorld());
this.parent = parent;
this.name = player.getName();
this.api = api;
this.world = player.parent.getWorld();
this.loc = new Location(world, 0, 0, 0);
}
@Override
public boolean flush() {
return parent.flush();
}
@Override
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
loc.setX(x);
loc.setY(y);
loc.setZ(z);
api.logBlock(name, world, loc, combinedId4DataFrom >> 4, (byte) (combinedId4DataFrom & 0xF), combinedId4DataTo >> 4, (byte) (combinedId4DataTo & 0xF));
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
}
@Override
public void addTileCreate(CompoundTag tag) {
parent.addTileCreate(tag);
}
@Override
public void addTileRemove(CompoundTag tag) {
parent.addTileRemove(tag);
}
@Override
public void addEntityRemove(CompoundTag tag) {
parent.addEntityRemove(tag);
}
@Override
public void addEntityCreate(CompoundTag tag) {
parent.addEntityCreate(tag);
}
@Override
public Iterator<Change> getIterator(boolean undo) {
return parent.getIterator(undo);
}
@Override
public int size() {
return parent.size();
}
}

View File

@ -1,232 +0,0 @@
package com.boydti.fawe.bukkit.logging;
import com.boydti.fawe.object.FawePlayer;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.change.BlockChange;
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.regions.Region;
import com.sk89q.worldedit.util.Location;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.PrimeSoft.blocksHub.IBlocksHubApi;
import org.bukkit.World;
import org.bukkit.entity.Player;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Stores changes to a {@link com.sk89q.worldedit.history.changeset.ChangeSet}.
* Logs changes to BlocksHub
*/
public class LoggingExtent extends AbstractDelegateExtent {
private final ChangeSet changeSet;
private final IBlocksHubApi api;
private final String playerName;
private final World world;
private final org.bukkit.Location loc;
/**
* Create a new instance.
*
* @param extent the extent
* @param changeSet the change set
* @param api
* @param player
*/
public LoggingExtent(final Extent extent, final ChangeSet changeSet, final FawePlayer<Player> player, final IBlocksHubApi api) {
super(extent);
checkNotNull(changeSet);
this.changeSet = changeSet;
this.api = api;
this.playerName = player.getName();
this.world = player.parent.getWorld();
this.loc = new org.bukkit.Location(this.world, 0, 0, 0);
}
@Override
public synchronized boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException {
if (super.setBlock(location, block)) {
BaseBlock previous;
try {
previous = this.getBlock(location);
} catch (final Exception e) {
previous = this.getBlock(location);
}
final int id_p = previous.getId();
final int id_b = block.getId();
switch (id_p) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 25:
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 52:
case 54:
case 56:
case 57:
case 58:
case 60:
case 7:
case 11:
case 73:
case 74:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 188:
case 189:
case 190:
case 191:
case 192:
if (id_p == id_b) {
return false;
}
this.loc.setX(location.getX());
this.loc.setY(location.getY());
this.loc.setZ(location.getZ());
this.api.logBlock(this.playerName, this.world, this.loc, id_p, (byte) 0, id_b, (byte) 0);
break;
default:
final int data_p = previous.getData();
final int data_b = block.getData();
if ((id_p == id_b) && (data_b == data_p)) {
return false;
}
this.loc.setX(location.getX());
this.loc.setY(location.getY());
this.loc.setZ(location.getZ());
this.api.logBlock(this.playerName, this.world, this.loc, id_p, (byte) data_p, id_b, (byte) data_b);
break;
}
this.changeSet.add(new BlockChange(location.toBlockVector(), previous, block));
return true;
}
return false;
}
@Nullable
@Override
public Entity createEntity(final Location location, final BaseEntity state) {
final Entity entity = super.createEntity(location, state);
if (state != null) {
this.changeSet.add(new EntityCreate(location, state, entity));
}
return entity;
}
@Override
public List<? extends Entity> getEntities() {
return this.wrapEntities(super.getEntities());
}
@Override
public List<? extends Entity> getEntities(final Region region) {
return this.wrapEntities(super.getEntities(region));
}
private List<? extends Entity> wrapEntities(final List<? extends Entity> entities) {
final List<Entity> newList = new ArrayList<Entity>(entities.size());
for (final Entity entity : entities) {
newList.add(new TrackedEntity(entity));
}
return newList;
}
private class TrackedEntity implements Entity {
private final Entity entity;
private TrackedEntity(final Entity entity) {
this.entity = entity;
}
@Override
public BaseEntity getState() {
return this.entity.getState();
}
@Override
public Location getLocation() {
return this.entity.getLocation();
}
@Override
public Extent getExtent() {
return this.entity.getExtent();
}
@Override
public boolean remove() {
final Location location = this.entity.getLocation();
final BaseEntity state = this.entity.getState();
final boolean success = this.entity.remove();
if ((state != null) && success) {
LoggingExtent.this.changeSet.add(new EntityRemove(location, state));
}
return success;
}
@Nullable
@Override
public <T> T getFacet(final Class<? extends T> cls) {
return this.entity.getFacet(cls);
}
}
}

View File

@ -1,29 +0,0 @@
package com.boydti.fawe.bukkit.v0;
import com.boydti.fawe.bukkit.logging.BlocksHubHook;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.sk89q.worldedit.EditSession;
public class BukkitEditSessionWrapper_0 extends EditSessionWrapper {
private BlocksHubHook hook;
public BukkitEditSessionWrapper_0(final EditSession session) {
super(session);
try {
// Try to hook into BlocksHub
this.hook = new BlocksHubHook();
} catch (final Throwable ignore) {}
}
@Override
public FaweChangeSet wrapChangeSet(FaweChangeSet set, FawePlayer<?> player) {
if (this.hook != null) {
// If we are doing logging, use a custom logging ChangeSet
return hook.getLoggingChangeSet(set, player);
}
return set;
}
}

View File

@ -18,7 +18,6 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedDeque;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -56,7 +55,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public static void onChunkUnload(ChunkUnloadEvent event) {
ConcurrentLinkedDeque<FaweQueue> queues = SetQueue.IMP.activeQueues;
Collection<FaweQueue> queues = SetQueue.IMP.getActiveQueues();
if (queues.isEmpty()) {
return;
}

View File

@ -123,10 +123,8 @@ public class AsyncWorld implements World {
* @return
*/
public static AsyncWorld create(final WorldCreator creator) {
long start = System.currentTimeMillis();
BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(creator.name(), true, false);
World world = queue.createWorld(creator);
System.out.println(System.currentTimeMillis() - start);
return wrap(world);
}

View File

@ -1,20 +1,12 @@
package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitEditSessionWrapper_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.EditSessionWrapper;
import com.sk89q.worldedit.EditSession;
public class BukkitMain_110 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
return new BukkitQueue_1_10(world);
// return new BukkitQueue_All(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new BukkitEditSessionWrapper_0(session);
}
}

View File

@ -131,29 +131,32 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], DataP
final boolean hardcore = false;
final IDataManager sdm = new ServerNBTManager(server.getWorldContainer(), name, true, server.getHandle().getServer().getDataConverterManager());
WorldData worlddata = sdm.getWorldData();
WorldSettings worldSettings = null;
final WorldSettings worldSettings;
if (worlddata == null) {
worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(server.getDefaultGameMode().getValue()), generateStructures, hardcore, type);
worldSettings.setGeneratorSettings(creator.generatorSettings());
worlddata = new WorldData(worldSettings, name);
} else {
worldSettings = null;
}
worlddata.checkName(name);
final WorldServer internal = (WorldServer)new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b();
if (worldSettings != null) {
internal.a(worldSettings);
}
startSet(true); // Temporarily allow async chunk load since the world isn't added yet
internal.a(worldSettings);
endSet(true);
internal.scoreboard = server.getScoreboardManager().getMainScoreboard().getHandle();
internal.tracker = new EntityTracker(internal);
internal.addIWorldAccess(new WorldManager(console, internal));
internal.worldData.setDifficulty(EnumDifficulty.EASY);
internal.setSpawnFlags(true, true);
console.worlds.add(internal);
if (generator != null) {
internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld()));
}
// Add the world
return TaskManager.IMP.sync(new RunnableVal<World>() {
@Override
public void run(World value) {
console.worlds.add(internal);
server.getPluginManager().callEvent(new WorldInitEvent(internal.getWorld()));
server.getPluginManager().callEvent(new WorldLoadEvent(internal.getWorld()));
this.value = internal.getWorld();

View File

@ -1,10 +1,7 @@
package com.boydti.fawe.bukkit.v1_8;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitEditSessionWrapper_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.EditSessionWrapper;
import com.sk89q.worldedit.EditSession;
public class BukkitMain_18 extends ABukkitMain {
@ -12,9 +9,4 @@ public class BukkitMain_18 extends ABukkitMain {
public BukkitQueue_0 getQueue(String world) {
return new BukkitQueue18R3(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new BukkitEditSessionWrapper_0(session);
}
}

View File

@ -1,19 +1,11 @@
package com.boydti.fawe.bukkit.v1_9;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitEditSessionWrapper_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.EditSessionWrapper;
import com.sk89q.worldedit.EditSession;
public class BukkitMain_19 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
return new BukkitQueue_1_9_R1(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new BukkitEditSessionWrapper_0(session);
}
}

View File

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

View File

@ -182,7 +182,7 @@ public class Fawe {
MainUtil.deleteOlder(new File(IMP.getDirectory(), "clipboard"), TimeUnit.DAYS.toMillis(Settings.CLIPBOARD.DELETE_AFTER_DAYS));
TaskManager.IMP = this.IMP.getTaskManager();
TaskManager.IMP.repeat(timer = new FaweTimer(), 50);
TaskManager.IMP.repeat(timer = new FaweTimer(), 1);
if (Settings.METRICS) {
this.IMP.startMetrics();
}
@ -211,6 +211,10 @@ public class Fawe {
this.setupMemoryListener();
}
public FaweTimer getTimer() {
return timer;
}
public double getTPS() {
return timer.getTPS();
}

View File

@ -482,7 +482,7 @@ public class FaweAPI {
* @param whenDone
*/
public static void addTask(final Runnable whenDone) {
SetQueue.IMP.addTask(whenDone);
SetQueue.IMP.addEmptyTask(whenDone);
}
/**

View File

@ -1,12 +1,10 @@
package com.boydti.fawe;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.world.World;
import java.io.File;
import java.util.Collection;
@ -31,8 +29,6 @@ public interface IFawe {
public String getWorldName(World world);
public EditSessionWrapper getEditSessionWrapper(final EditSession session);
public Collection<FaweMaskManager> getMaskManagers();
public void startMetrics();
@ -42,4 +38,6 @@ public interface IFawe {
public UUID getUUID(String name);
public String getName(UUID uuid);
public Object getBlocksHubApi();
}

View File

@ -6,7 +6,7 @@ import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.SetQueue;
import com.sk89q.worldedit.EditSession;
import java.util.List;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
@ -22,7 +22,7 @@ public class Cancel extends FaweCommand {
return false;
}
UUID uuid = player.getUUID();
List<FaweQueue> queues = SetQueue.IMP.getAllQueues();
Collection<FaweQueue> queues = SetQueue.IMP.getAllQueues();
int cancelled = 0;
for (FaweQueue queue : queues) {
Set<EditSession> sessions = queue.getEditSessions();

View File

@ -103,6 +103,8 @@ public enum BBC {
SELECTOR_CUBOID_POS1("First position set to %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_CUBOID_POS2("Second position set to %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_INVALID_COORDINATES("Invalid coordinates %s0", "WorldEdit.Selector"),
SELECTOR_ALREADY_SET("Position already set.", "WorldEdit.Selector"),
COMMAND_INVALID_SYNTAX("The command was not used properly (no more help available).", "WorldEdit.Command"),

View File

@ -32,13 +32,13 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
mode = Settings.LIGHTING.FIX_ALL ? FaweQueue.RelightMode.OPTIMAL : FaweQueue.RelightMode.MINIMAL;
}
final RelightMode finalMode = mode;
TaskManager.IMP.taskSyncSoon(new Runnable() {
TaskManager.IMP.taskSoonMain(new Runnable() {
@Override
public void run() {
final long pair = fc.longHash();
relighting.put(pair, pair);
final boolean result = finalMode == RelightMode.NONE || fixLighting(fc, finalMode);
TaskManager.IMP.taskSyncNow(new Runnable() {
TaskManager.IMP.taskNowMain(new Runnable() {
@Override
public void run() {
if (!result) {

View File

@ -0,0 +1,99 @@
package com.boydti.fawe.logging;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.history.change.Change;
import java.util.Iterator;
import org.bukkit.entity.Player;
import org.primesoft.blockshub.IBlocksHubApi;
import org.primesoft.blockshub.api.IPlayer;
import org.primesoft.blockshub.api.IWorld;
public class LoggingChangeSet extends FaweChangeSet {
private static boolean initialized = false;
public static FaweChangeSet wrap(FawePlayer<Player> player, FaweChangeSet parent) {
if (!initialized) {
initialized = true;
api = (IBlocksHubApi) Fawe.imp().getBlocksHubApi();
}
if (api == null) {
return parent;
}
return new LoggingChangeSet(player, parent);
}
public static IBlocksHubApi api;
private final FaweChangeSet parent;
private final MutableVector loc;
private final IPlayer player;
private final IWorld world;
private final MutableBlockData oldBlock;
private final MutableBlockData newBlock;
private LoggingChangeSet(FawePlayer player, FaweChangeSet parent) {
super(parent.getWorld());
this.parent = parent;
this.world = api.getWorld(player.getLocation().world);
this.loc = new MutableVector();
this.oldBlock = new MutableBlockData();
this.newBlock = new MutableBlockData();
this.player = api.getPlayer(player.getUUID());
}
@Override
public boolean flush() {
return parent.flush();
}
@Override
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
// Mutable (avoids object creation)
loc.x = x;
loc.y = y;
loc.z = z;
oldBlock.id = FaweCache.getId(combinedId4DataFrom);
oldBlock.data = FaweCache.getData(combinedId4DataFrom);
newBlock.id = FaweCache.getId(combinedId4DataTo);
newBlock.data = FaweCache.getData(combinedId4DataTo);
// Log to BlocksHub and parent
api.logBlock(loc, player, world, oldBlock, newBlock);
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
}
@Override
public void addTileCreate(CompoundTag tag) {
parent.addTileCreate(tag);
}
@Override
public void addTileRemove(CompoundTag tag) {
parent.addTileRemove(tag);
}
@Override
public void addEntityRemove(CompoundTag tag) {
parent.addEntityRemove(tag);
}
@Override
public void addEntityCreate(CompoundTag tag) {
parent.addEntityCreate(tag);
}
@Override
public Iterator<Change> getIterator(boolean undo) {
return parent.getIterator(undo);
}
@Override
public int size() {
return parent.size();
}
}

View File

@ -0,0 +1,29 @@
package com.boydti.fawe.logging;
import org.primesoft.blockshub.api.BlockData;
public class MutableBlockData extends BlockData {
public int data;
public int id;
public MutableBlockData() {
super(0, 0);
this.id = 0;
this.data = 0;
}
@Override
public int getType() {
return id;
}
@Override
public int getData() {
return data;
}
@Override
public boolean isAir() {
return id == 0;
}
}

View File

@ -0,0 +1,47 @@
package com.boydti.fawe.logging;
import org.primesoft.blockshub.api.Vector;
public class MutableVector extends Vector {
public double x, y, z;
public MutableVector() {
super(0, 0, 0);
this.x = 0;
this.y = 0;
this.z = 0;
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getZ() {
return z;
}
public boolean equals(Object obj) {
if(!(obj instanceof Vector)) {
return false;
} else {
Vector v = (Vector)obj;
return this.x == v.getX() && this.z == v.getZ() && this.y == v.getY();
}
}
public int hashCode() {
byte hash = 3;
int hash1 = 59 * hash + (int)(Double.doubleToLongBits(this.x) ^ Double.doubleToLongBits(this.x) >>> 32);
hash1 = 59 * hash1 + (int)(Double.doubleToLongBits(this.y) ^ Double.doubleToLongBits(this.y) >>> 32);
hash1 = 59 * hash1 + (int)(Double.doubleToLongBits(this.z) ^ Double.doubleToLongBits(this.z) >>> 32);
return hash1;
}
}

View File

@ -1,121 +0,0 @@
package com.boydti.fawe.object;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
public class EditSessionWrapper {
public final EditSession session;
public EditSessionWrapper(final EditSession session) {
this.session = session;
}
public int getHighestTerrainBlock(final int x, final int z, final int minY, final int maxY, final boolean naturalOnly) {
Vector pt = new Vector(x, 0, z);
for (int y = maxY; y >= minY; --y) {
BaseBlock block = session.getLazyBlock(x, y, z);
final int id = block.getId();
int data;
switch (id) {
case 0: {
continue;
}
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 25:
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 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
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 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
return y;
default:
data = 0;
}
if (naturalOnly ? BlockType.isNaturalTerrainBlock(id, data) : !BlockType.canPassThrough(id, data)) {
return y;
}
}
return minY;
}
public FaweChangeSet wrapChangeSet(FaweChangeSet set, FawePlayer<?> player) {
return set;
}
}

View File

@ -19,6 +19,7 @@ import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
@ -57,7 +58,7 @@ public abstract class FawePlayer<T> {
*/
public static <V> FawePlayer<V> wrap(final Object obj) {
if (obj == null) {
return null;
return FakePlayer.getConsole().toFawePlayer();
}
if (obj instanceof FakePlayer) {
return ((FakePlayer) obj).toFawePlayer();
@ -88,6 +89,15 @@ public abstract class FawePlayer<T> {
}
}
}
if (obj instanceof Actor) {
Actor actor = (Actor) obj;
FawePlayer existing = Fawe.get().getCachedPlayer(actor.getName());
if (existing != null) {
return existing;
}
FakePlayer fake = new FakePlayer(actor.getName(), actor.getUniqueId(), actor);
return fake.toFawePlayer();
}
return Fawe.imp().wrap(obj);
}
@ -448,4 +458,4 @@ public abstract class FawePlayer<T> {
});
return true;
}
}
}

View File

@ -13,6 +13,11 @@ public abstract class RunnableVal<T> implements Runnable {
public void run() {
run(this.value);
}
public T runAndGet() {
run();
return value;
}
public abstract void run(T value);
}

View File

@ -18,6 +18,7 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.regions.CuboidRegion;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
@ -34,7 +35,7 @@ import java.util.UUID;
*
* TODO load on join
*/
public class DiskOptimizedClipboard extends FaweClipboard {
public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public static int COMPRESSION = 0;
public static int MODE = 0;

View File

@ -38,7 +38,7 @@ public class EditSessionBuilder {
* An EditSession builder<br>
* - Unset values will revert to their default<br>
* <br>
* player: The player doing the edit (defaults to to console)<br>
* player: The player doing the edit (defaults to to null)<br>
* limit: Block/Entity/Action limit (defaults to unlimited)<br>
* changeSet: Stores changes (defaults to config.yml value)<br>
* allowedRegions: Allowed editable regions (defaults to player's allowed regions, or everywhere)<br>

View File

@ -2,36 +2,41 @@ package com.boydti.fawe.util;
public class FaweTimer implements Runnable {
private long tick = 0;
private final double[] history = new double[] {20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d,20d};
private int historyIndex = 0;
private long lastPoll = System.nanoTime();
private long lastPoll = System.currentTimeMillis();
private long tickStart = System.currentTimeMillis();
private final long tickInterval = 50;
private long tick = 0;
private long tickMod = 0;
@Override
public void run() {
final long startTime = System.nanoTime();
final long currentTime = System.currentTimeMillis();
long timeSpent = (startTime - lastPoll) / 1000;
tickStart = System.currentTimeMillis();
tick++;
if (++tickMod == tickInterval) {
tickMod = 0;
} else {
return;
}
long timeSpent = (tickStart - lastPoll);
if (timeSpent == 0)
{
timeSpent = 1;
}
tick++;
double tps = tickInterval * 1000000.0 / timeSpent;
history[historyIndex++] = tps;
if (historyIndex >= history.length) {
historyIndex = 0;
}
lastPoll = startTime;
lastPoll = tickStart;
}
private long lastGetTPSTick = 0;
private double lastGetTPSValue = 20d;
public double getTPS() {
if (tick == lastGetTPSTick) {
if (tick < lastGetTPSTick + tickInterval) {
return lastGetTPSValue;
}
double total = 0;
@ -42,4 +47,37 @@ public class FaweTimer implements Runnable {
lastGetTPSTick = tick;
return lastGetTPSValue;
}
public long getTick() {
return tick;
}
public long getTickMillis() {
return System.currentTimeMillis() - tickStart;
}
private long skip = 0;
private long skipTick = 0;
public boolean isAbove(double tps) {
if (skip > 0) {
if (skipTick != tick) {
skip--;
}
return false;
}
if (getTickMillis() < 50 || getTPS() < tps) {
skip = 10;
skipTick = tick;
}
return true;
}
private boolean runIfAbove(Runnable run, double tps) {
if (isAbove(tps)) {
run.run();
return true;
}
return false;
}
}

View File

@ -6,9 +6,9 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal2;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
public class SetQueue {
@ -22,8 +22,9 @@ public class SetQueue {
INACTIVE, ACTIVE, NONE;
}
public final ConcurrentLinkedDeque<FaweQueue> activeQueues;
public final ConcurrentLinkedDeque<FaweQueue> inactiveQueues;
private final ConcurrentLinkedDeque<FaweQueue> activeQueues;
private final ConcurrentLinkedDeque<FaweQueue> inactiveQueues;
private final ConcurrentLinkedDeque<Runnable> tasks;
/**
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server
@ -35,7 +36,7 @@ public class SetQueue {
/**
* A queue of tasks that will run when the queue is empty
*/
private final ConcurrentLinkedDeque<Runnable> runnables = new ConcurrentLinkedDeque<>();
private final ConcurrentLinkedDeque<Runnable> emptyTasks = new ConcurrentLinkedDeque<>();
private final RunnableVal2<Long, FaweQueue> SET_TASK = new RunnableVal2<Long, FaweQueue>() {
@Override
@ -45,7 +46,7 @@ public class SetQueue {
if (current == null) {
lastSuccess = last;
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
tasks();
runEmptyTasks();
}
return;
}
@ -54,14 +55,18 @@ public class SetQueue {
};
public SetQueue() {
tasks = new ConcurrentLinkedDeque<>();
activeQueues = new ConcurrentLinkedDeque();
inactiveQueues = new ConcurrentLinkedDeque<>();
TaskManager.IMP.repeat(new Runnable() {
@Override
public void run() {
while (!tasks.isEmpty() && Fawe.get().getTimer().isAbove(18.5)) {
Runnable task = tasks.poll();
}
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
lastSuccess = System.currentTimeMillis();
tasks();
runEmptyTasks();
return;
}
if (!MemUtil.isMemoryFree()) {
@ -76,7 +81,7 @@ public class SetQueue {
if (SetQueue.this.forceChunkSet()) {
System.gc();
} else {
SetQueue.this.tasks();
SetQueue.this.runEmptyTasks();
}
return;
}
@ -155,19 +160,19 @@ public class SetQueue {
activeQueues.remove(queue);
}
public List<FaweQueue> getAllQueues() {
public Collection<FaweQueue> getAllQueues() {
ArrayList<FaweQueue> list = new ArrayList<FaweQueue>(activeQueues.size() + inactiveQueues.size());
list.addAll(inactiveQueues);
list.addAll(activeQueues);
return list;
}
public List<FaweQueue> getActiveQueues() {
return new ArrayList<>(activeQueues);
public Collection<FaweQueue> getActiveQueues() {
return activeQueues;
}
public List<FaweQueue> getInactiveQueues() {
return new ArrayList<>(inactiveQueues);
public Collection<FaweQueue> getInactiveQueues() {
return inactiveQueues;
}
public FaweQueue getNewQueue(String world, boolean fast, boolean autoqueue) {
@ -319,31 +324,44 @@ public class SetQueue {
return next() != null;
}
public boolean isDone() {
/**
* Is the this empty
* @return
*/
public boolean isEmpty() {
return activeQueues.size() == 0 && inactiveQueues.size() == 0;
}
public boolean addTask(final Runnable whenDone) {
if (this.isDone()) {
public void addTask(Runnable whenFree) {
tasks.add(whenFree);
}
/**
* Add a task to run when it is empty
* @param whenDone
* @return
*/
public boolean addEmptyTask(final Runnable whenDone) {
if (this.isEmpty()) {
// Run
this.tasks();
this.runEmptyTasks();
if (whenDone != null) {
whenDone.run();
}
return true;
}
if (whenDone != null) {
this.runnables.add(whenDone);
this.emptyTasks.add(whenDone);
}
return false;
}
public synchronized boolean tasks() {
if (this.runnables.isEmpty()) {
private synchronized boolean runEmptyTasks() {
if (this.emptyTasks.isEmpty()) {
return false;
}
final ConcurrentLinkedDeque<Runnable> tmp = new ConcurrentLinkedDeque<>(this.runnables);
this.runnables.clear();
final ConcurrentLinkedDeque<Runnable> tmp = new ConcurrentLinkedDeque<>(this.emptyTasks);
this.emptyTasks.clear();
for (final Runnable runnable : tmp) {
runnable.run();
}

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import java.util.Collection;
import java.util.Iterator;
@ -98,6 +99,21 @@ public abstract class TaskManager {
}
/**
* Disable async catching for a specific task
* @param queue
* @param run
*/
public void runUnsafe(FaweQueue queue, Runnable run) {
queue.startSet(true);
try {
run.run();
} catch (Throwable e) {
e.printStackTrace();
}
queue.endSet(true);
}
/**
* Run a task on the current thread or asynchronously
* - If it's already the main thread, it will jst call run()
@ -117,7 +133,7 @@ public abstract class TaskManager {
* @param r
* @param async
*/
public void taskSyncNow(final Runnable r, boolean async) {
public void taskNowMain(final Runnable r, boolean async) {
if (async) {
async(r);
} else if (r != null && Thread.currentThread() == Fawe.get().getMainThread()){
@ -132,7 +148,7 @@ public abstract class TaskManager {
* @param r
* @param async
*/
public void taskSyncSoon(final Runnable r, boolean async) {
public void taskSoonMain(final Runnable r, boolean async) {
if (async) {
async(r);
} else {
@ -220,6 +236,54 @@ public abstract class TaskManager {
}
}
/**
* Run a task on the main thread when the TPS is high enough, and wait for execution to finish:<br>
* - Useful if you need to access something from the Bukkit API from another thread<br>
* - Usualy wait time is around 25ms<br>
* @param function
* @param timeout - How long to wait for execution
* @param <T>
* @return
*/
public <T> T syncWhenFree(final RunnableVal<T> function, int timeout) {
if (Fawe.get().getMainThread() == Thread.currentThread()) {
function.run();
return function.value;
}
final AtomicBoolean running = new AtomicBoolean(true);
RunnableVal<RuntimeException> run = new RunnableVal<RuntimeException>() {
@Override
public void run(RuntimeException value) {
try {
function.run();
} catch (RuntimeException e) {
this.value = e;
} catch (Throwable neverHappens) {
MainUtil.handleError(neverHappens);
} finally {
running.set(false);
}
synchronized (function) {
function.notifyAll();
}
}
};
SetQueue.IMP.addTask(run);
try {
synchronized (function) {
while (running.get()) {
function.wait(timeout);
}
}
} catch (InterruptedException e) {
MainUtil.handleError(e);
}
if (run.value != null) {
throw run.value;
}
return function.value;
}
/**
* Quickly run a task on the main thread, and wait for execution to finish:<br>
* - Useful if you need to access something from the Bukkit API from another thread<br>

View File

@ -64,7 +64,8 @@ public class WEManager {
* @return
*/
public RegionWrapper[] getMask(final FawePlayer<?> player) {
HashSet<RegionWrapper> mask = TaskManager.IMP.sync(new RunnableVal<HashSet<RegionWrapper>>() {
// HashSet<RegionWrapper> mask = TaskManager.IMP.sync(new RunnableVal<HashSet<RegionWrapper>>() {
HashSet<RegionWrapper> mask = new RunnableVal<HashSet<RegionWrapper>>() {
@Override
public void run(HashSet<RegionWrapper> ignore) {
this.value = new HashSet<>();
@ -87,7 +88,8 @@ public class WEManager {
}
}
}
}, 1000);
// }, 1000);
}.runAndGet();
if (mask == null || mask.isEmpty()) {
mask = player.getMeta("lastMask");
if (mask == null) {
@ -130,7 +132,7 @@ public class WEManager {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
SetQueue.IMP.addTask(new Runnable() {
SetQueue.IMP.addEmptyTask(new Runnable() {
@Override
public void run() {
if ((System.currentTimeMillis() - start) > 1000) {
@ -150,7 +152,7 @@ public class WEManager {
}
public boolean delay(final FawePlayer<?> player, final Runnable whenDone, final boolean delayed, final boolean onlyDelayedExecution) {
final boolean free = SetQueue.IMP.addTask(null);
final boolean free = SetQueue.IMP.addEmptyTask(null);
if (free) {
if (delayed) {
if (whenDone != null) {
@ -167,7 +169,7 @@ public class WEManager {
if (!delayed && (player != null)) {
BBC.WORLDEDIT_DELAYED.send(player);
}
SetQueue.IMP.addTask(whenDone);
SetQueue.IMP.addEmptyTask(whenDone);
}
return true;
}

View File

@ -11,6 +11,7 @@ import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.session.SessionKey;
@ -28,77 +29,90 @@ public class FakePlayer extends LocalPlayer {
public static FakePlayer getConsole() {
if (CONSOLE == null) {
CONSOLE = new FakePlayer("#CONSOLE", null);
CONSOLE = new FakePlayer("#CONSOLE", null, null) {
@Override
public boolean hasPermission(String permission) {
return true;
}
};
}
return CONSOLE;
}
private final Actor parent;
private final String name;
private final UUID uuid;
private World world;
private Location pos;
public FakePlayer(String name, UUID uuid) {
public FakePlayer(String name, UUID uuid, Actor parent) {
this.name = name;
this.uuid = uuid == null ? UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)) : uuid;
this.world = WorldEdit.getInstance().getServer().getWorlds().get(0);
this.pos = new Location(world, 0, 0, 0);
this.parent = parent;
}
private FawePlayer fp;
private FawePlayer fp = null;
public FawePlayer toFawePlayer() {
if (fp == null) {
fp = new FawePlayer(this) {
@Override
public void sendTitle(String head, String sub) {}
@Override
public void resetTitle() {}
@Override
public String getName() {
return name;
}
@Override
public UUID getUUID() {
return uuid;
}
@Override
public boolean hasPermission(String perm) {
return FakePlayer.this.hasPermission(perm) || (Boolean) getMeta("perm." + perm, false);
}
@Override
public void setPermission(String perm, boolean flag) {
setMeta("perm." + perm, true);
}
@Override
public void sendMessage(String message) {
FakePlayer.this.print(message);
}
@Override
public void executeCommand(String substring) {
CommandManager.getInstance().handleCommand(new CommandEvent(FakePlayer.this, substring));
}
@Override
public FaweLocation getLocation() {
Location loc = FakePlayer.this.getLocation();
return new FaweLocation(loc.getExtent().toString(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
@Override
public Player getPlayer() {
return FakePlayer.this;
}
};
if (fp != null) {
Fawe.get().register(fp);
return fp;
}
return fp;
FawePlayer existing = Fawe.get().getCachedPlayer(getName());
if (existing != null) {
return fp = existing;
}
final Actor actor = this;
return fp = new FawePlayer(this) {
@Override
public void sendTitle(String head, String sub) {}
@Override
public void resetTitle() {}
@Override
public String getName() {
return actor.getName();
}
@Override
public UUID getUUID() {
return actor.getUniqueId();
}
@Override
public boolean hasPermission(String perm) {
return actor.hasPermission(perm) || (Boolean) getMeta("perm." + perm, false);
}
@Override
public void setPermission(String perm, boolean flag) {
setMeta("perm." + perm, true);
}
@Override
public void sendMessage(String message) {
actor.print(message);
}
@Override
public void executeCommand(String substring) {
CommandManager.getInstance().handleCommand(new CommandEvent(actor, substring));
}
@Override
public FaweLocation getLocation() {
Location loc = FakePlayer.this.getLocation();
return new FaweLocation(loc.getExtent().toString(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
@Override
public Player getPlayer() {
return FakePlayer.this;
}
};
}
@Override
@ -152,26 +166,45 @@ public class FakePlayer extends LocalPlayer {
@Override
public String getName() {
if (parent != null) {
return parent.getName();
}
return name;
}
@Override
public void printRaw(String msg) {
if (parent != null) {
parent.printRaw(msg);
return;
}
Fawe.debug(msg);
}
@Override
public void printDebug(String msg) {
if (parent != null) {
parent.printDebug(msg);
return;
}
Fawe.debug(msg);
}
@Override
public void print(String msg) {
if (parent != null) {
parent.print(msg);
return;
}
Fawe.debug(msg);
}
@Override
public void printError(String msg) {
if (parent != null) {
parent.printError(msg);
return;
}
Fawe.debug(msg);
}
@ -179,6 +212,9 @@ public class FakePlayer extends LocalPlayer {
@Override
public SessionKey getSessionKey() {
if (parent != null) {
return parent.getSessionKey();
}
if (key == null) {
key = new FakeSessionKey(uuid, name);
}
@ -193,16 +229,25 @@ public class FakePlayer extends LocalPlayer {
@Override
public UUID getUniqueId() {
if (parent != null) {
return parent.getUniqueId();
}
return uuid;
}
@Override
public String[] getGroups() {
if (parent != null) {
return parent.getGroups();
}
return new String[0];
}
@Override
public boolean hasPermission(String permission) {
if (parent != null) {
return parent.hasPermission(permission);
}
return true;
}

View File

@ -23,7 +23,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
@ -54,6 +54,7 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent;
@ -247,12 +248,12 @@ public class EditSession implements Extent {
this.blockBag = blockBag;
this.limit = limit;
this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), fastmode, autoQueue);
queue.addEditSession(this);
this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), bus, event, Stage.BEFORE_CHANGE);
this.bypassHistory = (this.extent = wrapExtent(bypassAll, bus, event, Stage.BEFORE_REORDER));
if (!fastmode && !(changeSet instanceof NullChangeSet)) {
if (player != null) {
EditSessionWrapper wrapper = Fawe.imp().getEditSessionWrapper(this);
changeSet = wrapper.wrapChangeSet(changeSet, player);
if (player != null && Fawe.imp().getBlocksHubApi() != null) {
changeSet = LoggingChangeSet.wrap(player, changeSet);
}
if (combineStages) {
changeTask = changeSet;
@ -324,7 +325,9 @@ public class EditSession implements Extent {
NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
while (traverser != null) {
ExtentTraverser next = traverser.next();
traverser.setNext(nullExtent);
if (traverser.get() instanceof AbstractDelegateExtent) {
traverser.setNext(nullExtent);
}
traverser = next;
}
bypassHistory = nullExtent;

View File

@ -228,7 +228,7 @@ public class LocalSession {
history.add(0, editSession);
historyPointer++;
}
while ((history.size() > MAX_HISTORY_SIZE || historySize < limitMb) && history.size() > 1) {
while ((history.size() > MAX_HISTORY_SIZE || (historySize >> 20) > limitMb) && history.size() > 1) {
EditSession item = history.get(0);
historySize -= MainUtil.getSizeInMemory(item.getChangeSet());
history.remove(0);

View File

@ -19,7 +19,9 @@
package com.sk89q.worldedit.command;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
import com.intellectualcrafters.plot.util.MathMan;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
@ -27,11 +29,13 @@ import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.world.World;
import static com.google.common.base.Preconditions.checkNotNull;
@ -157,7 +161,7 @@ public class NavigationCommands {
}
@Command(
aliases = { "jumpto", "j" },
aliases = { "jumpto [world,x,y,z]", "j" },
usage = "",
desc = "Teleport to a location",
min = 0,
@ -165,8 +169,20 @@ public class NavigationCommands {
)
@CommandPermissions("worldedit.navigation.jumpto.command")
public void jumpTo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
WorldVector pos = player.getSolidBlockTrace(300);
WorldVector pos;
if (args.argsLength() == 1) {
String arg = args.getString(0);
String[] split = arg.split(",");
World world = FaweAPI.getWorld(split[0]);
if (world != null && split.length == 4 && MathMan.isInteger(split[1]) && MathMan.isInteger(split[2]) && MathMan.isInteger(split[3])) {
pos = new WorldVector((LocalWorld) world, Integer.parseInt(split[1]), Integer.parseInt(split[2]), Integer.parseInt(split[3]));
} else {
BBC.SELECTOR_INVALID_COORDINATES.send(player, args.getString(0));
return;
}
} else {
pos = player.getSolidBlockTrace(300);
}
if (pos != null) {
player.findFreePosition(pos);
BBC.POOF.send(player);

View File

@ -93,7 +93,7 @@ public class SelectionCommands {
String[] coords = args.getString(0).split(",");
pos = new Vector(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]), Integer.parseInt(coords[2]));
} else {
player.printError("Invalid coordinates " + args.getString(0));
BBC.SELECTOR_INVALID_COORDINATES.send(player, args.getString(0));
return;
}
} else {
@ -101,7 +101,7 @@ public class SelectionCommands {
}
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) {
player.printError("Position already set.");
BBC.SELECTOR_ALREADY_SET.send(player);
return;
}
@ -128,7 +128,7 @@ public class SelectionCommands {
Integer.parseInt(coords[1]),
Integer.parseInt(coords[2]));
} else {
player.printError("Invalid coordinates " + args.getString(0));
BBC.SELECTOR_INVALID_COORDINATES.send(player, args.getString(0));
return;
}
} else {
@ -136,7 +136,7 @@ public class SelectionCommands {
}
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
player.printError("Position already set.");
BBC.SELECTOR_ALREADY_SET.send(player);
return;
}
@ -158,7 +158,7 @@ public class SelectionCommands {
if (pos != null) {
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) {
player.printError("Position already set.");
BBC.SELECTOR_ALREADY_SET.send(player);
return;
}
@ -183,7 +183,7 @@ public class SelectionCommands {
if (pos != null) {
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
player.printError("Position already set.");
BBC.SELECTOR_ALREADY_SET.send(player);
return;
}
@ -232,7 +232,7 @@ public class SelectionCommands {
// coords specified
String[] coords = args.getString(0).split(",");
if (coords.length != 2) {
throw new InsufficientArgumentsException("Invalid coordinates specified.");
BBC.SELECTOR_INVALID_COORDINATES.send(player, args.getString(0));
}
int x = Integer.parseInt(coords[0]);
int z = Integer.parseInt(coords[1]);

View File

@ -26,6 +26,7 @@ import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.FakePlayer;
import com.boydti.fawe.wrappers.PlayerWrapper;
import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.CommandException;
@ -233,17 +234,18 @@ public final class CommandManager {
TaskManager.IMP.taskNow(new Runnable() {
@Override
public void run() {
final Actor actor = platformManager.createProxyActor(event.getActor());
String[] split = commandDetection(event.getArguments().split(" "));
Actor actor = platformManager.createProxyActor(event.getActor());
String args = event.getArguments();
String[] split = commandDetection(args.split(" "));
// No command found!
if (!dispatcher.contains(split[0])) {
return;
}
if (!actor.isPlayer()) {
actor = new FakePlayer(actor.getName(), actor.getUniqueId(), actor);
}
final LocalSession session = worldEdit.getSessionManager().get(actor);
LocalConfiguration config = worldEdit.getConfiguration();
CommandLocals locals = new CommandLocals();
final FawePlayer fp = FawePlayer.wrap(actor);
if (fp != null) {
@ -252,11 +254,11 @@ public final class CommandManager {
return;
}
fp.setMeta("fawe_action", true);
locals.put(Actor.class, PlayerWrapper.wrap((Player) actor));
locals.put(Actor.class, actor instanceof Player ? new PlayerWrapper((Player) actor) : actor);
} else {
locals.put(Actor.class, actor);
}
locals.put("arguments", event.getArguments());
locals.put("arguments", args);
final long start = System.currentTimeMillis();
try {
// This is a bit of a hack, since the call method can only throw CommandExceptions

View File

@ -4,7 +4,6 @@ package com.boydti.fawe.forge;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.IFawe;
import com.boydti.fawe.forge.v0.ForgeQueue_All;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
@ -12,7 +11,6 @@ import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.forge.ForgeWorld;
import com.sk89q.worldedit.world.World;
import java.io.File;
@ -111,11 +109,6 @@ public class FaweForge implements IFawe {
return new ForgeQueue_All(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new EditSessionWrapper(session);
}
@Override
public Collection<FaweMaskManager> getMaskManagers() {
return new ArrayList<>();
@ -150,4 +143,9 @@ public class FaweForge implements IFawe {
public String getName(UUID uuid) {
return uuid.toString();
}
@Override
public Object getBlocksHubApi() {
return null;
}
}

View File

@ -4,7 +4,6 @@ package com.boydti.fawe.forge;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.IFawe;
import com.boydti.fawe.forge.v0.ForgeQueue_All;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.FaweMaskManager;
@ -13,7 +12,6 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.mojang.authlib.GameProfile;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.forge.ForgeWorld;
import com.sk89q.worldedit.world.World;
import java.io.File;
@ -25,6 +23,7 @@ import net.minecraft.command.ServerCommandManager;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.Logger;
import org.primesoft.blockshub.IBlocksHubApi;
public class FaweForge implements IFawe {
@ -114,11 +113,6 @@ public class FaweForge implements IFawe {
return new ForgeQueue_All(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new EditSessionWrapper(session);
}
@Override
public Collection<FaweMaskManager> getMaskManagers() {
return new ArrayList<>();
@ -159,4 +153,9 @@ public class FaweForge implements IFawe {
return null;
}
}
@Override
public Object getBlocksHubApi() {
return null;
}
}

View File

@ -173,9 +173,9 @@
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.PrimeSoft</groupId>
<groupId>org.primesoft</groupId>
<artifactId>blockshub</artifactId>
<version>1.2</version>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>

View File

@ -5,16 +5,14 @@ import com.boydti.fawe.IFawe;
import com.boydti.fawe.SpongeCommand;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.EditSessionWrapper;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.sponge.v1_8.SpongeQueue_1_8;
import com.boydti.fawe.sponge.v1_8.SpongeQueue_ALL;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import com.sk89q.worldedit.world.World;
import java.io.File;
@ -126,11 +124,6 @@ public class FaweSponge implements IFawe {
return world.getName();
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new EditSessionWrapper(session);
}
@Override
public Collection<FaweMaskManager> getMaskManagers() {
return new ArrayList<>();
@ -173,4 +166,9 @@ public class FaweSponge implements IFawe {
return null;
}
}
@Override
public Object getBlocksHubApi() {
return null;
}
}