async bukkit wrappers / vs hook / api changes
This commit is contained in:
parent
a4353bb760
commit
c950b7554d
@ -13,4 +13,5 @@ dependencies {
|
||||
compile 'com.worldcretornica:plotme_core:0.16.3'
|
||||
compile 'junit:junit:4.11'
|
||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.1-SNAPSHOT'
|
||||
compile 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
package com.boydti.fawe.bukkit;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.EditSessionWrapper;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Sniper;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public abstract class ABukkitMain extends JavaPlugin {
|
||||
@ -10,6 +13,12 @@ public abstract class ABukkitMain extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
new FaweBukkit(this);
|
||||
|
||||
try {
|
||||
SnipeData.inject();
|
||||
Sniper.inject();
|
||||
Fawe.debug("Injected VoxelSniper classes");
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
|
||||
public abstract FaweQueue getQueue(String world);
|
||||
|
@ -19,7 +19,7 @@ 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.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
|
@ -3,7 +3,7 @@ package com.boydti.fawe.bukkit.logging;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import org.PrimeSoft.blocksHub.BlocksHub;
|
||||
|
@ -5,7 +5,7 @@ import com.boydti.fawe.object.EditSessionWrapper;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
|
@ -0,0 +1,277 @@
|
||||
package com.boydti.fawe.bukkit.wrapper;
|
||||
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.PistonMoveReaction;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class AsyncBlock implements Block {
|
||||
|
||||
public final int z;
|
||||
public final int y;
|
||||
public final int x;
|
||||
public final FaweQueue queue;
|
||||
public final World world;
|
||||
|
||||
public AsyncBlock(World world, FaweQueue queue, int x, int y, int z) {
|
||||
this.world = world;
|
||||
this.queue = queue;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getData() {
|
||||
return (byte) (queue.getCombinedId4Data(x, y, z) & 0xF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getRelative(int modX, int modY, int modZ) {
|
||||
return new AsyncBlock(world, queue, x + modX, y + modY, z + modZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getRelative(BlockFace face) {
|
||||
return this.getRelative(face.getModX(), face.getModY(), face.getModZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getRelative(BlockFace face, int distance) {
|
||||
return this.getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getType() {
|
||||
return Material.getMaterial(queue.getCombinedId4Data(x, y, z) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeId() {
|
||||
return queue.getCombinedId4Data(x, y, z) >> 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getLightLevel() {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getLightFromSky() {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getLightFromBlocks() {
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation(Location loc) {
|
||||
if(loc != null) {
|
||||
loc.setWorld(this.getWorld());
|
||||
loc.setX((double)this.x);
|
||||
loc.setY((double)this.y);
|
||||
loc.setZ((double)this.z);
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk() {
|
||||
return world.getChunkAt(x >> 4, z >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(byte data) {
|
||||
setTypeIdAndData(getTypeId(), data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(byte data, boolean applyPhysics) {
|
||||
setTypeIdAndData(getTypeId(), data, applyPhysics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Material type) {
|
||||
setTypeIdAndData(type.getId(), (byte) 0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Material type, boolean applyPhysics) {
|
||||
setTypeIdAndData(type.getId(), (byte) 0, applyPhysics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeId(int type) {
|
||||
return setTypeIdAndData(type, (byte) 0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeId(int type, boolean applyPhysics) {
|
||||
return setTypeIdAndData(type, (byte) 0, applyPhysics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeIdAndData(int type, byte data, boolean applyPhysics) {
|
||||
return queue.setBlock(x, y, z, (short) type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockFace getFace(Block block) {
|
||||
BlockFace[] directions = BlockFace.values();
|
||||
for(int i = 0; i < directions.length; ++i) {
|
||||
BlockFace face = directions[i];
|
||||
if(this.getX() + face.getModX() == block.getX() && this.getY() + face.getModY() == block.getY() && this.getZ() + face.getModZ() == block.getZ()) {
|
||||
return face;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getState() {
|
||||
return new AsyncBlockState(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(Biome bio) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockPowered() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockIndirectlyPowered() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockFacePowered(BlockFace face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockFaceIndirectlyPowered(BlockFace face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockPower(BlockFace face) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockPower() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLiquid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTemperature() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHumidity() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PistonMoveReaction getPistonMoveReaction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean breakNaturally() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean breakNaturally(ItemStack tool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ItemStack> getDrops() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ItemStack> getDrops(ItemStack tool) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetadataValue> getMetadata(String metadataKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata(String metadataKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package com.boydti.fawe.bukkit.wrapper;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import java.util.List;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class AsyncBlockState implements BlockState {
|
||||
|
||||
private byte data;
|
||||
private short id;
|
||||
private CompoundTag nbt;
|
||||
private final AsyncBlock block;
|
||||
|
||||
public AsyncBlockState(AsyncBlock block) {
|
||||
this.block = block;
|
||||
int combined = block.queue.getCombinedId4Data(block.x, block.y, block.z);
|
||||
this.id = (short) (combined >> 4);
|
||||
this.data = (byte) (combined & 0xF);
|
||||
if (FaweCache.hasNBT(id)) {
|
||||
this.nbt = block.queue.getTileEntity(block.x, block.y, block.z);
|
||||
} else {
|
||||
this.nbt = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialData getData() {
|
||||
return new MaterialData(id, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getType() {
|
||||
return Material.getMaterial(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getLightLevel() {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return block.world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return block.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return block.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return block.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return block.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation(Location loc) {
|
||||
return block.getLocation(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk() {
|
||||
return block.getChunk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(MaterialData data) {
|
||||
setTypeId(data.getItemTypeId());
|
||||
setRawData(data.getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Material type) {
|
||||
setTypeId(type.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTypeId(int type) {
|
||||
if (id != type) {
|
||||
this.id = (short) type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
return update(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force) {
|
||||
return update(force, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = block.queue.setBlock(block.x, block.y, block.z, id, data);
|
||||
if (nbt != null) {
|
||||
block.queue.setTile(block.x, block.y, block.z, nbt);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getRawData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRawData(byte data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaced() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadata(String key, MetadataValue value) {
|
||||
block.setMetadata(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetadataValue> getMetadata(String key) {
|
||||
return block.getMetadata(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata(String key) {
|
||||
return block.hasMetadata(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMetadata(String key, Plugin plugin) {
|
||||
block.removeMetadata(key, plugin);
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package com.boydti.fawe.bukkit.wrapper;
|
||||
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class AsyncChunk implements Chunk {
|
||||
|
||||
private final World world;
|
||||
private final int z;
|
||||
private final int x;
|
||||
private final FaweQueue queue;
|
||||
|
||||
public AsyncChunk(World world, FaweQueue queue, int x, int z) {
|
||||
this.world = world instanceof AsyncWorld ? world : new AsyncWorld(world, true);
|
||||
this.queue = queue;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return new AsyncBlock(world, queue, (this.x << 4) + x, y, (this.z << 4) + z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getChunkSnapshot() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity[] getEntities() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState[] getTileEntities() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return world.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(boolean generate) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = world.loadChunk(x, z, generate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
return load(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean save, boolean safe) {
|
||||
return world.unloadChunk(x, z, save, safe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean save) {
|
||||
return unload(true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload() {
|
||||
return unload(true);
|
||||
}
|
||||
}
|
@ -0,0 +1,868 @@
|
||||
package com.boydti.fawe.bukkit.wrapper;
|
||||
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.BlockChangeDelegate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Modify the world from an async thread <br>
|
||||
* - Any Chunk/Block/BlockState objects returned should also be thread safe <br>
|
||||
* - Use world.commit() to execute the changes <br>
|
||||
* - Don't rely on autoQueue as behavior is determined by the settings.yml <br>
|
||||
*/
|
||||
public class AsyncWorld implements World {
|
||||
|
||||
public final World parent;
|
||||
public final FaweQueue queue;
|
||||
private BukkitImplAdapter adapter;
|
||||
|
||||
public AsyncWorld(World parent, boolean autoQueue) {
|
||||
this(parent, FaweAPI.createQueue(parent.getName(), autoQueue));
|
||||
}
|
||||
|
||||
public AsyncWorld(World parent, FaweQueue queue) {
|
||||
this.parent = parent;
|
||||
this.queue = queue;
|
||||
if (queue instanceof BukkitQueue_0) {
|
||||
this.adapter = (BukkitImplAdapter) ((BukkitQueue_0) queue).adapter;
|
||||
} else {
|
||||
try {
|
||||
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
||||
fieldAdapter.setAccessible(true);
|
||||
this.adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
queue.enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldBorder getWorldBorder() {
|
||||
return TaskManager.IMP.sync(new RunnableVal<WorldBorder>() {
|
||||
@Override
|
||||
public void run(WorldBorder value) {
|
||||
this.value = parent.getWorldBorder();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(int x, int y, int z) {
|
||||
return new AsyncBlock(this, queue, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(Location loc) {
|
||||
return getBlockAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int getBlockTypeIdAt(int x, int y, int z) {
|
||||
return queue.getCombinedId4Data(x, y, z) >> 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int getBlockTypeIdAt(Location loc) {
|
||||
return getBlockTypeIdAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestBlockYAt(int x, int z) {
|
||||
for (int y = 255; y >= 0; y--) {
|
||||
if (queue.getCombinedId4Data(x, y, z) != 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestBlockYAt(Location loc) {
|
||||
return getHighestBlockYAt(loc.getBlockX(), loc.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getHighestBlockAt(int x, int z) {
|
||||
int y = getHighestBlockYAt(x, z);
|
||||
return getBlockAt(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getHighestBlockAt(Location loc) {
|
||||
return getHighestBlockAt(loc.getBlockX(), loc.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
return new AsyncChunk(this, queue, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(Location location) {
|
||||
return getChunkAt(location.getBlockX(), location.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(Block block) {
|
||||
return getChunkAt(block.getX(), block.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(Chunk chunk) {
|
||||
return chunk.isLoaded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk[] getLoadedChunks() {
|
||||
return parent.getLoadedChunks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadChunk(final Chunk chunk) {
|
||||
if (!chunk.isLoaded()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.loadChunk(chunk);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return parent.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkInUse(int x, int z) {
|
||||
return parent.isChunkInUse(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadChunk(int x, int z) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.loadChunk(x, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.loadChunk(x, z, generate);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunk(Chunk chunk) {
|
||||
if (chunk.isLoaded()) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.unloadChunk(chunk);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunk(int x, int z) {
|
||||
return unloadChunk(x, z, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunk(int x, int z, boolean save) {
|
||||
return unloadChunk(x, z, save, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunk(int x, int z, boolean save, boolean safe) {
|
||||
if (isChunkLoaded(x, z)) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.unloadChunk(x, z, save, safe);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunkRequest(int x, int z) {
|
||||
return unloadChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unloadChunkRequest(int x, int z, boolean safe) {
|
||||
return unloadChunk(x, z, safe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.regenerateChunk(x, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean refreshChunk(int x, int z) {
|
||||
queue.sendChunk(queue.getFaweChunk(x, z), FaweQueue.RelightMode.NONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item dropItem(Location location, ItemStack item) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Item>() {
|
||||
@Override
|
||||
public void run(Item value) {
|
||||
this.value = parent.dropItem(location, item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item dropItemNaturally(Location location, ItemStack item) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Item>() {
|
||||
@Override
|
||||
public void run(Item value) {
|
||||
this.value = parent.dropItemNaturally(location, item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Arrow spawnArrow(Location location, Vector direction, float speed, float spread) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Arrow>() {
|
||||
@Override
|
||||
public void run(Arrow value) {
|
||||
this.value = parent.spawnArrow(location, direction, speed, spread);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateTree(Location location, TreeType type) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.generateTree(location, type);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.generateTree(loc, type, delegate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(Location loc, EntityType type) {
|
||||
return spawn(loc, type.getEntityClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public LivingEntity spawnCreature(Location loc, EntityType type) {
|
||||
return (LivingEntity)this.spawnEntity(loc, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public LivingEntity spawnCreature(Location loc, CreatureType type) {
|
||||
return this.spawnCreature(loc, type.toEntityType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightningStrike strikeLightning(Location loc) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<LightningStrike>() {
|
||||
@Override
|
||||
public void run(LightningStrike value) {
|
||||
this.value = parent.strikeLightning(loc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightningStrike strikeLightningEffect(Location loc) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<LightningStrike>() {
|
||||
@Override
|
||||
public void run(LightningStrike value) {
|
||||
this.value = parent.strikeLightningEffect(loc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> getEntities() {
|
||||
return TaskManager.IMP.sync(new RunnableVal<List<Entity>>() {
|
||||
@Override
|
||||
public void run(List<Entity> value) {
|
||||
this.value = parent.getEntities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LivingEntity> getLivingEntities() {
|
||||
return TaskManager.IMP.sync(new RunnableVal<List<LivingEntity>>() {
|
||||
@Override
|
||||
public void run(List<LivingEntity> value) {
|
||||
this.value = parent.getLivingEntities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public <T extends Entity> Collection<T> getEntitiesByClass(Class<T>... classes) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Collection<T>>() {
|
||||
@Override
|
||||
public void run(Collection<T> value) {
|
||||
this.value = (Collection<T>) parent.getEntitiesByClass(classes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> Collection<T> getEntitiesByClass(Class<T> cls) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Collection<T>>() {
|
||||
@Override
|
||||
public void run(Collection<T> value) {
|
||||
this.value = (Collection<T>) parent.getEntitiesByClass(cls);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Entity> getEntitiesByClasses(Class<?>... classes) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Collection<Entity>>() {
|
||||
@Override
|
||||
public void run(Collection<Entity> value) {
|
||||
this.value = parent.getEntitiesByClasses(classes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Player> getPlayers() {
|
||||
return TaskManager.IMP.sync(new RunnableVal<List<Player>>() {
|
||||
@Override
|
||||
public void run(List<Player> value) {
|
||||
this.value = parent.getPlayers();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Entity> getNearbyEntities(Location location, double x, double y, double z) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Collection<Entity>>() {
|
||||
@Override
|
||||
public void run(Collection<Entity> value) {
|
||||
this.value = parent.getNearbyEntities(location, x, y, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return parent.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUID() {
|
||||
return parent.getUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getSpawnLocation() {
|
||||
return parent.getSpawnLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSpawnLocation(int x, int y, int z) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.setSpawnLocation(x, y, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTime() {
|
||||
return parent.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTime(long time) {
|
||||
parent.setTime(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFullTime() {
|
||||
return parent.getFullTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullTime(long time) {
|
||||
parent.setFullTime(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStorm() {
|
||||
return parent.hasStorm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorm(boolean hasStorm) {
|
||||
parent.setStorm(hasStorm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWeatherDuration() {
|
||||
return parent.getWeatherDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeatherDuration(int duration) {
|
||||
parent.setWeatherDuration(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThundering() {
|
||||
return parent.isThundering();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThundering(boolean thundering) {
|
||||
parent.setThundering(thundering);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThunderDuration() {
|
||||
return parent.getThunderDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThunderDuration(int duration) {
|
||||
parent.setThunderDuration(duration);
|
||||
}
|
||||
|
||||
public boolean createExplosion(double x, double y, double z, float power) {
|
||||
return this.createExplosion(x, y, z, power, false, true);
|
||||
}
|
||||
|
||||
public boolean createExplosion(double x, double y, double z, float power, boolean setFire) {
|
||||
return this.createExplosion(x, y, z, power, setFire, true);
|
||||
}
|
||||
|
||||
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
this.value = parent.createExplosion(x, y, z, power, setFire, breakBlocks);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean createExplosion(Location loc, float power) {
|
||||
return this.createExplosion(loc, power, false);
|
||||
}
|
||||
|
||||
public boolean createExplosion(Location loc, float power, boolean setFire) {
|
||||
return this.createExplosion(loc.getX(), loc.getY(), loc.getZ(), power, setFire);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment getEnvironment() {
|
||||
return parent.getEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return parent.getSeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getPVP() {
|
||||
return parent.getPVP();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPVP(boolean pvp) {
|
||||
parent.setPVP(pvp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
return parent.getGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getPopulators() {
|
||||
return parent.getPopulators();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> T spawn(Location location, Class<T> clazz) throws IllegalArgumentException {
|
||||
return TaskManager.IMP.sync(new RunnableVal<T>() {
|
||||
@Override
|
||||
public void run(T value) {
|
||||
this.value = parent.spawn(location, clazz);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public FallingBlock spawnFallingBlock(Location location, Material material, byte data) throws IllegalArgumentException {
|
||||
return this.spawnFallingBlock(location, material.getId(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public FallingBlock spawnFallingBlock(Location location, int blockId, byte blockData) throws IllegalArgumentException {
|
||||
return TaskManager.IMP.sync(new RunnableVal<FallingBlock>() {
|
||||
@Override
|
||||
public void run(FallingBlock value) {
|
||||
this.value = parent.spawnFallingBlock(location, blockId, blockData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playEffect(Location location, Effect effect, int data) {
|
||||
this.playEffect(location, effect, data, 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playEffect(Location location, Effect effect, int data, int radius) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.playEffect(location, effect, data, radius);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void playEffect(Location loc, Effect effect, T data) {
|
||||
this.playEffect(loc, effect, data, 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void playEffect(Location location, Effect effect, T data, int radius) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.playEffect(location, effect, data, radius);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
return TaskManager.IMP.sync(new RunnableVal<ChunkSnapshot>() {
|
||||
@Override
|
||||
public void run(ChunkSnapshot value) {
|
||||
this.value = parent.getEmptyChunkSnapshot(x, z, includeBiome, includeBiomeTempRain);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) {
|
||||
parent.setSpawnFlags(allowMonsters, allowAnimals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAllowAnimals() {
|
||||
return parent.getAllowAnimals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAllowMonsters() {
|
||||
return parent.getAllowMonsters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, Biome bio) {
|
||||
int id = adapter.getBiomeId(bio);
|
||||
queue.setBiome(x, z, new BaseBiome(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTemperature(int x, int z) {
|
||||
return parent.getTemperature(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHumidity(int x, int z) {
|
||||
return parent.getHumidity(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return parent.getMaxHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return parent.getSeaLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getKeepSpawnInMemory() {
|
||||
return parent.getKeepSpawnInMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepSpawnInMemory(boolean keepLoaded) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.setKeepSpawnInMemory(keepLoaded);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoSave() {
|
||||
return parent.isAutoSave();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoSave(boolean value) {
|
||||
parent.setAutoSave(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDifficulty(Difficulty difficulty) {
|
||||
parent.setDifficulty(difficulty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Difficulty getDifficulty() {
|
||||
return parent.getDifficulty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getWorldFolder() {
|
||||
return parent.getWorldFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldType getWorldType() {
|
||||
return parent.getWorldType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canGenerateStructures() {
|
||||
return parent.canGenerateStructures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTicksPerAnimalSpawns() {
|
||||
return parent.getTicksPerAnimalSpawns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) {
|
||||
parent.setTicksPerAnimalSpawns(ticksPerAnimalSpawns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTicksPerMonsterSpawns() {
|
||||
return parent.getTicksPerMonsterSpawns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) {
|
||||
parent.setTicksPerMonsterSpawns(ticksPerMonsterSpawns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMonsterSpawnLimit() {
|
||||
return parent.getMonsterSpawnLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMonsterSpawnLimit(int limit) {
|
||||
parent.setMonsterSpawnLimit(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimalSpawnLimit() {
|
||||
return parent.getAnimalSpawnLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimalSpawnLimit(int limit) {
|
||||
parent.setAnimalSpawnLimit(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWaterAnimalSpawnLimit() {
|
||||
return parent.getWaterAnimalSpawnLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaterAnimalSpawnLimit(int limit) {
|
||||
parent.setWaterAnimalSpawnLimit(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmbientSpawnLimit() {
|
||||
return parent.getAmbientSpawnLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmbientSpawnLimit(int limit) {
|
||||
parent.setAmbientSpawnLimit(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Location location, Sound sound, float volume, float pitch) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
parent.playSound(location, sound, volume, pitch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGameRules() {
|
||||
return parent.getGameRules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGameRuleValue(String rule) {
|
||||
return parent.getGameRuleValue(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setGameRuleValue(String rule, String value) {
|
||||
return parent.setGameRuleValue(rule, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGameRule(String rule) {
|
||||
return parent.isGameRule(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadata(String key, MetadataValue value) {
|
||||
parent.setMetadata(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetadataValue> getMetadata(String key) {
|
||||
return parent.getMetadata(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata(String key) {
|
||||
return parent.hasMetadata(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMetadata(String key, Plugin plugin) {
|
||||
parent.removeMetadata(key, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPluginMessage(Plugin source, String channel, byte[] message) {
|
||||
parent.sendPluginMessage(source, channel, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getListeningPluginChannels() {
|
||||
return parent.getListeningPluginChannels();
|
||||
}
|
||||
}
|
252
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java
Normal file
252
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java
Normal file
@ -0,0 +1,252 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.util.VoxelList;
|
||||
import org.bukkit.World;
|
||||
|
||||
/**
|
||||
* @author Piotr
|
||||
*/
|
||||
public class SnipeData {
|
||||
|
||||
public static final int DEFAULT_REPLACE_DATA_VALUE = 0;
|
||||
public static final int DEFAULT_CYLINDER_CENTER = 0;
|
||||
public static final int DEFAULT_VOXEL_HEIGHT = 1;
|
||||
public static final int DEFAULT_BRUSH_SIZE = 3;
|
||||
public static final int DEFAULT_DATA_VALUE = 0;
|
||||
public static final int DEFAULT_REPLACE_ID = 0;
|
||||
public static final int DEFAULT_VOXEL_ID = 0;
|
||||
|
||||
private final Sniper owner;
|
||||
private Message voxelMessage;
|
||||
/**
|
||||
* Brush size -- set blockPositionY /b #.
|
||||
*/
|
||||
private int brushSize = SnipeData.DEFAULT_BRUSH_SIZE;
|
||||
/**
|
||||
* Voxel Id -- set blockPositionY /v (#,name).
|
||||
*/
|
||||
private int voxelId = SnipeData.DEFAULT_VOXEL_ID;
|
||||
/**
|
||||
* Voxel Replace Id -- set blockPositionY /vr #.
|
||||
*/
|
||||
private int replaceId = SnipeData.DEFAULT_REPLACE_ID;
|
||||
/**
|
||||
* Voxel 'ink' -- set blockPositionY /vi #.
|
||||
*/
|
||||
private byte data = SnipeData.DEFAULT_DATA_VALUE;
|
||||
/**
|
||||
* Voxel 'ink' Replace -- set blockPositionY /vir #.
|
||||
*/
|
||||
private byte replaceData = SnipeData.DEFAULT_REPLACE_DATA_VALUE;
|
||||
/**
|
||||
* Voxel List of ID's -- set blockPositionY /vl # # # -#.
|
||||
*/
|
||||
private VoxelList voxelList = new VoxelList();
|
||||
/**
|
||||
* Voxel 'heigth' -- set blockPositionY /vh #.
|
||||
*/
|
||||
private int voxelHeight = SnipeData.DEFAULT_VOXEL_HEIGHT;
|
||||
/**
|
||||
* Voxel centroid -- set Cylynder center /vc #.
|
||||
*/
|
||||
private int cCen = SnipeData.DEFAULT_CYLINDER_CENTER;
|
||||
private int range = 0;
|
||||
private boolean ranged = false;
|
||||
private boolean lightning = false;
|
||||
|
||||
/**
|
||||
* @param vs
|
||||
*/
|
||||
public SnipeData(final Sniper vs) {
|
||||
this.owner = vs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the brushSize
|
||||
*/
|
||||
public final int getBrushSize() {
|
||||
return this.brushSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cCen
|
||||
*/
|
||||
public final int getcCen() {
|
||||
return this.cCen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the data
|
||||
*/
|
||||
public final byte getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the replaceData
|
||||
*/
|
||||
public final byte getReplaceData() {
|
||||
return this.replaceData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the replaceId
|
||||
*/
|
||||
public final int getReplaceId() {
|
||||
return this.replaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the voxelHeight
|
||||
*/
|
||||
public final int getVoxelHeight() {
|
||||
return this.voxelHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the voxelId
|
||||
*/
|
||||
public final int getVoxelId() {
|
||||
return this.voxelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the voxelList
|
||||
*/
|
||||
public final VoxelList getVoxelList() {
|
||||
return this.voxelList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the voxelMessage
|
||||
*/
|
||||
public final Message getVoxelMessage() {
|
||||
return this.voxelMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return World
|
||||
*/
|
||||
public final World getWorld() {
|
||||
return this.owner.getWorld(); // Changed
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Sniper
|
||||
*/
|
||||
public final Sniper owner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to default values.
|
||||
*/
|
||||
public final void reset() {
|
||||
this.voxelId = SnipeData.DEFAULT_VOXEL_ID;
|
||||
this.replaceId = SnipeData.DEFAULT_REPLACE_ID;
|
||||
this.data = SnipeData.DEFAULT_DATA_VALUE;
|
||||
this.brushSize = SnipeData.DEFAULT_BRUSH_SIZE;
|
||||
this.voxelHeight = SnipeData.DEFAULT_VOXEL_HEIGHT;
|
||||
this.cCen = SnipeData.DEFAULT_CYLINDER_CENTER;
|
||||
this.replaceData = SnipeData.DEFAULT_REPLACE_DATA_VALUE;
|
||||
this.voxelList = new VoxelList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public final void sendMessage(final String message) {
|
||||
this.owner.getPlayer().sendMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param brushSize the brushSize to set
|
||||
*/
|
||||
public final void setBrushSize(final int brushSize) {
|
||||
this.brushSize = brushSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cCen the cCen to set
|
||||
*/
|
||||
public final void setcCen(final int cCen) {
|
||||
this.cCen = cCen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data the data to set
|
||||
*/
|
||||
public final void setData(final byte data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param replaceData the replaceData to set
|
||||
*/
|
||||
public final void setReplaceData(final byte replaceData) {
|
||||
this.replaceData = replaceData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param replaceId the replaceId to set
|
||||
*/
|
||||
public final void setReplaceId(final int replaceId) {
|
||||
this.replaceId = replaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param voxelHeight the voxelHeight to set
|
||||
*/
|
||||
public final void setVoxelHeight(final int voxelHeight) {
|
||||
this.voxelHeight = voxelHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param voxelId the voxelId to set
|
||||
*/
|
||||
public final void setVoxelId(final int voxelId) {
|
||||
this.voxelId = voxelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param voxelList the voxelList to set
|
||||
*/
|
||||
public final void setVoxelList(final VoxelList voxelList) {
|
||||
this.voxelList = voxelList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param voxelMessage the voxelMessage to set
|
||||
*/
|
||||
public final void setVoxelMessage(final Message voxelMessage) {
|
||||
this.voxelMessage = voxelMessage;
|
||||
}
|
||||
|
||||
public int getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(int range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public boolean isRanged() {
|
||||
return ranged;
|
||||
}
|
||||
|
||||
public void setRanged(boolean ranged) {
|
||||
this.ranged = ranged;
|
||||
}
|
||||
|
||||
public boolean isLightningEnabled() {
|
||||
return lightning;
|
||||
}
|
||||
|
||||
public void setLightningEnabled(boolean lightning) {
|
||||
this.lightning = lightning;
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return SnipeData.class;
|
||||
}
|
||||
}
|
546
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java
Normal file
546
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java
Normal file
@ -0,0 +1,546 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.MaskedFaweQueue;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ClassToInstanceMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.MutableClassToInstanceMap;
|
||||
import com.thevoxelbox.voxelsniper.brush.IBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.SnipeBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.Performer;
|
||||
import com.thevoxelbox.voxelsniper.event.SniperMaterialChangedEvent;
|
||||
import com.thevoxelbox.voxelsniper.event.SniperReplaceMaterialChangedEvent;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Sniper {
|
||||
private VoxelSniper plugin;
|
||||
private final UUID player;
|
||||
private boolean enabled = true;
|
||||
private LinkedList<Undo> undoList = new LinkedList<Undo>();
|
||||
private Map<String, SniperTool> tools = Maps.newHashMap();
|
||||
|
||||
public Sniper(VoxelSniper plugin, Player player) {
|
||||
this.plugin = plugin;
|
||||
this.player = player.getUniqueId();
|
||||
SniperTool sniperTool = new SniperTool(this);
|
||||
sniperTool.assignAction(SnipeAction.ARROW, Material.ARROW);
|
||||
sniperTool.assignAction(SnipeAction.GUNPOWDER, Material.SULPHUR);
|
||||
tools.put(null, sniperTool);
|
||||
}
|
||||
|
||||
public String getCurrentToolId() {
|
||||
return getToolId((getPlayer().getItemInHand() != null) ? getPlayer().getItemInHand().getType() : null);
|
||||
}
|
||||
|
||||
public String getToolId(Material itemInHand) {
|
||||
if (itemInHand == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, SniperTool> entry : tools.entrySet()) {
|
||||
if (entry.getValue().hasToolAssigned(itemInHand)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Added
|
||||
public AsyncWorld tmpWorld;
|
||||
|
||||
// Added
|
||||
public World getWorld() {
|
||||
if (this.tmpWorld == null) {
|
||||
return new AsyncWorld(getPlayer().getWorld(), false);
|
||||
}
|
||||
return tmpWorld;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return Bukkit.getPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniper execution call.
|
||||
*
|
||||
* @param action Action player performed
|
||||
* @param itemInHand Item in hand of player
|
||||
* @param clickedBlock Block that the player targeted/interacted with
|
||||
* @param clickedFace Face of that targeted Block
|
||||
* @return true if command visibly processed, false otherwise.
|
||||
*/
|
||||
public boolean snipe(Action action, Material itemInHand, Block clickedBlock, BlockFace clickedFace) {
|
||||
try {
|
||||
// Added
|
||||
FaweQueue queue;
|
||||
{
|
||||
Player player = getPlayer();
|
||||
if (tmpWorld == null || !player.getWorld().getName().equals(tmpWorld.getName())) {
|
||||
FawePlayer<Player> fp = FawePlayer.wrap(player);
|
||||
RegionWrapper[] mask = WEManager.IMP.getMask(fp).toArray(new RegionWrapper[0]);
|
||||
queue = FaweAPI.createQueue(fp.getLocation().world, true);
|
||||
queue = new MaskedFaweQueue(queue, mask);
|
||||
tmpWorld = new AsyncWorld(player.getWorld(), queue);
|
||||
}
|
||||
if (clickedBlock != null) {
|
||||
clickedBlock = tmpWorld.getBlockAt(clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
|
||||
}
|
||||
}
|
||||
return snipe(action, itemInHand, tmpWorld, clickedBlock, clickedFace);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Old method (plus world arg)
|
||||
public boolean snipe(Action action, Material itemInHand, AsyncWorld world, Block clickedBlock, BlockFace clickedFace) {
|
||||
String toolId = getToolId(itemInHand);
|
||||
SniperTool sniperTool = tools.get(toolId);
|
||||
|
||||
switch (action) {
|
||||
case LEFT_CLICK_AIR:
|
||||
case LEFT_CLICK_BLOCK:
|
||||
case RIGHT_CLICK_AIR:
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sniperTool.hasToolAssigned(itemInHand)) {
|
||||
if (sniperTool.getCurrentBrush() == null) {
|
||||
getPlayer().sendMessage("No Brush selected.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!getPlayer().hasPermission(sniperTool.getCurrentBrush().getPermissionNode())) {
|
||||
getPlayer().sendMessage("You are not allowed to use this brush. You're missing the permission node '" + sniperTool.getCurrentBrush().getPermissionNode() + "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
SnipeData snipeData = sniperTool.getSnipeData();
|
||||
if (getPlayer().isSneaking()) {
|
||||
Block targetBlock;
|
||||
SnipeAction snipeAction = sniperTool.getActionAssigned(itemInHand);
|
||||
|
||||
switch (action) {
|
||||
case LEFT_CLICK_BLOCK:
|
||||
case LEFT_CLICK_AIR:
|
||||
if (clickedBlock != null) {
|
||||
targetBlock = clickedBlock;
|
||||
} else {
|
||||
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
|
||||
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
|
||||
}
|
||||
|
||||
switch (snipeAction) {
|
||||
case ARROW:
|
||||
if (targetBlock != null) {
|
||||
int originalVoxel = snipeData.getVoxelId();
|
||||
snipeData.setVoxelId(targetBlock.getTypeId());
|
||||
SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, new MaterialData(originalVoxel, snipeData.getData()), new MaterialData(snipeData.getVoxelId(), snipeData.getData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().voxel();
|
||||
return true;
|
||||
} else {
|
||||
int originalVoxel = snipeData.getVoxelId();
|
||||
snipeData.setVoxelId(0);
|
||||
SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, new MaterialData(originalVoxel, snipeData.getData()), new MaterialData(snipeData.getVoxelId(), snipeData.getData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().voxel();
|
||||
return true;
|
||||
}
|
||||
case GUNPOWDER:
|
||||
if (targetBlock != null) {
|
||||
byte originalData = snipeData.getData();
|
||||
snipeData.setData(targetBlock.getData());
|
||||
SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, new MaterialData(snipeData.getVoxelId(), originalData), new MaterialData(snipeData.getVoxelId(), snipeData.getData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().data();
|
||||
return true;
|
||||
} else {
|
||||
byte originalData = snipeData.getData();
|
||||
snipeData.setData((byte) 0);
|
||||
SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, new MaterialData(snipeData.getVoxelId(), originalData), new MaterialData(snipeData.getVoxelId(), snipeData.getData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().data();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RIGHT_CLICK_AIR:
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
if (clickedBlock != null) {
|
||||
targetBlock = clickedBlock;
|
||||
} else {
|
||||
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
|
||||
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
|
||||
}
|
||||
|
||||
switch (snipeAction) {
|
||||
case ARROW:
|
||||
if (targetBlock != null) {
|
||||
int originalId = snipeData.getReplaceId();
|
||||
snipeData.setReplaceId(targetBlock.getTypeId());
|
||||
SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, new MaterialData(originalId, snipeData.getReplaceData()), new MaterialData(snipeData.getReplaceId(), snipeData.getReplaceData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().replace();
|
||||
return true;
|
||||
} else {
|
||||
int originalId = snipeData.getReplaceId();
|
||||
snipeData.setReplaceId(0);
|
||||
SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, new MaterialData(originalId, snipeData.getReplaceData()), new MaterialData(snipeData.getReplaceId(), snipeData.getReplaceData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().replace();
|
||||
return true;
|
||||
}
|
||||
case GUNPOWDER:
|
||||
if (targetBlock != null) {
|
||||
byte originalData = snipeData.getReplaceData();
|
||||
snipeData.setReplaceData(targetBlock.getData());
|
||||
SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, new MaterialData(snipeData.getReplaceId(), originalData), new MaterialData(snipeData.getReplaceId(), snipeData.getReplaceData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().replaceData();
|
||||
return true;
|
||||
} else {
|
||||
byte originalData = snipeData.getReplaceData();
|
||||
snipeData.setReplaceData((byte) 0);
|
||||
SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, new MaterialData(snipeData.getReplaceId(), originalData), new MaterialData(snipeData.getReplaceId(), snipeData.getReplaceData()));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
snipeData.getVoxelMessage().replaceData();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Block targetBlock;
|
||||
Block lastBlock;
|
||||
SnipeAction snipeAction = sniperTool.getActionAssigned(itemInHand);
|
||||
|
||||
switch (action) {
|
||||
case RIGHT_CLICK_AIR:
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clickedBlock != null) {
|
||||
targetBlock = clickedBlock;
|
||||
lastBlock = clickedBlock.getRelative(clickedFace);
|
||||
if (lastBlock == null) {
|
||||
getPlayer().sendMessage(ChatColor.RED + "Snipe target block must be visible.");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
|
||||
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
|
||||
lastBlock = rangeBlockHelper.getLastBlock();
|
||||
|
||||
if (targetBlock == null || lastBlock == null) {
|
||||
getPlayer().sendMessage(ChatColor.RED + "Snipe target block must be visible.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (sniperTool.getCurrentBrush() instanceof PerformBrush) {
|
||||
// PerformBrush performerBrush = (PerformBrush) sniperTool.getCurrentBrush();
|
||||
// performerBrush.initP(snipeData);
|
||||
// }
|
||||
//
|
||||
// boolean result = sniperTool.getCurrentBrush().perform(snipeAction, snipeData, targetBlock, lastBlock);
|
||||
// if (result) {
|
||||
// MetricsManager.increaseBrushUsage(sniperTool.getCurrentBrush().getName());
|
||||
// }
|
||||
// return result;
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (sniperTool.getCurrentBrush() instanceof PerformBrush) {
|
||||
PerformBrush performerBrush = (PerformBrush) sniperTool.getCurrentBrush();
|
||||
performerBrush.initP(snipeData);
|
||||
world.commit();
|
||||
}
|
||||
boolean result = sniperTool.getCurrentBrush().perform(snipeAction, snipeData, targetBlock, lastBlock);
|
||||
if (result) {
|
||||
MetricsManager.increaseBrushUsage(sniperTool.getCurrentBrush().getName());
|
||||
}
|
||||
world.commit();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IBrush setBrush(String toolId, Class<? extends IBrush> brush) {
|
||||
if (!tools.containsKey(toolId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tools.get(toolId).setCurrentBrush(brush);
|
||||
}
|
||||
|
||||
public IBrush getBrush(String toolId) {
|
||||
if (!tools.containsKey(toolId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tools.get(toolId).getCurrentBrush();
|
||||
}
|
||||
|
||||
public IBrush previousBrush(String toolId) {
|
||||
if (!tools.containsKey(toolId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tools.get(toolId).previousBrush();
|
||||
}
|
||||
|
||||
public boolean setTool(String toolId, SnipeAction action, Material itemInHand) {
|
||||
for (Map.Entry<String, SniperTool> entry : tools.entrySet()) {
|
||||
if (entry.getKey() != toolId && entry.getValue().hasToolAssigned(itemInHand)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tools.containsKey(toolId)) {
|
||||
SniperTool tool = new SniperTool(this);
|
||||
tools.put(toolId, tool);
|
||||
}
|
||||
tools.get(toolId).assignAction(action, itemInHand);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeTool(String toolId, Material itemInHand) {
|
||||
if (!tools.containsKey(toolId)) {
|
||||
SniperTool tool = new SniperTool(this);
|
||||
tools.put(toolId, tool);
|
||||
}
|
||||
tools.get(toolId).unassignAction(itemInHand);
|
||||
}
|
||||
|
||||
public void removeTool(String toolId) {
|
||||
if (toolId == null) {
|
||||
return;
|
||||
}
|
||||
tools.remove(toolId);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void storeUndo(Undo undo) {
|
||||
if (VoxelSniper.getInstance().getVoxelSniperConfiguration().getUndoCacheSize() <= 0) {
|
||||
return;
|
||||
}
|
||||
if (undo != null && undo.getSize() > 0) {
|
||||
while (undoList.size() >= plugin.getVoxelSniperConfiguration().getUndoCacheSize()) {
|
||||
this.undoList.pollLast();
|
||||
}
|
||||
undoList.push(undo);
|
||||
}
|
||||
}
|
||||
|
||||
public void undo() {
|
||||
undo(1);
|
||||
}
|
||||
|
||||
public void undo(int amount) {
|
||||
int sum = 0;
|
||||
if (this.undoList.isEmpty()) {
|
||||
getPlayer().sendMessage(ChatColor.GREEN + "There's nothing to undo.");
|
||||
} else {
|
||||
for (int x = 0; x < amount && !undoList.isEmpty(); x++) {
|
||||
Undo undo = this.undoList.pop();
|
||||
if (undo != null) {
|
||||
undo.undo();
|
||||
sum += undo.getSize();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
getPlayer().sendMessage(ChatColor.GREEN + "Undo successful: " + ChatColor.RED + sum + ChatColor.GREEN + " blocks have been replaced.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(String toolId) {
|
||||
SniperTool backup = tools.remove(toolId);
|
||||
SniperTool newTool = new SniperTool(this);
|
||||
|
||||
for (Map.Entry<SnipeAction, Material> entry : backup.getActionTools().entrySet()) {
|
||||
newTool.assignAction(entry.getKey(), entry.getValue());
|
||||
}
|
||||
tools.put(toolId, newTool);
|
||||
}
|
||||
|
||||
public SnipeData getSnipeData(String toolId) {
|
||||
return tools.containsKey(toolId) ? tools.get(toolId).getSnipeData() : null;
|
||||
}
|
||||
|
||||
public void displayInfo() {
|
||||
String currentToolId = getCurrentToolId();
|
||||
SniperTool sniperTool = tools.get(currentToolId);
|
||||
IBrush brush = sniperTool.getCurrentBrush();
|
||||
getPlayer().sendMessage("Current Tool: " + ((currentToolId != null) ? currentToolId : "Default Tool"));
|
||||
if (brush == null) {
|
||||
getPlayer().sendMessage("No brush selected.");
|
||||
return;
|
||||
}
|
||||
brush.info(sniperTool.getMessageHelper());
|
||||
if (brush instanceof Performer) {
|
||||
((Performer) brush).showInfo(sniperTool.getMessageHelper());
|
||||
}
|
||||
}
|
||||
|
||||
public SniperTool getSniperTool(String toolId) {
|
||||
return tools.get(toolId);
|
||||
}
|
||||
|
||||
public class SniperTool {
|
||||
private BiMap<SnipeAction, Material> actionTools = HashBiMap.create();
|
||||
private ClassToInstanceMap<IBrush> brushes = MutableClassToInstanceMap.create();
|
||||
private Class<? extends IBrush> currentBrush;
|
||||
private Class<? extends IBrush> previousBrush;
|
||||
private SnipeData snipeData;
|
||||
private Message messageHelper;
|
||||
|
||||
private SniperTool(Sniper owner) {
|
||||
this(SnipeBrush.class, new SnipeData(owner));
|
||||
}
|
||||
|
||||
private SniperTool(Class<? extends IBrush> currentBrush, SnipeData snipeData) {
|
||||
this.snipeData = snipeData;
|
||||
messageHelper = new Message(snipeData);
|
||||
snipeData.setVoxelMessage(messageHelper);
|
||||
|
||||
IBrush newBrushInstance = instanciateBrush(currentBrush);
|
||||
if (snipeData.owner().getPlayer().hasPermission(newBrushInstance.getPermissionNode())) {
|
||||
brushes.put(currentBrush, newBrushInstance);
|
||||
this.currentBrush = currentBrush;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasToolAssigned(Material material) {
|
||||
return actionTools.containsValue(material);
|
||||
}
|
||||
|
||||
public SnipeAction getActionAssigned(Material itemInHand) {
|
||||
return actionTools.inverse().get(itemInHand);
|
||||
}
|
||||
|
||||
public Material getToolAssigned(SnipeAction action) {
|
||||
return actionTools.get(action);
|
||||
}
|
||||
|
||||
public void assignAction(SnipeAction action, Material itemInHand) {
|
||||
actionTools.forcePut(action, itemInHand);
|
||||
}
|
||||
|
||||
public void unassignAction(Material itemInHand) {
|
||||
actionTools.inverse().remove(itemInHand);
|
||||
}
|
||||
|
||||
public BiMap<SnipeAction, Material> getActionTools() {
|
||||
return ImmutableBiMap.copyOf(actionTools);
|
||||
}
|
||||
|
||||
public SnipeData getSnipeData() {
|
||||
return snipeData;
|
||||
}
|
||||
|
||||
public Message getMessageHelper() {
|
||||
return messageHelper;
|
||||
}
|
||||
|
||||
public IBrush getCurrentBrush() {
|
||||
if (currentBrush == null) {
|
||||
return null;
|
||||
}
|
||||
return brushes.getInstance(currentBrush);
|
||||
}
|
||||
|
||||
public IBrush setCurrentBrush(Class<? extends IBrush> brush) {
|
||||
Preconditions.checkNotNull(brush, "Can't set brush to null.");
|
||||
IBrush brushInstance = brushes.get(brush);
|
||||
if (brushInstance == null) {
|
||||
brushInstance = instanciateBrush(brush);
|
||||
Preconditions.checkNotNull(brushInstance, "Could not instanciate brush class.");
|
||||
if (snipeData.owner().getPlayer().hasPermission(brushInstance.getPermissionNode())) {
|
||||
brushes.put(brush, brushInstance);
|
||||
previousBrush = currentBrush;
|
||||
currentBrush = brush;
|
||||
return brushInstance;
|
||||
}
|
||||
}
|
||||
|
||||
if (snipeData.owner().getPlayer().hasPermission(brushInstance.getPermissionNode())) {
|
||||
previousBrush = currentBrush;
|
||||
currentBrush = brush;
|
||||
return brushInstance;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IBrush previousBrush() {
|
||||
if (previousBrush == null) {
|
||||
return null;
|
||||
}
|
||||
return setCurrentBrush(previousBrush);
|
||||
}
|
||||
|
||||
private IBrush instanciateBrush(Class<? extends IBrush> brush) {
|
||||
try {
|
||||
return brush.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return Sniper.class;
|
||||
}
|
||||
}
|
68
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/Undo.java
Normal file
68
bukkit0/src/main/java/com/thevoxelbox/voxelsniper/Undo.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Set;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Holds {@link BlockState}s that can be later on used to reset those block
|
||||
* locations back to the recorded states.
|
||||
*/
|
||||
public class Undo {
|
||||
|
||||
private final Set<Vector> containing = Sets.newHashSet();
|
||||
private final ArrayDeque<BlockState> all;
|
||||
|
||||
private World world;
|
||||
|
||||
/**
|
||||
* Default constructor of a Undo container.
|
||||
*/
|
||||
public Undo() {
|
||||
all = new ArrayDeque<BlockState>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of blocks in the collection.
|
||||
*
|
||||
* @return size of the Undo collection
|
||||
*/
|
||||
public int getSize() {
|
||||
return containing.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Block to the collection.
|
||||
*
|
||||
* @param block Block to be added
|
||||
*/
|
||||
public void put(Block block) {
|
||||
if (world == null) {
|
||||
world = block.getWorld();
|
||||
}
|
||||
Vector pos = block.getLocation().toVector();
|
||||
if (this.containing.contains(pos)) {
|
||||
return;
|
||||
}
|
||||
this.containing.add(pos);
|
||||
all.add(block.getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the blockstates of all recorded blocks back to the state when they
|
||||
* were inserted.
|
||||
*/
|
||||
public void undo() {
|
||||
for (BlockState blockState : all) {
|
||||
blockState.update(true, false);
|
||||
}
|
||||
if (world instanceof AsyncWorld) {
|
||||
((AsyncWorld) world).commit();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.bukkit.v1_8;
|
||||
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
|
||||
@ -19,6 +19,6 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk> {
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return Bukkit.getWorld(getParent().world).getChunkAt(getX(), getZ());
|
||||
return Bukkit.getWorld(getParent().getWorld()).getChunkAt(getX(), getZ());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package com.boydti.fawe.bukkit.v1_9;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -8,7 +8,7 @@ import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
@ -106,7 +106,7 @@ public class FaweAPI {
|
||||
* - The FaweQueue skips a bit of overhead so it's faster<br>
|
||||
* - The WorldEdit EditSession can do a lot more<br>
|
||||
* Remember to enqueue it when you're done!<br>
|
||||
* @see com.boydti.fawe.util.FaweQueue#enqueue()
|
||||
* @see com.boydti.fawe.object.FaweQueue#enqueue()
|
||||
* @param worldName The name of the world
|
||||
* @param autoqueue If it should start dispatching before you enqueue it.
|
||||
* @return
|
||||
|
@ -4,7 +4,7 @@ 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.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
@ -3,7 +3,7 @@ package com.boydti.fawe.command;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
|
@ -4,7 +4,7 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FaweLocation;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
|
@ -3,7 +3,7 @@ package com.boydti.fawe.example;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
|
@ -6,7 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.IntegerPair;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
@ -29,8 +29,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
private LinkedBlockingDeque<FaweChunk> chunks = new LinkedBlockingDeque<FaweChunk>() {
|
||||
@Override
|
||||
public boolean add(FaweChunk o) {
|
||||
if (progressTask != null) {
|
||||
progressTask.run(ProgressType.QUEUE, size() + 1);
|
||||
if (getProgressTask() != null) {
|
||||
getProgressTask().run(ProgressType.QUEUE, size() + 1);
|
||||
}
|
||||
return super.add(o);
|
||||
}
|
||||
@ -93,7 +93,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
if (impWorld != null) {
|
||||
return impWorld;
|
||||
}
|
||||
return impWorld = getWorld(world);
|
||||
return impWorld = getWorld(super.getWorldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -275,8 +275,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
}
|
||||
|
||||
public void runTasks() {
|
||||
if (progressTask != null) {
|
||||
progressTask.run(ProgressType.DONE, 1);
|
||||
if (getProgressTask() != null) {
|
||||
getProgressTask().run(ProgressType.DONE, 1);
|
||||
}
|
||||
ArrayDeque<Runnable> tmp = new ArrayDeque<>(tasks);
|
||||
tasks.clear();
|
||||
@ -306,9 +306,9 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
return false;
|
||||
}
|
||||
// Set blocks / entities / biome
|
||||
if (progressTask != null) {
|
||||
progressTask.run(ProgressType.QUEUE, chunks.size());
|
||||
progressTask.run(ProgressType.DISPATCH, ++dispatched);
|
||||
if (getProgressTask() != null) {
|
||||
getProgressTask().run(ProgressType.QUEUE, chunks.size());
|
||||
getProgressTask().run(ProgressType.DISPATCH, ++dispatched);
|
||||
}
|
||||
if (getChangeTask() != null) {
|
||||
if (!this.setComponents(fc, new RunnableVal<FaweChunk>() {
|
||||
|
@ -3,7 +3,7 @@ package com.boydti.fawe.example;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import java.util.Collection;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
|
@ -2,7 +2,6 @@ package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayDeque;
|
||||
|
@ -1,10 +1,11 @@
|
||||
package com.boydti.fawe.util;
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
@ -15,7 +16,17 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
public abstract class FaweQueue {
|
||||
|
||||
public static enum ProgressType {
|
||||
private final String world;
|
||||
private LinkedBlockingDeque<EditSession> sessions;
|
||||
private long modified = System.currentTimeMillis();
|
||||
private RunnableVal2<FaweChunk, FaweChunk> changeTask;
|
||||
private RunnableVal2<ProgressType, Integer> progressTask;
|
||||
|
||||
public FaweQueue(String world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public enum ProgressType {
|
||||
QUEUE,
|
||||
DISPATCH,
|
||||
DONE,
|
||||
@ -28,24 +39,18 @@ public abstract class FaweQueue {
|
||||
ALL,
|
||||
}
|
||||
|
||||
public final String world;
|
||||
public LinkedBlockingDeque<EditSession> sessions;
|
||||
public long modified = System.currentTimeMillis();
|
||||
public RunnableVal2<FaweChunk, FaweChunk> changeTask;
|
||||
public RunnableVal2<ProgressType, Integer> progressTask;
|
||||
|
||||
public FaweQueue(String world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void addEditSession(EditSession session) {
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
if (this.sessions == null) {
|
||||
sessions = new LinkedBlockingDeque<>();
|
||||
if (this.getSessions() == null) {
|
||||
setSessions(new LinkedBlockingDeque<EditSession>());
|
||||
}
|
||||
sessions.add(session);
|
||||
getSessions().add(session);
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,11 +60,35 @@ public abstract class FaweQueue {
|
||||
* @param progressTask
|
||||
*/
|
||||
public void setProgressTracker(RunnableVal2<ProgressType, Integer> progressTask) {
|
||||
this.progressTask = progressTask;
|
||||
this.setProgressTask(progressTask);
|
||||
}
|
||||
|
||||
public Set<EditSession> getEditSessions() {
|
||||
return sessions == null ? new HashSet<EditSession>() : new HashSet<>(sessions);
|
||||
return getSessions() == null ? new HashSet<EditSession>() : new HashSet<>(getSessions());
|
||||
}
|
||||
|
||||
public LinkedBlockingDeque<EditSession> getSessions() {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public void setSessions(LinkedBlockingDeque<EditSession> sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
public long getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(long modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public RunnableVal2<ProgressType, Integer> getProgressTask() {
|
||||
return progressTask;
|
||||
}
|
||||
|
||||
public void setProgressTask(RunnableVal2<ProgressType, Integer> progressTask) {
|
||||
this.progressTask = progressTask;
|
||||
}
|
||||
|
||||
public void setChangeTask(RunnableVal2<FaweChunk, FaweChunk> changeTask) {
|
||||
@ -99,7 +128,7 @@ public abstract class FaweQueue {
|
||||
public int cancel() {
|
||||
clear();
|
||||
int count = 0;
|
||||
for (EditSession session : sessions) {
|
||||
for (EditSession session : getSessions()) {
|
||||
if (session.cancel()) {
|
||||
count++;
|
||||
}
|
@ -2,7 +2,6 @@ package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
|
@ -0,0 +1,45 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.util.DelegateFaweQueue;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
public class MaskedFaweQueue extends DelegateFaweQueue {
|
||||
private final RegionWrapper[] mask;
|
||||
|
||||
public MaskedFaweQueue(FaweQueue parent, RegionWrapper[] mask) {
|
||||
super(parent);
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tag) {
|
||||
if (WEManager.IMP.maskContains(mask, x, z)) {
|
||||
super.setTile(x, y, z, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(int x, int y, int z, CompoundTag tag) {
|
||||
if (WEManager.IMP.maskContains(mask, x, z)) {
|
||||
super.setEntity(x, y, z, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, short id, byte data) {
|
||||
if (WEManager.IMP.maskContains(mask, x, z)) {
|
||||
return super.setBlock(x, y, z, id, data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BaseBiome biome) {
|
||||
if (WEManager.IMP.maskContains(mask, x, z)) {
|
||||
return super.setBiome(x, z, biome);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package com.boydti.fawe.object.changeset;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.change.MutableChunkChange;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
@ -5,7 +5,7 @@ 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.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
|
@ -4,7 +4,7 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
|
||||
|
211
core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
Normal file
211
core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
Normal file
@ -0,0 +1,211 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
public class DelegateFaweQueue extends FaweQueue {
|
||||
private final FaweQueue parent;
|
||||
|
||||
public DelegateFaweQueue(FaweQueue parent) {
|
||||
super(parent.getWorldName());
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorldName() {
|
||||
return parent.getWorldName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEditSession(EditSession session) {
|
||||
parent.addEditSession(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressTracker(RunnableVal2<ProgressType, Integer> progressTask) {
|
||||
parent.setProgressTracker(progressTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<EditSession> getEditSessions() {
|
||||
return parent.getEditSessions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedBlockingDeque<EditSession> getSessions() {
|
||||
return parent.getSessions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessions(LinkedBlockingDeque<EditSession> sessions) {
|
||||
parent.setSessions(sessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getModified() {
|
||||
return parent.getModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(long modified) {
|
||||
parent.setModified(modified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunnableVal2<ProgressType, Integer> getProgressTask() {
|
||||
return parent.getProgressTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressTask(RunnableVal2<ProgressType, Integer> progressTask) {
|
||||
parent.setProgressTask(progressTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangeTask(RunnableVal2<FaweChunk, FaweChunk> changeTask) {
|
||||
parent.setChangeTask(changeTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunnableVal2<FaweChunk, FaweChunk> getChangeTask() {
|
||||
return parent.getChangeTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optimize() {
|
||||
parent.optimize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, short id, byte data) {
|
||||
return parent.setBlock(x, y, z, id, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tag) {
|
||||
parent.setTile(x, y, z, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(int x, int y, int z, CompoundTag tag) {
|
||||
parent.setEntity(x, y, z, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
parent.removeEntity(x, y, z, uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BaseBiome biome) {
|
||||
return parent.setBiome(x, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk<?> getFaweChunk(int x, int z) {
|
||||
return parent.getFaweChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunk(FaweChunk<?> chunk) {
|
||||
parent.setChunk(chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixLighting(FaweChunk<?> chunk, RelightMode mode) {
|
||||
return parent.fixLighting(chunk, mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return parent.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
return parent.regenerateChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSet(boolean parallel) {
|
||||
parent.startSet(parallel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endSet(boolean parallel) {
|
||||
parent.endSet(parallel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cancel() {
|
||||
return parent.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk next() {
|
||||
return parent.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveMemory() {
|
||||
parent.saveMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(FaweChunk chunk, RelightMode mode) {
|
||||
parent.sendChunk(chunk, mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
parent.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotifyTask(int x, int z, Runnable runnable) {
|
||||
parent.addNotifyTask(x, z, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotifyTask(Runnable runnable) {
|
||||
parent.addNotifyTask(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
return parent.getCombinedId4Data(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
return parent.getTileEntity(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(int x, int y, int z, int def) {
|
||||
return parent.getCombinedId4Data(x, y, z, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4DataDebug(int x, int y, int z, int def, EditSession session) {
|
||||
return parent.getCombinedId4DataDebug(x, y, z, def, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return parent.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue() {
|
||||
parent.enqueue();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package com.boydti.fawe.util;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
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.List;
|
||||
@ -178,7 +179,7 @@ public class SetQueue {
|
||||
while (activeQueues.size() > 0) {
|
||||
FaweQueue queue = activeQueues.peek();
|
||||
if (queue != null && queue.size() > 0) {
|
||||
queue.modified = System.currentTimeMillis();
|
||||
queue.setModified(System.currentTimeMillis());
|
||||
return queue;
|
||||
} else {
|
||||
activeQueues.poll();
|
||||
@ -190,10 +191,10 @@ public class SetQueue {
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastSuccess != 0) {
|
||||
for (FaweQueue queue : tmp) {
|
||||
if (queue != null && queue.size() > 0 && now - queue.modified > Settings.QUEUE_MAX_WAIT) {
|
||||
queue.modified = now;
|
||||
if (queue != null && queue.size() > 0 && now - queue.getModified() > Settings.QUEUE_MAX_WAIT) {
|
||||
queue.setModified(now);
|
||||
return queue;
|
||||
} else if (now - queue.modified > Settings.QUEUE_DISCARD_AFTER) {
|
||||
} else if (now - queue.getModified() > Settings.QUEUE_DISCARD_AFTER) {
|
||||
inactiveQueues.remove(queue);
|
||||
}
|
||||
}
|
||||
@ -207,7 +208,7 @@ public class SetQueue {
|
||||
if (total > Settings.QUEUE_SIZE) {
|
||||
for (FaweQueue queue : tmp) {
|
||||
if (queue != null && queue.size() > 0) {
|
||||
queue.modified = System.currentTimeMillis();
|
||||
queue.setModified(System.currentTimeMillis());
|
||||
return queue;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
|
@ -41,7 +41,7 @@ import com.boydti.fawe.object.extent.MemoryCheckingExtent;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.ProcessedWEExtent;
|
||||
import com.boydti.fawe.object.progress.DefaultProgressTracker;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.Perm;
|
||||
|
@ -23,7 +23,7 @@ import com.boydti.fawe.config.Settings;
|
||||
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.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
|
@ -25,7 +25,7 @@ import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.NullChangeSet;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.google.common.base.Joiner;
|
||||
|
@ -8,7 +8,7 @@ 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.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
|
@ -2,7 +2,7 @@ package com.boydti.fawe.forge.v0;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
@ -8,7 +8,7 @@ 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.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.forge.v0;
|
||||
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.sponge.v1_8.SpongeQueue_1_8;
|
||||
import com.boydti.fawe.sponge.v1_8.SpongeQueue_ALL;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.sponge.v1_8;
|
||||
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
@ -13,7 +13,7 @@ public class SpongeChunk_1_8 extends CharFaweChunk<net.minecraft.world.chunk.Chu
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.chunk.Chunk getNewChunk() {
|
||||
World world = Sponge.getServer().getWorld(getParent().world).get();
|
||||
World world = Sponge.getServer().getWorld(getParent().getWorld()).get();
|
||||
return (net.minecraft.world.chunk.Chunk) world.loadChunk(getX(), 0, getZ(), true).get();
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
|
||||
@Override
|
||||
public World getWorld(String world) {
|
||||
return Sponge.getServer().getWorld(this.world).get();
|
||||
return Sponge.getServer().getWorld(super.getWorld()).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -179,7 +179,7 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
|
||||
|
||||
@Override
|
||||
public World getWorld(String world) {
|
||||
return Sponge.getServer().getWorld(this.world).get();
|
||||
return Sponge.getServer().getWorld(super.getWorld()).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user