Remove CUI and other cleaning

This commit is contained in:
MattBDev 2019-06-06 18:39:51 -04:00
parent b42553116c
commit 229182aa63
28 changed files with 574 additions and 2653 deletions

View File

@ -25,7 +25,6 @@ import com.boydti.fawe.bukkit.util.BukkitTaskMan;
import com.boydti.fawe.bukkit.util.ItemUtil; import com.boydti.fawe.bukkit.util.ItemUtil;
import com.boydti.fawe.bukkit.util.VaultUtil; import com.boydti.fawe.bukkit.util.VaultUtil;
import com.boydti.fawe.bukkit.util.cui.CUIListener; import com.boydti.fawe.bukkit.util.cui.CUIListener;
import com.boydti.fawe.bukkit.util.cui.StructureCUI;
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer; import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_All; import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
@ -41,7 +40,6 @@ import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.Jars; import com.boydti.fawe.util.Jars;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.cui.CUI;
import com.boydti.fawe.util.image.ImageViewer; import com.boydti.fawe.util.image.ImageViewer;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -64,7 +62,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public class FaweBukkit implements IFawe, Listener { public class FaweBukkit implements IFawe, Listener {
@ -149,32 +146,6 @@ public class FaweBukkit implements IFawe, Listener {
}); });
} }
@Override
public CUI getCUI(FawePlayer player) {
if (Settings.IMP.EXPERIMENTAL.VANILLA_CUI) {
if (listeningCui && cuiListener == null) return null;
listeningCui = true;
if (cuiListener == null) {
Plugin protocolLib = Bukkit.getPluginManager().getPlugin("ProtocolLib");
if (protocolLib != null && protocolLib.isEnabled()) {
cuiListener = new CUIListener(plugin);
} else {
return null;
}
}
return new StructureCUI(player);
}
return null;
}
@Override
public void registerPacketListener() {
PluginManager manager = Bukkit.getPluginManager();
if (packetListener == null && manager.getPlugin("ProtocolLib") != null) {
packetListener = new CFIPacketListener(plugin);
}
}
@Override @Override
public synchronized ImageViewer getImageViewer(FawePlayer fp) { public synchronized ImageViewer getImageViewer(FawePlayer fp) {
if (listeningImages && imageListener == null) return null; if (listeningImages && imageListener == null) return null;

View File

@ -69,6 +69,7 @@ public class StructureCUI extends CUI {
private int viewDistance() { private int viewDistance() {
Player player = this.<Player>getPlayer().parent; Player player = this.<Player>getPlayer().parent;
//todo replace with PaperLib.isPaper()
if (Bukkit.getVersion().contains("paper")) { if (Bukkit.getVersion().contains("paper")) {
return player.getViewDistance(); return player.getViewDistance();
} else { } else {

View File

@ -56,8 +56,8 @@ import org.bukkit.inventory.ItemStack;
* Adapts between Bukkit and WorldEdit equivalent objects. * Adapts between Bukkit and WorldEdit equivalent objects.
*/ */
public enum BukkitAdapter { public enum BukkitAdapter {
INSTANCE INSTANCE;
;
private final IBukkitAdapter adapter; private final IBukkitAdapter adapter;
BukkitAdapter() { BukkitAdapter() {
@ -73,14 +73,36 @@ public enum BukkitAdapter {
return INSTANCE.adapter; return INSTANCE.adapter;
} }
/**
* Checks equality between a WorldEdit BlockType and a Bukkit Material
*
* @param blockType The WorldEdit BlockType
* @param type The Bukkit Material
* @return If they are equal
*/
public static boolean equals(BlockType blockType, Material type) { public static boolean equals(BlockType blockType, Material type) {
return getAdapter().equals(blockType, type); return getAdapter().equals(blockType, type);
} }
/**
* Convert any WorldEdit world into an equivalent wrapped Bukkit world.
*
* <p>If a matching world cannot be found, a {@link RuntimeException}
* will be thrown.</p>
*
* @param world the world
* @return a wrapped Bukkit world
*/
public static BukkitWorld asBukkitWorld(World world) { public static BukkitWorld asBukkitWorld(World world) {
return getAdapter().asBukkitWorld(world); return getAdapter().asBukkitWorld(world);
} }
/**
* Create a WorldEdit world from a Bukkit world.
*
* @param world the Bukkit world
* @return a WorldEdit world
*/
public static World adapt(org.bukkit.World world) { public static World adapt(org.bukkit.World world) {
return getAdapter().adapt(world); return getAdapter().adapt(world);
} }
@ -89,23 +111,48 @@ public enum BukkitAdapter {
return getAdapter().adapt(world); return getAdapter().adapt(world);
} }
/**
* Create a WorldEdit location from a Bukkit location.
*
* @param location the Bukkit location
* @return a WorldEdit location
*/
public static Location adapt(org.bukkit.Location location) { public static Location adapt(org.bukkit.Location location) {
checkNotNull(location);
return getAdapter().adapt(location); return getAdapter().adapt(location);
} }
/**
* Create a Bukkit location from a WorldEdit location.
*
* @param location the WorldEdit location
* @return a Bukkit location
*/
public static org.bukkit.Location adapt(Location location) { public static org.bukkit.Location adapt(Location location) {
checkNotNull(location);
return getAdapter().adapt(location); return getAdapter().adapt(location);
} }
public static org.bukkit.Location adapt(org.bukkit.World world, Vector3 position) { public static org.bukkit.Location adapt(org.bukkit.World world, Vector3 position) {
return getAdapter().adapt(world, position); return getAdapter().adapt(world, position);
} }
public static org.bukkit.Location adapt(org.bukkit.World world, BlockVector3 position) { public static org.bukkit.Location adapt(org.bukkit.World world, BlockVector3 position) {
checkNotNull(world);
checkNotNull(position);
return getAdapter().adapt(world, position); return getAdapter().adapt(world, position);
} }
/**
* Create a Bukkit location from a WorldEdit location with a Bukkit world.
*
* @param world the Bukkit world
* @param location the WorldEdit location
* @return a Bukkit location
*/
public static org.bukkit.Location adapt(org.bukkit.World world, Location location) { public static org.bukkit.Location adapt(org.bukkit.World world, Location location) {
checkNotNull(world);
checkNotNull(location);
return getAdapter().adapt(world, location); return getAdapter().adapt(world, location);
} }
@ -113,23 +160,58 @@ public enum BukkitAdapter {
return getAdapter().asVector(location); return getAdapter().asVector(location);
} }
/**
* Create a WorldEdit Vector from a Bukkit location.
*
* @param location The Bukkit location
* @return a WorldEdit vector
*/
public static BlockVector3 asBlockVector(org.bukkit.Location location) { public static BlockVector3 asBlockVector(org.bukkit.Location location) {
checkNotNull(location);
return getAdapter().asBlockVector(location); return getAdapter().asBlockVector(location);
} }
/**
* Create a WorldEdit entity from a Bukkit entity.
*
* @param entity the Bukkit entity
* @return a WorldEdit entity
*/
public static Entity adapt(org.bukkit.entity.Entity entity) { public static Entity adapt(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
return getAdapter().adapt(entity); return getAdapter().adapt(entity);
} }
/**
* Create a Bukkit Material form a WorldEdit ItemType
*
* @param itemType The WorldEdit ItemType
* @return The Bukkit Material
*/
public static Material adapt(ItemType itemType) { public static Material adapt(ItemType itemType) {
checkNotNull(itemType);
return getAdapter().adapt(itemType); return getAdapter().adapt(itemType);
} }
/**
* Create a Bukkit Material form a WorldEdit BlockType
*
* @param blockType The WorldEdit BlockType
* @return The Bukkit Material
*/
public static Material adapt(BlockType blockType) { public static Material adapt(BlockType blockType) {
checkNotNull(blockType);
return getAdapter().adapt(blockType); return getAdapter().adapt(blockType);
} }
/**
* Create a WorldEdit GameMode from a Bukkit one.
*
* @param gameMode Bukkit GameMode
* @return WorldEdit GameMode
*/
public static GameMode adapt(org.bukkit.GameMode gameMode) { public static GameMode adapt(org.bukkit.GameMode gameMode) {
checkNotNull(gameMode);
return getAdapter().adapt(gameMode); return getAdapter().adapt(gameMode);
} }
@ -161,15 +243,37 @@ public enum BukkitAdapter {
return getAdapter().adapt(entityType); return getAdapter().adapt(entityType);
} }
/**
* Converts a Material to a BlockType
*
* @param material The material
* @return The blocktype
*/
public static BlockType asBlockType(Material material) { public static BlockType asBlockType(Material material) {
checkNotNull(material);
return getAdapter().asBlockType(material); return getAdapter().asBlockType(material);
} }
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
public static ItemType asItemType(Material material) { public static ItemType asItemType(Material material) {
checkNotNull(material);
return getAdapter().asItemType(material); return getAdapter().asItemType(material);
} }
/**
* Create a WorldEdit BlockState from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
public static BlockState adapt(BlockData blockData) { public static BlockState adapt(BlockData blockData) {
checkNotNull(blockData);
return getAdapter().adapt(blockData); return getAdapter().adapt(blockData);
} }
@ -183,7 +287,8 @@ public enum BukkitAdapter {
* @param block The WorldEdit BlockStateHolder * @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData * @return The Bukkit BlockData
*/ */
public static <B extends BlockStateHolder<B>> BlockData adapt(B block) { public static BlockData adapt(BlockStateHolder block) {
checkNotNull(block);
return getAdapter().adapt(block); return getAdapter().adapt(block);
} }
@ -191,15 +296,40 @@ public enum BukkitAdapter {
return getAdapter().getBlockData(combinedId); return getAdapter().getBlockData(combinedId);
} }
public static BlockState asBlockState(ItemStack itemStack) { /**
return getAdapter().asBlockState(itemStack); * Create a WorldEdit BlockState from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BlockState
*/
public static BlockState asBlockState(ItemStack itemStack) throws WorldEditException {
checkNotNull(itemStack);
if (itemStack.getType().isBlock()) {
return getAdapter().asBlockState(itemStack);
} else {
throw new NotABlockException();
}
} }
/**
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BaseItemStack
*/
public static BaseItemStack adapt(ItemStack itemStack) { public static BaseItemStack adapt(ItemStack itemStack) {
checkNotNull(itemStack);
return getAdapter().adapt(itemStack); return getAdapter().adapt(itemStack);
} }
/**
* Create a Bukkit ItemStack from a WorldEdit BaseItemStack
*
* @param item The WorldEdit BaseItemStack
* @return The Bukkit ItemStack
*/
public static ItemStack adapt(BaseItemStack item) { public static ItemStack adapt(BaseItemStack item) {
checkNotNull(item);
return getAdapter().adapt(item); return getAdapter().adapt(item);
} }

View File

@ -109,8 +109,8 @@ public class BukkitPlayer extends AbstractPlayerActor {
if (itemStack.getType().getId().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { if (itemStack.getType().getId().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) {
inv.remove(newItem); inv.remove(newItem);
} }
final ItemStack item = player.getItemInHand(); final ItemStack item = player.getInventory().getItemInMainHand();
player.setItemInHand(newItem); player.getInventory().setItemInMainHand(newItem);
HashMap<Integer, ItemStack> overflow = inv.addItem(item); HashMap<Integer, ItemStack> overflow = inv.addItem(item);
if (!overflow.isEmpty()) { if (!overflow.isEmpty()) {
TaskManager.IMP.sync(new RunnableVal<Object>() { TaskManager.IMP.sync(new RunnableVal<Object>() {
@ -216,7 +216,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
if (params.length > 0) { if (params.length > 0) {
send = send + "|" + StringUtil.joinString(params, "|"); send = send + "|" + StringUtil.joinString(params, "|");
} }
player.sendPluginMessage(plugin, WorldEditPlugin.getCuiPluginChannel(), send.getBytes(CUIChannelListener.UTF_8_CHARSET)); player.sendPluginMessage(plugin, WorldEditPlugin.CUI_PLUGIN_CHANNEL, send.getBytes(CUIChannelListener.UTF_8_CHARSET));
} }
public Player getPlayer() { public Player getPlayer() {
@ -305,7 +305,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
} }
@Override @Override
public void sendFakeBlock(BlockVector3 pos, BlockStateHolder block) { public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
Location loc = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ()); Location loc = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ());
if (block == null) { if (block == null) {
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData()); player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());

View File

@ -100,7 +100,7 @@ public class BukkitServerInterface implements MultiUserPlatform {
return player; return player;
} else { } else {
org.bukkit.entity.Player bukkitPlayer = server.getPlayerExact(player.getName()); org.bukkit.entity.Player bukkitPlayer = server.getPlayerExact(player.getName());
return bukkitPlayer != null ? plugin.wrapPlayer(bukkitPlayer) : null; return bukkitPlayer != null ? WorldEditPlugin.getInstance().wrapPlayer(bukkitPlayer) : null;
} }
} }
@ -119,7 +119,7 @@ public class BukkitServerInterface implements MultiUserPlatform {
public void registerCommands(Dispatcher dispatcher) { public void registerCommands(Dispatcher dispatcher) {
List<CommandInfo> toRegister = new ArrayList<>(); List<CommandInfo> toRegister = new ArrayList<>();
BukkitCommandInspector inspector = new BukkitCommandInspector(plugin, dispatcher); BukkitCommandInspector inspector = new BukkitCommandInspector(plugin, dispatcher);
for (CommandMapping command : dispatcher.getCommands()) { for (CommandMapping command : dispatcher.getCommands()) {
Description description = command.getDescription(); Description description = command.getDescription();
List<String> permissions = description.getPermissions(); List<String> permissions = description.getPermissions();
@ -177,7 +177,7 @@ public class BukkitServerInterface implements MultiUserPlatform {
public Collection<Actor> getConnectedUsers() { public Collection<Actor> getConnectedUsers() {
List<Actor> users = new ArrayList<>(); List<Actor> users = new ArrayList<>();
for (org.bukkit.entity.Player player : Bukkit.getServer().getOnlinePlayers()) { for (org.bukkit.entity.Player player : Bukkit.getServer().getOnlinePlayers()) {
users.add(plugin.wrapPlayer(player)); users.add(WorldEditPlugin.getInstance().wrapPlayer(player));
} }
return users; return users;
} }

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.bukkit; package com.sk89q.worldedit.bukkit;
import com.bekvon.bukkit.residence.commands.message;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit; import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2; import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
@ -34,47 +33,35 @@ import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader; import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent; import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory; import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory; import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.File; import java.io.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -111,7 +98,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
lookupNamesField.setAccessible(true); lookupNamesField.setAccessible(true);
List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager); List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager);
lookupNames = (Map<String, Plugin>) lookupNamesField.get(manager); lookupNames = (Map<String, Plugin>) lookupNamesField.get(manager);
pluginsField.set(manager, plugins = new ArrayList<Plugin>(plugins) { pluginsField.set(manager, new ArrayList<Plugin>(plugins) {
@Override @Override
public boolean add(Plugin plugin) { public boolean add(Plugin plugin) {
if (plugin.getName().startsWith("AsyncWorldEdit")) { if (plugin.getName().startsWith("AsyncWorldEdit")) {
@ -126,7 +113,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}); });
lookupNamesField.set(manager, lookupNames = new ConcurrentHashMap<String, Plugin>(lookupNames) { lookupNamesField.set(manager, lookupNames = new ConcurrentHashMap<String, Plugin>(lookupNames) {
@Override @Override
public Plugin put(String key, Plugin plugin) { public Plugin put(@NotNull String key, @NotNull Plugin plugin) {
if (plugin.getName().startsWith("AsyncWorldEdit") || plugin.getName().startsWith("BetterShutdown")) { if (plugin.getName().startsWith("AsyncWorldEdit") || plugin.getName().startsWith("BetterShutdown")) {
return null; return null;
} }
@ -157,15 +144,11 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
setEnabled(true); setEnabled(true);
} }
public static String getCuiPluginChannel() {
return CUI_PLUGIN_CHANNEL;
}
@Override @Override
public void onLoad() { public void onLoad() {
if (INSTANCE != null) return; if (INSTANCE != null) return;
rename(); rename();
this.INSTANCE = this; INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this); FaweBukkit imp = new FaweBukkit(this);
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
@ -190,6 +173,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
if (INSTANCE != null) return; if (INSTANCE != null) return;
onLoad(); onLoad();
setupTags(); // these have to be done post-world since they rely on MC registries. the other ones just use Bukkit enums setupTags(); // these have to be done post-world since they rely on MC registries. the other ones just use Bukkit enums
//TODO: FAWE -- This needs to be moved to onLoad()
setupRegistries(); setupRegistries();
WorldEdit.getInstance().loadMappings(); WorldEdit.getInstance().loadMappings();
@ -226,28 +210,30 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
} }
// Block & Item // Block & Item
for (Material material : Material.values()) { for (Material material : Material.values()) {
// if (material.isBlock() && !material.isLegacy()) { /*
// BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> { if (material.isBlock() && !material.isLegacy()) {
// // TODO Use something way less hacky than this. BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
// ParserContext context = new ParserContext(); // TODO Use something way less hacky than this.
// context.setPreferringWildcard(true); ParserContext context = new ParserContext();
// context.setTryLegacy(false); context.setPreferringWildcard(true);
// context.setRestricted(false); context.setTryLegacy(false);
// try { context.setRestricted(false);
// FuzzyBlockState state = (FuzzyBlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput( try {
// BukkitAdapter.adapt(blockState.getBlockType()).createBlockData().getAsString(), context FuzzyBlockState state = (FuzzyBlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(
// ).toImmutableState(); BukkitAdapter.adapt(blockState.getBlockType()).createBlockData().getAsString(), context
// BlockState defaultState = blockState.getBlockType().getAllStates().get(0); ).toImmutableState();
// for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) { BlockState defaultState = blockState.getBlockType().getAllStates().get(0);
// defaultState = defaultState.with((Property) propertyObjectEntry.getKey(), propertyObjectEntry.getValue()); for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) {
// } defaultState = defaultState.with((Property) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
// return defaultState; }
// } catch (InputParseException e) { return defaultState;
// e.printStackTrace(); } catch (InputParseException e) {
// return blockState; e.printStackTrace();
// } return blockState;
// })); }
// } }));
}
*/
if (material.isItem() && !material.isLegacy()) { if (material.isItem() && !material.isLegacy()) {
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString())); ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
} }
@ -276,63 +262,30 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
} }
private void rename() { private void rename() {
// { File dir = getDataFolder();
// PluginDescriptionFile desc = getDescription(); dir = new File(dir.getParentFile(), "FastAsyncWorldEdit");
// if (desc != null) { try {
// try { Field descriptionField = JavaPlugin.class.getDeclaredField("dataFolder");
// Field nameField = PluginDescriptionFile.class.getDeclaredField("name"); descriptionField.setAccessible(true);
// nameField.setAccessible(true); descriptionField.set(this, dir);
// nameField.set(desc, "FastAsyncWorldEdit"); } catch (Throwable throwable) {
// Field descriptionField = JavaPlugin.class.getDeclaredField("description"); throwable.printStackTrace();
// descriptionField.setAccessible(true);
// descriptionField.set(this, desc);
// } catch (Throwable ignore) {
// ignore.printStackTrace();
// }
// }
// }
{
File dir = getDataFolder();
if (dir != null) {
dir = new File(dir.getParentFile(), "FastAsyncWorldEdit");
try {
Field descriptionField = JavaPlugin.class.getDeclaredField("dataFolder");
descriptionField.setAccessible(true);
descriptionField.set(this, dir);
} catch (Throwable ignore) {
ignore.printStackTrace();
}
}
} }
// { File pluginsFolder = MainUtil.getJarFile().getParentFile();
// Logger logger = getLogger(); for (File file : pluginsFolder.listFiles()) {
// if (logger != null) { if (file.length() == 1988) return;
// try { }
// Field nameField = Logger.class.getDeclaredField("name"); Plugin plugin = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
// nameField.setAccessible(true); File dummy = MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "DummyFawe.jar");
// nameField.set(logger, "FastAsyncWorldEdit"); if (dummy != null && dummy.exists() && plugin == this) {
// } catch (Throwable ignore) { try {
// ignore.printStackTrace(); Bukkit.getPluginManager().loadPlugin(dummy);
// } } catch (Throwable e) {
// } e.printStackTrace();
// }
{
File pluginsFolder = MainUtil.getJarFile().getParentFile();
for (File file : pluginsFolder.listFiles()) {
if (file.length() == 1988) return;
}
Plugin plugin = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
File dummy = MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "DummyFawe.jar");
if (dummy != null && dummy.exists() && plugin == this) {
try {
Bukkit.getPluginManager().loadPlugin(dummy);
} catch (Throwable e) {
e.printStackTrace();
}
getLogger().info("Please restart the server if you have any plugins which depend on FAWE.");
} else if (dummy == null) {
MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "update" + File.separator + "DummyFawe.jar");
} }
getLogger().info("Please restart the server if you have any plugins which depend on FAWE.");
} else if (dummy == null) {
MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "update" + File.separator + "DummyFawe.jar");
} }
} }
@ -470,20 +423,20 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
return true; return true;
} }
// @Deprecated Using Async tab complete (rather than main thread) /*
// @Override @Override
// public List<String> onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) { public List<String> onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) {
// // Add the command to the array because the underlying command handling // Add the command to the array because the underlying command handling
// // code of WorldEdit expects it // code of WorldEdit expects it
// String[] split = new String[args.length + 1]; String[] split = new String[args.length + 1];
// System.arraycopy(args, 0, split, 1, args.length); System.arraycopy(args, 0, split, 1, args.length);
// split[0] = cmd.getName(); split[0] = cmd.getName();
//
// CommandSuggestionEvent event = new CommandSuggestionEvent(wrapCommandSender(sender), Joiner.on(" ").join(split)); CommandSuggestionEvent event = new CommandSuggestionEvent(wrapCommandSender(sender), Joiner.on(" ").join(split));
// getWorldEdit().getEventBus().post(event); getWorldEdit().getEventBus().post(event);
// return event.getSuggestions();
// return event.getSuggestions(); }
// } */
/** /**
* Gets the session for the player. * Gets the session for the player.

View File

@ -9,7 +9,6 @@ import com.boydti.fawe.regions.general.plot.PlotSquaredFeature;
import com.boydti.fawe.util.*; import com.boydti.fawe.util.*;
import com.boydti.fawe.util.chat.ChatManager; import com.boydti.fawe.util.chat.ChatManager;
import com.boydti.fawe.util.chat.PlainChatManager; import com.boydti.fawe.util.chat.PlainChatManager;
import com.boydti.fawe.util.cui.CUI;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.DefaultTransformParser; import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
@ -199,25 +198,6 @@ public class Fawe {
public void onDisable() { public void onDisable() {
} }
public CUI getCUI(Actor actor) {
FawePlayer<Object> fp = FawePlayer.wrap(actor);
CUI cui = fp.getMeta("CUI");
if (cui == null) {
cui = Fawe.imp().getCUI(fp);
if (cui != null) {
synchronized (fp) {
CUI tmp = fp.getMeta("CUI");
if (tmp == null) {
fp.setMeta("CUI", cui);
} else {
cui = tmp;
}
}
}
}
return cui;
}
public ChatManager getChatManager() { public ChatManager getChatManager() {
return chatManager; return chatManager;
} }
@ -315,11 +295,10 @@ public class Fawe {
Settings.IMP.PLATFORM = IMP.getPlatform().replace("\"", ""); Settings.IMP.PLATFORM = IMP.getPlatform().replace("\"", "");
try (InputStream stream = getClass().getResourceAsStream("/fawe.properties"); try (InputStream stream = getClass().getResourceAsStream("/fawe.properties");
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) { BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
// java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
String versionString = br.readLine(); String versionString = br.readLine();
String commitString = br.readLine(); String commitString = br.readLine();
String dateString = br.readLine(); String dateString = br.readLine();
// scanner.close(); br.close();
this.version = FaweVersion.tryParse(versionString, commitString, dateString); this.version = FaweVersion.tryParse(versionString, commitString, dateString);
Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toGMTString(); Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toGMTString();
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-Breaking/" + version.build; Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-Breaking/" + version.build;
@ -381,7 +360,7 @@ public class Fawe {
try { try {
String arch = System.getenv("PROCESSOR_ARCHITECTURE"); String arch = System.getenv("PROCESSOR_ARCHITECTURE");
String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432"); String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
boolean x86OS = arch.endsWith("64") || wow64Arch != null && wow64Arch.endsWith("64") ? false : true; boolean x86OS = !arch.endsWith("64") && (wow64Arch == null || !wow64Arch.endsWith("64"));
boolean x86JVM = System.getProperty("sun.arch.data.model").equals("32"); boolean x86JVM = System.getProperty("sun.arch.data.model").equals("32");
if (x86OS != x86JVM) { if (x86OS != x86JVM) {
debug("====== UPGRADE TO 64-BIT JAVA ======"); debug("====== UPGRADE TO 64-BIT JAVA ======");

View File

@ -5,7 +5,6 @@ import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager; import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.cui.CUI;
import com.boydti.fawe.util.image.ImageViewer; import com.boydti.fawe.util.image.ImageViewer;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -36,12 +35,8 @@ public interface IFawe {
void startMetrics(); void startMetrics();
default CUI getCUI(FawePlayer player) { return null; }
default ImageViewer getImageViewer(FawePlayer player) { return null; } default ImageViewer getImageViewer(FawePlayer player) { return null; }
default void registerPacketListener() {}
default int getPlayerCount() { default int getPlayerCount() {
return Fawe.get().getCachedPlayers().size(); return Fawe.get().getCachedPlayers().size();
} }

View File

@ -65,12 +65,9 @@ public class PlotLoader {
area.setMeta("lastPlot", new PlotId(0, 0)); area.setMeta("lastPlot", new PlotId(0, 0));
} }
PlotId lastId = (PlotId) area.getMeta("lastPlot"); PlotId lastId = (PlotId) area.getMeta("lastPlot");
while (true) { do {
lastId = Auto.getNextPlotId(lastId, 1); lastId = Auto.getNextPlotId(lastId, 1);
if (area.canClaim(player, lastId, lastId)) { } while (!area.canClaim(player, lastId, lastId));
break;
}
}
area.setMeta("lastPlot", lastId); area.setMeta("lastPlot", lastId);
this.value = area.getPlot(lastId); this.value = area.getPlot(lastId);
this.value.setOwner(player.getUUID()); this.value.setOwner(player.getUUID());

View File

@ -339,11 +339,6 @@ public class Settings extends Config {
"Allows brushes to be persistent (default: true)", "Allows brushes to be persistent (default: true)",
}) })
public boolean PERSISTENT_BRUSHES = true; public boolean PERSISTENT_BRUSHES = true;
@Comment({
"[SAFE] Enable CUI without needing the mod installed (Requires ProtocolLib)",
})
public boolean VANILLA_CUI = false;
@Comment({ @Comment({
"Disable using native libraries", "Disable using native libraries",
@ -502,4 +497,4 @@ public class Settings extends Config {
} }
return limit; return limit;
} }
} }

View File

@ -37,19 +37,14 @@ import javax.swing.border.EmptyBorder;
public class InstallerFrame extends JFrame { public class InstallerFrame extends JFrame {
private final InvisiblePanel loggerPanel; private final InvisiblePanel loggerPanel;
private Color LIGHT_GRAY = new Color(0x66, 0x66, 0x66); private Color DARKER_GRAY;
private Color GRAY = new Color(0x44, 0x44, 0x46);
private Color DARK_GRAY = new Color(0x33, 0x33, 0x36);
private Color DARKER_GRAY = new Color(0x26, 0x26, 0x28);
private Color INVISIBLE = new Color(0, 0, 0, 0); private Color INVISIBLE = new Color(0, 0, 0, 0);
private Color OFF_WHITE = new Color(200, 200, 200);
private JTextArea loggerTextArea; private JTextArea loggerTextArea;
private BrowseButton browse; private BrowseButton browse;
public InstallerFrame() throws Exception { public InstallerFrame() throws Exception {
final MovablePanel movable = new MovablePanel(this); final MovablePanel movable = new MovablePanel(this);
Container content = this.getContentPane(); Container content = this.getContentPane();
content.add(movable); content.add(movable);
this.setSize(480, 320); this.setSize(480, 320);
@ -61,117 +56,109 @@ public class InstallerFrame extends JFrame {
this.setLocation(x, y); this.setLocation(x, y);
this.setVisible(true); this.setVisible(true);
this.setOpacity(0); this.setOpacity(0);
movable.setBackground(DARK_GRAY); movable.setBackground(Color.darkGray);
movable.setLayout(new BorderLayout()); movable.setLayout(new BorderLayout());
fadeIn(); fadeIn();
JPanel topBar = new InvisiblePanel(new BorderLayout()); JPanel topBar = new InvisiblePanel(new BorderLayout());
{ JPanel topBarLeft = new InvisiblePanel();
JPanel topBarLeft = new InvisiblePanel(); JPanel topBarRight = new InvisiblePanel();
JPanel topBarRight = new InvisiblePanel();
JLabel title = new JLabel("FastAsyncWorldEdit Installer"); JLabel title = new JLabel("FastAsyncWorldEdit Installer");
title.setHorizontalAlignment(SwingConstants.CENTER); title.setHorizontalAlignment(SwingConstants.CENTER);
title.setAlignmentX(Component.RIGHT_ALIGNMENT); title.setAlignmentX(Component.RIGHT_ALIGNMENT);
title.setForeground(LIGHT_GRAY); title.setForeground(Color.lightGray);
MinimizeButton minimize = new MinimizeButton(this); MinimizeButton minimize = new MinimizeButton(this);
CloseButton exit = new CloseButton(); CloseButton exit = new CloseButton();
topBarLeft.add(title); topBarLeft.add(title);
topBarRight.add(minimize); topBarRight.add(minimize);
topBarRight.add(exit); topBarRight.add(exit);
topBar.add(topBarLeft, BorderLayout.CENTER); topBar.add(topBarLeft, BorderLayout.CENTER);
topBar.add(topBarRight, BorderLayout.EAST); topBar.add(topBarRight, BorderLayout.EAST);
}
final JPanel mainContent = new InvisiblePanel(new BorderLayout()); final JPanel mainContent = new InvisiblePanel(new BorderLayout());
{ DARKER_GRAY = new Color(0x26, 0x26, 0x28);
final JPanel browseContent = new InvisiblePanel(new BorderLayout()); final JPanel browseContent = new InvisiblePanel(new BorderLayout());
File dir = MainUtil.getWorkingDirectory("minecraft"); File dir = MainUtil.getWorkingDirectory("minecraft");
JLabel folder = new JLabel("Folder: "); JLabel folder = new JLabel("Folder: ");
folder.setForeground(OFF_WHITE); folder.setForeground(Color.white);
final InteractiveButton text = new InteractiveButton(dir.getPath(), DARKER_GRAY) { final InteractiveButton text = new InteractiveButton(dir.getPath(), DARKER_GRAY) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
browse.actionPerformed(e); browse.actionPerformed(e);
}
};
text.setForeground(OFF_WHITE);
text.setBackground(DARKER_GRAY);
text.setOpaque(true);
text.setBorder(new EmptyBorder(4, 4, 4, 4));
browse = new BrowseButton("") {
@Override
public void onSelect(File folder) {
text.setText(folder.getPath());
movable.repaint();
}
};
InteractiveButton install = new InteractiveButton(">> Create Profile <<", DARKER_GRAY) {
@Override
public void actionPerformed(ActionEvent e) {
try {
install(text.getText());
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
browseContent.add(folder, BorderLayout.WEST);
browseContent.add(text, BorderLayout.CENTER);
browseContent.add(browse, BorderLayout.EAST);
final JPanel installContent = new InvisiblePanel(new FlowLayout());
install.setPreferredSize(new Dimension(416, 32));
installContent.add(install);
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
this.loggerPanel = new InvisiblePanel(new BorderLayout());
this.loggerPanel.setBackground(Color.GREEN);
loggerPanel.setPreferredSize(new Dimension(416, 160));
loggerTextArea = new JTextArea(12, 52);
loggerTextArea.setBackground(GRAY);
loggerTextArea.setForeground(DARKER_GRAY);
loggerTextArea.setFont(new Font(loggerTextArea.getFont().getName(), Font.PLAIN, 9));
JScrollPane scroll = new JScrollPane(loggerTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBackground(DARK_GRAY);
scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
loggerPanel.add(scroll);
loggerPanel.setVisible(false);
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
mainContent.add(browseContent, BorderLayout.NORTH);
mainContent.add(installContent, BorderLayout.CENTER);
mainContent.add(loggerPanel, BorderLayout.SOUTH);
}
JPanel bottomBar = new InvisiblePanel();
{
try {
InputStream stream = getClass().getResourceAsStream("/fawe.properties");
java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
String versionString = scanner.next().trim();
scanner.close();
FaweVersion version = null;
String date = new Date(100 + version.year, version.month, version.day).toGMTString();
String build = "https://ci.athion.net/job/FastAsyncWorldEdit/" + version.build;
String commit = "https://github.com/boy0001/FastAsyncWorldedit/commit/" + Integer.toHexString(version.hash);
String footerMessage = "FAWE v" + version.year + "." + version.month + "." + version.day + " by Empire92 (c) 2017 (GPL v3.0)";
URL licenseUrl = new URL("https://github.com/boy0001/FastAsyncWorldedit/blob/master/LICENSE");
URLButton licenseButton = new URLButton(licenseUrl, footerMessage);
bottomBar.add(licenseButton);
} catch (Throwable ignore) {
ignore.printStackTrace();
} }
URL chat = new URL("https://discord.gg/ngZCzbU"); };
URLButton chatButton = new URLButton(chat, "Chat"); text.setForeground(Color.white);
bottomBar.add(chatButton); text.setBackground(DARKER_GRAY);
URL wiki = new URL("https://github.com/boy0001/FastAsyncWorldedit/wiki"); text.setOpaque(true);
URLButton wikiButton = new URLButton(wiki, "Wiki"); text.setBorder(new EmptyBorder(4, 4, 4, 4));
bottomBar.add(wikiButton); browse = new BrowseButton("") {
URL issue = new URL("https://github.com/boy0001/FastAsyncWorldedit/issues/new"); @Override
URLButton issueButton = new URLButton(issue, "Report Issue"); public void onSelect(File folder) {
bottomBar.add(issueButton); text.setText(folder.getPath());
movable.repaint();
}
};
InteractiveButton install = new InteractiveButton(">> Create Profile <<", DARKER_GRAY) {
@Override
public void actionPerformed(ActionEvent e) {
try {
install(text.getText());
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
browseContent.add(folder, BorderLayout.WEST);
browseContent.add(text, BorderLayout.CENTER);
browseContent.add(browse, BorderLayout.EAST);
final JPanel installContent = new InvisiblePanel(new FlowLayout());
install.setPreferredSize(new Dimension(416, 32));
installContent.add(install);
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
this.loggerPanel = new InvisiblePanel(new BorderLayout());
this.loggerPanel.setBackground(Color.GREEN);
loggerPanel.setPreferredSize(new Dimension(416, 160));
loggerTextArea = new JTextArea(12, 52);
Color GRAY = new Color(0x44, 0x44, 0x46);
loggerTextArea.setBackground(GRAY);
loggerTextArea.setForeground(DARKER_GRAY);
loggerTextArea.setFont(new Font(loggerTextArea.getFont().getName(), Font.PLAIN, 9));
JScrollPane scroll = new JScrollPane(loggerTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBackground(Color.darkGray);
scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
loggerPanel.add(scroll);
loggerPanel.setVisible(false);
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
mainContent.add(browseContent, BorderLayout.NORTH);
mainContent.add(installContent, BorderLayout.CENTER);
mainContent.add(loggerPanel, BorderLayout.SOUTH);
JPanel bottomBar = new InvisiblePanel();
try {
FaweVersion version = null;
String date = new Date(100 + version.year, version.month, version.day).toGMTString();
String build = "https://ci.athion.net/job/FastAsyncWorldEdit/" + version.build;
String commit = "https://github.com/boy0001/FastAsyncWorldedit/commit/" + Integer.toHexString(version.hash);
String footerMessage = "FAWE v" + version.year + "." + version.month + "." + version.day + " by Empire92 (c) 2017 (GPL v3.0)";
URL licenseUrl = new URL("https://github.com/boy0001/FastAsyncWorldedit/blob/master/LICENSE");
URLButton licenseButton = new URLButton(licenseUrl, footerMessage);
bottomBar.add(licenseButton);
} catch (Throwable ignore) {
ignore.printStackTrace();
} }
URL chat = new URL("https://discord.gg/ngZCzbU");
URLButton chatButton = new URLButton(chat, "Chat");
bottomBar.add(chatButton);
URL wiki = new URL("https://github.com/boy0001/FastAsyncWorldedit/wiki");
URLButton wikiButton = new URLButton(wiki, "Wiki");
bottomBar.add(wikiButton);
URL issue = new URL("https://github.com/boy0001/FastAsyncWorldedit/issues/new");
URLButton issueButton = new URLButton(issue, "Report Issue");
bottomBar.add(issueButton);
// We want to add these a bit later // We want to add these a bit later
movable.add(topBar, BorderLayout.NORTH); movable.add(topBar, BorderLayout.NORTH);
@ -214,140 +201,134 @@ public class InstallerFrame extends JFrame {
prompt("You must select a folder, not a file"); prompt("You must select a folder, not a file");
return; return;
} }
Thread installThread = new Thread(new Runnable() { Thread installThread = new Thread(() -> {
@Override List<String> supported = Arrays.asList("v1710", "v189", "v194", "v110", "v111");
public void run() { String supportedString = null;
List<String> supported = Arrays.asList("v1710", "v189", "v194", "v110", "v111"); for (String version : supported) {
String supportedString = null;
for (String version : supported) {
try {
Class.forName("com.boydti.fawe.forge." + version + ".ForgeChunk_All");
supportedString = version;
break;
} catch (ClassNotFoundException ignore) {
}
}
if (supportedString == null) {
prompt("This version of FAWE cannot be installed this way.");
return;
}
debug("Selected version " + supportedString);
URL forgeUrl;
URL worldEditUrl;
URL worldEditCuiUrl;
try { try {
switch (supportedString) { Class.forName("com.boydti.fawe.forge." + version + ".ForgeChunk_All");
case "v111": supportedString = version;
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.11.2-13.20.0.2201/forge-1.11.2-13.20.0.2201-installer.jar"); break;
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9593/download/worldedit-forge-mc1.11-6.1.6-SNAPSHOT-dist.jar"); } catch (ClassNotFoundException ignore) {
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/241/worldeditcuife-v1.0.6-mf-1.11.2-13.20.0.2201.jar");
break;
case "v110":
forgeUrl = new URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.10.2-12.18.3.2185/forge-1.10.2-12.18.3.2185-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9395/download/worldedit-forge-mc1.10.2-6.1.4-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/239/WorldEditCuiFe-v1.0.6-mf-1.10.2-12.18.2.2125.jar");
break;
case "v194":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.9.4-12.17.0.2051/forge-1.9.4-12.17.0.2051-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9171/download/worldedit-forge-mc1.9.4-6.1.3-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/236/WorldEditCuiFe-v1.0.6-mf-1.9.4-12.17.0.1976.jar");
break;
case "v189":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.8.9-11.15.1.1902-1.8.9/forge-1.8.9-11.15.1.1902-1.8.9-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/8755/download/worldedit-forge-mc1.8.9-6.1.1-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/235/WorldEditCuiFe-v1.0.6-mf-1.8.9-11.15.1.1855.jar");
break;
case "v1710":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.4.1614-1.7.10/forge-1.7.10-10.13.4.1614-1.7.10-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9194/download/worldedit-forge-mc1.7.10-6.1.2-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/234/WorldEditCuiFe-v1.0.6-mf-1.7.10-10.13.4.1566.jar");
break;
default:
return;
}
} catch (MalformedURLException e) {
e.printStackTrace();
return;
} }
try { // install forge
debug("Downloading forge installer from:\n - https://files.minecraftforge.net/");
URLClassLoader loader = new URLClassLoader(new URL[]{forgeUrl});
debug("Connected");
Class<?> forgeInstallClass = loader.loadClass("net.minecraftforge.installer.ClientInstall");
debug("Found ClientInstall class");
Object forgeInstallInstance = forgeInstallClass.newInstance();
debug(forgeInstallInstance + " | " + forgeInstallClass + " | " + StringMan.getString(forgeInstallClass.getMethods()));
debug("Created instance " + forgeInstallInstance);
Method methodRun = forgeInstallClass.getDeclaredMethods()[0];//("run", File.class, Predicate.class);
Object alwaysTrue = loader.loadClass("com.google.common.base.Predicates").getDeclaredMethod("alwaysTrue").invoke(null);
methodRun.invoke(forgeInstallInstance, dirMc, alwaysTrue);
debug("Forge profile created, now installing WorldEdit");
} catch (Throwable e) {
e.printStackTrace();
prompt("[ERROR] Forge install failed, download from:\nhttps://files.minecraftforge.net/");
}
File mods = new File(dirMc, "mods");
if (!mods.exists()) {
debug("Creating mods directory");
mods.mkdirs();
} else {
for (File file : mods.listFiles()) {
String name = file.getName().toLowerCase();
if ((name.contains("worldedit") || name.contains("fawe"))) {
debug("Delete existing: " + file.getName());
file.delete();
}
}
}
try { // install worldedit
debug("Downloading WE-CUI from:\n - https://minecraft.curseforge.com/projects/worldeditcui-forge-edition");
try (ReadableByteChannel rbc = Channels.newChannel(worldEditCuiUrl.openStream())) {
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEditCUI.jar"))) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
debug("Successfully downloaded WorldEdit-CUI");
} catch (Throwable e) {
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
}
try { // install worldedit
debug("Downloading WorldEdit from:\n - http://builds.enginehub.org/job/worldedit");
try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) {
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEdit.jar"))) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
debug("Successfully downloaded WorldEdit");
} catch (Throwable e) {
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
}
try { // install FAWE
debug("Copying FastAsyncWorldEdit to mods directory");
File file = new File(InstallerFrame.class.getProtectionDomain().getCodeSource().getLocation().getPath());
debug(" - " + file.getPath());
MainUtil.copyFile(file, new File(mods, "FastAsyncWorldEdit.jar"));
debug("Installation complete!");
} catch (Throwable e) {
prompt("[ERROR] Copy installer failed, please copy this installer jar manually");
}
prompt("Installation complete!\nLaunch the game using the forge profile.");
} }
if (supportedString == null) {
prompt("This version of FAWE cannot be installed this way.");
return;
}
debug("Selected version " + supportedString);
URL forgeUrl;
URL worldEditUrl;
URL worldEditCuiUrl;
try {
switch (supportedString) {
case "v111":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.11.2-13.20.0.2201/forge-1.11.2-13.20.0.2201-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9593/download/worldedit-forge-mc1.11-6.1.6-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/241/worldeditcuife-v1.0.6-mf-1.11.2-13.20.0.2201.jar");
break;
case "v110":
forgeUrl = new URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.10.2-12.18.3.2185/forge-1.10.2-12.18.3.2185-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9395/download/worldedit-forge-mc1.10.2-6.1.4-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/239/WorldEditCuiFe-v1.0.6-mf-1.10.2-12.18.2.2125.jar");
break;
case "v194":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.9.4-12.17.0.2051/forge-1.9.4-12.17.0.2051-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9171/download/worldedit-forge-mc1.9.4-6.1.3-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/236/WorldEditCuiFe-v1.0.6-mf-1.9.4-12.17.0.1976.jar");
break;
case "v189":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.8.9-11.15.1.1902-1.8.9/forge-1.8.9-11.15.1.1902-1.8.9-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/8755/download/worldedit-forge-mc1.8.9-6.1.1-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/235/WorldEditCuiFe-v1.0.6-mf-1.8.9-11.15.1.1855.jar");
break;
case "v1710":
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.4.1614-1.7.10/forge-1.7.10-10.13.4.1614-1.7.10-installer.jar");
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9194/download/worldedit-forge-mc1.7.10-6.1.2-SNAPSHOT-dist.jar");
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/234/WorldEditCuiFe-v1.0.6-mf-1.7.10-10.13.4.1566.jar");
break;
default:
return;
}
} catch (MalformedURLException e) {
e.printStackTrace();
return;
}
try { // install forge
debug("Downloading forge installer from:\n - https://files.minecraftforge.net/");
URLClassLoader loader = new URLClassLoader(new URL[]{forgeUrl});
debug("Connected");
Class<?> forgeInstallClass = loader.loadClass("net.minecraftforge.installer.ClientInstall");
debug("Found ClientInstall class");
Object forgeInstallInstance = forgeInstallClass.newInstance();
debug(forgeInstallInstance + " | " + forgeInstallClass + " | " + StringMan.getString(forgeInstallClass.getMethods()));
debug("Created instance " + forgeInstallInstance);
Method methodRun = forgeInstallClass.getDeclaredMethods()[0];//("run", File.class, Predicate.class);
Object alwaysTrue = loader.loadClass("com.google.common.base.Predicates").getDeclaredMethod("alwaysTrue").invoke(null);
methodRun.invoke(forgeInstallInstance, dirMc, alwaysTrue);
debug("Forge profile created, now installing WorldEdit");
} catch (Throwable e) {
e.printStackTrace();
prompt("[ERROR] Forge install failed, download from:\nhttps://files.minecraftforge.net/");
}
File mods = new File(dirMc, "mods");
if (!mods.exists()) {
debug("Creating mods directory");
mods.mkdirs();
} else {
for (File file : mods.listFiles()) {
String name1 = file.getName().toLowerCase();
if ((name1.contains("worldedit") || name1.contains("fawe"))) {
debug("Delete existing: " + file.getName());
file.delete();
}
}
}
try { // install worldedit
debug("Downloading WE-CUI from:\n - https://minecraft.curseforge.com/projects/worldeditcui-forge-edition");
try (ReadableByteChannel rbc = Channels.newChannel(worldEditCuiUrl.openStream())) {
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEditCUI.jar"))) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
debug("Successfully downloaded WorldEdit-CUI");
} catch (Throwable e) {
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
}
try { // install worldedit
debug("Downloading WorldEdit from:\n - http://builds.enginehub.org/job/worldedit");
try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) {
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEdit.jar"))) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
debug("Successfully downloaded WorldEdit");
} catch (Throwable e) {
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
}
try { // install FAWE
debug("Copying FastAsyncWorldEdit to mods directory");
File file = new File(InstallerFrame.class.getProtectionDomain().getCodeSource().getLocation().getPath());
debug(" - " + file.getPath());
MainUtil.copyFile(file, new File(mods, "FastAsyncWorldEdit.jar"));
debug("Installation complete!");
} catch (Throwable e) {
prompt("[ERROR] Copy installer failed, please copy this installer jar manually");
}
prompt("Installation complete!\nLaunch the game using the forge profile.");
}); });
installThread.start(); installThread.start();
} }
public void fadeIn() { public void fadeIn() {
Thread thread = new Thread(new Runnable() { Thread thread = new Thread(() -> {
@Override for (float i = 0; i <= 1; i += 0.001) {
public void run() { InstallerFrame.this.setOpacity(i);
for (float i = 0; i <= 1; i += 0.001) { try {
InstallerFrame.this.setOpacity(i); Thread.sleep(1);
try { } catch (InterruptedException e) {
Thread.sleep(1); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
} }
}); });

View File

@ -1,206 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.UNSAFE;
import static com.boydti.fawe.object.io.zstd.Util.highestBit;
import static com.boydti.fawe.object.io.zstd.Util.verify;
import static com.boydti.fawe.object.io.zstd.ZstdFrameDecompressor.SIZE_OF_LONG;
/**
* Bit streams are encoded as a byte-aligned little-endian stream. Thus, bits are laid out
* in the following manner, and the stream is read from right to left.
* <p>
* <p>
* ... [16 17 18 19 20 21 22 23] [8 9 10 11 12 13 14 15] [0 1 2 3 4 5 6 7]
*/
class BitStream
{
private BitStream()
{
}
public static boolean isEndOfStream(long startAddress, long currentAddress, int bitsConsumed)
{
return startAddress == currentAddress && bitsConsumed == Long.SIZE;
}
static long readTail(Object inputBase, long inputAddress, int inputSize)
{
long bits = UNSAFE.getByte(inputBase, inputAddress) & 0xFF;
switch (inputSize) {
case 7:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 6) & 0xFFL) << 48;
case 6:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 5) & 0xFFL) << 40;
case 5:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 4) & 0xFFL) << 32;
case 4:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 3) & 0xFFL) << 24;
case 3:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 2) & 0xFFL) << 16;
case 2:
bits |= (UNSAFE.getByte(inputBase, inputAddress + 1) & 0xFFL) << 8;
}
return bits;
}
/**
* @return numberOfBits in the low order bits of a long
*/
public static long peekBits(int bitsConsumed, long bitContainer, int numberOfBits)
{
return (((bitContainer << bitsConsumed) >>> 1) >>> (63 - numberOfBits));
}
/**
* numberOfBits must be > 0
*
* @return numberOfBits in the low order bits of a long
*/
public static long peekBitsFast(int bitsConsumed, long bitContainer, int numberOfBits)
{
return ((bitContainer << bitsConsumed) >>> (64 - numberOfBits));
}
static class Initializer
{
private final Object inputBase;
private final long startAddress;
private final long endAddress;
private long bits;
private long currentAddress;
private int bitsConsumed;
public Initializer(Object inputBase, long startAddress, long endAddress)
{
this.inputBase = inputBase;
this.startAddress = startAddress;
this.endAddress = endAddress;
}
public long getBits()
{
return bits;
}
public long getCurrentAddress()
{
return currentAddress;
}
public int getBitsConsumed()
{
return bitsConsumed;
}
public void initialize()
{
verify(endAddress - startAddress >= 1, startAddress, "Bitstream is empty");
int lastByte = UNSAFE.getByte(inputBase, endAddress - 1) & 0xFF;
verify(lastByte != 0, endAddress, "Bitstream end mark not present");
bitsConsumed = SIZE_OF_LONG - highestBit(lastByte);
int inputSize = (int) (endAddress - startAddress);
if (inputSize >= SIZE_OF_LONG) { /* normal case */
currentAddress = endAddress - SIZE_OF_LONG;
bits = UNSAFE.getLong(inputBase, currentAddress);
}
else {
currentAddress = startAddress;
bits = readTail(inputBase, startAddress, inputSize);
bitsConsumed += (SIZE_OF_LONG - inputSize) * 8;
}
}
}
static final class Loader
{
private final Object inputBase;
private final long startAddress;
private long bits;
private long currentAddress;
private int bitsConsumed;
private boolean overflow;
public Loader(Object inputBase, long startAddress, long currentAddress, long bits, int bitsConsumed)
{
this.inputBase = inputBase;
this.startAddress = startAddress;
this.bits = bits;
this.currentAddress = currentAddress;
this.bitsConsumed = bitsConsumed;
}
public long getBits()
{
return bits;
}
public long getCurrentAddress()
{
return currentAddress;
}
public int getBitsConsumed()
{
return bitsConsumed;
}
public boolean isOverflow()
{
return overflow;
}
public boolean load()
{
if (bitsConsumed > 64) {
overflow = true;
return true;
}
else if (currentAddress == startAddress) {
return true;
}
int bytes = bitsConsumed >>> 3; // divide by 8
if (currentAddress >= startAddress + SIZE_OF_LONG) {
if (bytes > 0) {
currentAddress -= bytes;
bits = UNSAFE.getLong(inputBase, currentAddress);
}
bitsConsumed &= 0b111;
}
else if (currentAddress - bytes < startAddress) {
bytes = (int) (currentAddress - startAddress);
currentAddress = startAddress;
bitsConsumed -= bytes * SIZE_OF_LONG;
bits = UNSAFE.getLong(inputBase, startAddress);
return true;
}
else {
currentAddress -= bytes;
bitsConsumed -= bytes * SIZE_OF_LONG;
bits = UNSAFE.getLong(inputBase, currentAddress);
}
return false;
}
}
}

View File

@ -1,176 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
import static com.boydti.fawe.object.io.zstd.BitStream.peekBits;
import static com.boydti.fawe.object.io.zstd.FseTableReader.FSE_MAX_SYMBOL_VALUE;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.UNSAFE;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
class FiniteStateEntropy
{
private static final int MAX_TABLE_LOG = 12;
private final FiniteStateEntropy.Table table;
private final FseTableReader reader = new FseTableReader();
public FiniteStateEntropy(int maxLog)
{
table = new FiniteStateEntropy.Table(maxLog);
}
public int decompress(final Object inputBase, final long inputAddress, final long inputLimit, byte[] weights)
{
long input = inputAddress;
input += reader.readFseTable(table, inputBase, input, inputLimit, FSE_MAX_SYMBOL_VALUE, MAX_TABLE_LOG);
final Object outputBase = weights;
final long outputAddress = ARRAY_BYTE_BASE_OFFSET;
final long outputLimit = outputAddress + weights.length;
long output = outputAddress;
// initialize bit stream
BitStream.Initializer initializer = new BitStream.Initializer(inputBase, input, inputLimit);
initializer.initialize();
int bitsConsumed = initializer.getBitsConsumed();
long currentAddress = initializer.getCurrentAddress();
long bits = initializer.getBits();
// initialize first FSE stream
int state1 = (int) peekBits(bitsConsumed, bits, table.log2Size);
bitsConsumed += table.log2Size;
BitStream.Loader loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader.load();
bits = loader.getBits();
bitsConsumed = loader.getBitsConsumed();
currentAddress = loader.getCurrentAddress();
// initialize second FSE stream
int state2 = (int) peekBits(bitsConsumed, bits, table.log2Size);
bitsConsumed += table.log2Size;
loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader.load();
bits = loader.getBits();
bitsConsumed = loader.getBitsConsumed();
currentAddress = loader.getCurrentAddress();
byte[] symbols = table.symbol;
byte[] numbersOfBits = table.numberOfBits;
int[] newStates = table.newState;
// decode 4 symbols per loop
while (output < outputLimit) {
int numberOfBits;
UNSAFE.putByte(outputBase, output, symbols[state1]);
numberOfBits = numbersOfBits[state1];
state1 = (int) (newStates[state1] + peekBits(bitsConsumed, bits, numberOfBits));
bitsConsumed += numberOfBits;
UNSAFE.putByte(outputBase, output + 1, symbols[state2]);
numberOfBits = numbersOfBits[state2];
state2 = (int) (newStates[state2] + peekBits(bitsConsumed, bits, numberOfBits));
bitsConsumed += numberOfBits;
UNSAFE.putByte(outputBase, output + 2, symbols[state1]);
numberOfBits = numbersOfBits[state1];
state1 = (int) (newStates[state1] + peekBits(bitsConsumed, bits, numberOfBits));
bitsConsumed += numberOfBits;
UNSAFE.putByte(outputBase, output + 3, symbols[state2]);
numberOfBits = numbersOfBits[state2];
state2 = (int) (newStates[state2] + peekBits(bitsConsumed, bits, numberOfBits));
bitsConsumed += numberOfBits;
output += ZstdFrameDecompressor.SIZE_OF_INT;
loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
boolean done = loader.load();
bitsConsumed = loader.getBitsConsumed();
bits = loader.getBits();
currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
}
while (true) {
UNSAFE.putByte(outputBase, output++, symbols[state1]);
int numberOfBits = numbersOfBits[state1];
state1 = (int) (newStates[state1] + peekBits(bitsConsumed, bits, numberOfBits));
bitsConsumed += numberOfBits;
loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader.load();
bitsConsumed = loader.getBitsConsumed();
bits = loader.getBits();
currentAddress = loader.getCurrentAddress();
if (loader.isOverflow()) {
UNSAFE.putByte(outputBase, output++, symbols[state2]);
break;
}
UNSAFE.putByte(outputBase, output++, symbols[state2]);
int numberOfBits1 = numbersOfBits[state2];
state2 = (int) (newStates[state2] + peekBits(bitsConsumed, bits, numberOfBits1));
bitsConsumed += numberOfBits1;
loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader.load();
bitsConsumed = loader.getBitsConsumed();
bits = loader.getBits();
currentAddress = loader.getCurrentAddress();
if (loader.isOverflow()) {
UNSAFE.putByte(outputBase, output++, symbols[state1]);
break;
}
}
return (int) (output - outputAddress);
}
public static final class Table
{
int log2Size;
final int[] newState;
final byte[] symbol;
final byte[] numberOfBits;
public Table(int log2Size)
{
int size = 1 << log2Size;
newState = new int[size];
symbol = new byte[size];
numberOfBits = new byte[size];
}
public Table(int log2Size, int[] newState, byte[] symbol, byte[] numberOfBits)
{
int size = 1 << log2Size;
if (newState.length != size || symbol.length != size || numberOfBits.length != size) {
throw new IllegalArgumentException("Expected arrays to match provided size");
}
this.log2Size = log2Size;
this.newState = newState;
this.symbol = symbol;
this.numberOfBits = numberOfBits;
}
}
}

View File

@ -1,182 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.UNSAFE;
import static com.boydti.fawe.object.io.zstd.Util.highestBit;
import static com.boydti.fawe.object.io.zstd.Util.verify;
class FseTableReader
{
private static final int FSE_MIN_TABLE_LOG = 5;
public static final int FSE_MAX_SYMBOL_VALUE = 255;
private final short[] nextSymbol = new short[FSE_MAX_SYMBOL_VALUE + 1];
private final short[] normalizedCounters = new short[FSE_MAX_SYMBOL_VALUE + 1];
public int readFseTable(FiniteStateEntropy.Table table, Object inputBase, long inputAddress, long inputLimit, int maxSymbol, int maxTableLog)
{
// read table headers
long input = inputAddress;
verify(inputLimit - inputAddress >= 4, input, "Not enough input bytes");
int threshold;
int symbolNumber = 0;
boolean previousIsZero = false;
int bitStream = UNSAFE.getInt(inputBase, input);
int tableLog = (bitStream & 0xF) + FSE_MIN_TABLE_LOG;
int numberOfBits = tableLog + 1;
bitStream >>>= 4;
int bitCount = 4;
verify(tableLog <= maxTableLog, input, "FSE table size exceeds maximum allowed size");
int remaining = (1 << tableLog) + 1;
threshold = 1 << tableLog;
while (remaining > 1 && symbolNumber <= maxSymbol) {
if (previousIsZero) {
int n0 = symbolNumber;
while ((bitStream & 0xFFFF) == 0xFFFF) {
n0 += 24;
if (input < inputLimit - 5) {
input += 2;
bitStream = (UNSAFE.getInt(inputBase, input) >>> bitCount);
}
else {
// end of bit stream
bitStream >>>= 16;
bitCount += 16;
}
}
while ((bitStream & 3) == 3) {
n0 += 3;
bitStream >>>= 2;
bitCount += 2;
}
n0 += bitStream & 3;
bitCount += 2;
verify(n0 <= maxSymbol, input, "Symbol larger than max value");
while (symbolNumber < n0) {
normalizedCounters[symbolNumber++] = 0;
}
if ((input <= inputLimit - 7) || (input + (bitCount >>> 3) <= inputLimit - 4)) {
input += bitCount >>> 3;
bitCount &= 7;
bitStream = UNSAFE.getInt(inputBase, input) >>> bitCount;
}
else {
bitStream >>>= 2;
}
}
short max = (short) ((2 * threshold - 1) - remaining);
short count;
if ((bitStream & (threshold - 1)) < max) {
count = (short) (bitStream & (threshold - 1));
bitCount += numberOfBits - 1;
}
else {
count = (short) (bitStream & (2 * threshold - 1));
if (count >= threshold) {
count -= max;
}
bitCount += numberOfBits;
}
count--; // extra accuracy
remaining -= Math.abs(count);
normalizedCounters[symbolNumber++] = count;
previousIsZero = count == 0;
while (remaining < threshold) {
numberOfBits--;
threshold >>>= 1;
}
if ((input <= inputLimit - 7) || (input + (bitCount >> 3) <= inputLimit - 4)) {
input += bitCount >>> 3;
bitCount &= 7;
}
else {
bitCount -= (int) (8 * (inputLimit - 4 - input));
input = inputLimit - 4;
}
bitStream = UNSAFE.getInt(inputBase, input) >>> (bitCount & 31);
}
verify(remaining == 1 && bitCount <= 32, input, "Input is corrupted");
maxSymbol = symbolNumber - 1;
verify(maxSymbol <= FSE_MAX_SYMBOL_VALUE, input, "Max symbol value too large (too many symbols for FSE)");
input += (bitCount + 7) >> 3;
// populate decoding table
int symbolCount = maxSymbol + 1;
int tableSize = 1 << tableLog;
int highThreshold = tableSize - 1;
table.log2Size = tableLog;
for (byte symbol = 0; symbol < symbolCount; symbol++) {
if (normalizedCounters[symbol] == -1) {
table.symbol[highThreshold--] = symbol;
nextSymbol[symbol] = 1;
}
else {
nextSymbol[symbol] = normalizedCounters[symbol];
}
}
// spread symbols
int tableMask = tableSize - 1;
int step = (tableSize >>> 1) + (tableSize >>> 3) + 3;
int position = 0;
for (byte symbol = 0; symbol < symbolCount; symbol++) {
for (int i = 0; i < normalizedCounters[symbol]; i++) {
table.symbol[position] = symbol;
do {
position = (position + step) & tableMask;
}
while (position > highThreshold);
}
}
// position must reach all cells once, otherwise normalizedCounter is incorrect
verify(position == 0, input, "Input is corrupted");
for (int i = 0; i < tableSize; i++) {
byte symbol = table.symbol[i];
short nextState = nextSymbol[symbol]++;
table.numberOfBits[i] = (byte) (tableLog - highestBit(nextState));
table.newState[i] = (short) ((nextState << table.numberOfBits[i]) - tableSize);
}
return (int) (input - inputAddress);
}
public static void buildRleTable(FiniteStateEntropy.Table table, byte value)
{
table.log2Size = 0;
table.symbol[0] = value;
table.newState[0] = 0;
table.numberOfBits[0] = 0;
}
}

View File

@ -1,317 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
import java.util.Arrays;
import static com.boydti.fawe.object.io.zstd.BitStream.isEndOfStream;
import static com.boydti.fawe.object.io.zstd.BitStream.peekBitsFast;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.UNSAFE;
import static com.boydti.fawe.object.io.zstd.Util.isPowerOf2;
import static com.boydti.fawe.object.io.zstd.Util.verify;
import static com.boydti.fawe.object.io.zstd.ZstdFrameDecompressor.SIZE_OF_INT;
import static com.boydti.fawe.object.io.zstd.ZstdFrameDecompressor.SIZE_OF_SHORT;
class Huffman
{
private static final int MAX_SYMBOL = 255;
private static final int MAX_TABLE_LOG = 12;
// stats
private final byte[] weights = new byte[MAX_SYMBOL + 1];
private final int[] ranks = new int[MAX_TABLE_LOG + 1];
// table
private int tableLog = -1;
private final byte[] symbols = new byte[1 << MAX_TABLE_LOG];
private final byte[] numbersOfBits = new byte[1 << MAX_TABLE_LOG];
private final FiniteStateEntropy finiteStateEntropy = new FiniteStateEntropy(6);
public boolean isLoaded()
{
return tableLog != -1;
}
public int readTable(final Object inputBase, final long inputAddress, final int size)
{
Arrays.fill(ranks, 0);
long input = inputAddress;
// read table header
verify(size > 0, input, "Not enough input bytes");
int inputSize = UNSAFE.getByte(inputBase, input++) & 0xFF;
int outputSize;
if (inputSize >= 128) {
outputSize = inputSize - 127;
inputSize = ((outputSize + 1) / 2);
verify(inputSize + 1 <= size, input, "Not enough input bytes");
verify(outputSize <= MAX_SYMBOL + 1, input, "Input is corrupted");
for (int i = 0; i < outputSize; i += 2) {
int value = UNSAFE.getByte(inputBase, input + i / 2) & 0xFF;
weights[i] = (byte) (value >>> 4);
weights[i + 1] = (byte) (value & 0b1111);
}
}
else {
verify(inputSize + 1 <= size, input, "Not enough input bytes");
outputSize = finiteStateEntropy.decompress(inputBase, input, input + inputSize, weights);
}
int totalWeight = 0;
for (int i = 0; i < outputSize; i++) {
ranks[weights[i]]++;
totalWeight += (1 << weights[i]) >> 1; // TODO same as 1 << (weights[n] - 1)?
}
verify(totalWeight != 0, input, "Input is corrupted");
tableLog = Util.highestBit(totalWeight) + 1;
verify(tableLog <= MAX_TABLE_LOG, input, "Input is corrupted");
int total = 1 << tableLog;
int rest = total - totalWeight;
verify(isPowerOf2(rest), input, "Input is corrupted");
int lastWeight = Util.highestBit(rest) + 1;
weights[outputSize] = (byte) lastWeight;
ranks[lastWeight]++;
int numberOfSymbols = outputSize + 1;
// populate table
int nextRankStart = 0;
for (int i = 1; i < tableLog + 1; ++i) {
int current = nextRankStart;
nextRankStart += ranks[i] << (i - 1);
ranks[i] = current;
}
for (int n = 0; n < numberOfSymbols; n++) {
int weight = weights[n];
int length = (1 << weight) >> 1; // TODO: 1 << (weight - 1) ??
byte symbol = (byte) n;
byte numberOfBits = (byte) (tableLog + 1 - weight);
for (int i = ranks[weight]; i < ranks[weight] + length; i++) {
symbols[i] = symbol;
numbersOfBits[i] = numberOfBits;
}
ranks[weight] += length;
}
verify(ranks[1] >= 2 && (ranks[1] & 1) == 0, input, "Input is corrupted");
return inputSize + 1;
}
public void decodeSingleStream(final Object inputBase, final long inputAddress, final long inputLimit, final Object outputBase, final long outputAddress, final long outputLimit)
{
BitStream.Initializer initializer = new BitStream.Initializer(inputBase, inputAddress, inputLimit);
initializer.initialize();
long bits = initializer.getBits();
int bitsConsumed = initializer.getBitsConsumed();
long currentAddress = initializer.getCurrentAddress();
int tableLog = this.tableLog;
byte[] numbersOfBits = this.numbersOfBits;
byte[] symbols = this.symbols;
// 4 symbols at a time
long output = outputAddress;
long fastOutputLimit = outputLimit - 4;
while (output < fastOutputLimit) {
BitStream.Loader loader = new BitStream.Loader(inputBase, inputAddress, currentAddress, bits, bitsConsumed);
boolean done = loader.load();
bits = loader.getBits();
bitsConsumed = loader.getBitsConsumed();
currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
bitsConsumed = decodeSymbol(outputBase, output, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
bitsConsumed = decodeSymbol(outputBase, output + 1, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
bitsConsumed = decodeSymbol(outputBase, output + 2, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
bitsConsumed = decodeSymbol(outputBase, output + 3, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
output += SIZE_OF_INT;
}
decodeTail(inputBase, inputAddress, currentAddress, bitsConsumed, bits, outputBase, output, outputLimit);
}
public void decode4Streams(final Object inputBase, final long inputAddress, final long inputLimit, final Object outputBase, final long outputAddress, final long outputLimit)
{
verify(inputLimit - inputAddress >= 10, inputAddress, "Input is corrupted"); // jump table + 1 byte per stream
long start1 = inputAddress + 3 * SIZE_OF_SHORT; // for the shorts we read below
long start2 = start1 + (UNSAFE.getShort(inputBase, inputAddress) & 0xFFFF);
long start3 = start2 + (UNSAFE.getShort(inputBase, inputAddress + 2) & 0xFFFF);
long start4 = start3 + (UNSAFE.getShort(inputBase, inputAddress + 4) & 0xFFFF);
BitStream.Initializer initializer = new BitStream.Initializer(inputBase, start1, start2);
initializer.initialize();
int stream1bitsConsumed = initializer.getBitsConsumed();
long stream1currentAddress = initializer.getCurrentAddress();
long stream1bits = initializer.getBits();
initializer = new BitStream.Initializer(inputBase, start2, start3);
initializer.initialize();
int stream2bitsConsumed = initializer.getBitsConsumed();
long stream2currentAddress = initializer.getCurrentAddress();
long stream2bits = initializer.getBits();
initializer = new BitStream.Initializer(inputBase, start3, start4);
initializer.initialize();
int stream3bitsConsumed = initializer.getBitsConsumed();
long stream3currentAddress = initializer.getCurrentAddress();
long stream3bits = initializer.getBits();
initializer = new BitStream.Initializer(inputBase, start4, inputLimit);
initializer.initialize();
int stream4bitsConsumed = initializer.getBitsConsumed();
long stream4currentAddress = initializer.getCurrentAddress();
long stream4bits = initializer.getBits();
int segmentSize = (int) ((outputLimit - outputAddress + 3) / 4);
long outputStart2 = outputAddress + segmentSize;
long outputStart3 = outputStart2 + segmentSize;
long outputStart4 = outputStart3 + segmentSize;
long output1 = outputAddress;
long output2 = outputStart2;
long output3 = outputStart3;
long output4 = outputStart4;
long fastOutputLimit = outputLimit - 7;
int tableLog = this.tableLog;
byte[] numbersOfBits = this.numbersOfBits;
byte[] symbols = this.symbols;
while (output4 < fastOutputLimit) {
stream1bitsConsumed = decodeSymbol(outputBase, output1, stream1bits, stream1bitsConsumed, tableLog, numbersOfBits, symbols);
stream2bitsConsumed = decodeSymbol(outputBase, output2, stream2bits, stream2bitsConsumed, tableLog, numbersOfBits, symbols);
stream3bitsConsumed = decodeSymbol(outputBase, output3, stream3bits, stream3bitsConsumed, tableLog, numbersOfBits, symbols);
stream4bitsConsumed = decodeSymbol(outputBase, output4, stream4bits, stream4bitsConsumed, tableLog, numbersOfBits, symbols);
stream1bitsConsumed = decodeSymbol(outputBase, output1 + 1, stream1bits, stream1bitsConsumed, tableLog, numbersOfBits, symbols);
stream2bitsConsumed = decodeSymbol(outputBase, output2 + 1, stream2bits, stream2bitsConsumed, tableLog, numbersOfBits, symbols);
stream3bitsConsumed = decodeSymbol(outputBase, output3 + 1, stream3bits, stream3bitsConsumed, tableLog, numbersOfBits, symbols);
stream4bitsConsumed = decodeSymbol(outputBase, output4 + 1, stream4bits, stream4bitsConsumed, tableLog, numbersOfBits, symbols);
stream1bitsConsumed = decodeSymbol(outputBase, output1 + 2, stream1bits, stream1bitsConsumed, tableLog, numbersOfBits, symbols);
stream2bitsConsumed = decodeSymbol(outputBase, output2 + 2, stream2bits, stream2bitsConsumed, tableLog, numbersOfBits, symbols);
stream3bitsConsumed = decodeSymbol(outputBase, output3 + 2, stream3bits, stream3bitsConsumed, tableLog, numbersOfBits, symbols);
stream4bitsConsumed = decodeSymbol(outputBase, output4 + 2, stream4bits, stream4bitsConsumed, tableLog, numbersOfBits, symbols);
stream1bitsConsumed = decodeSymbol(outputBase, output1 + 3, stream1bits, stream1bitsConsumed, tableLog, numbersOfBits, symbols);
stream2bitsConsumed = decodeSymbol(outputBase, output2 + 3, stream2bits, stream2bitsConsumed, tableLog, numbersOfBits, symbols);
stream3bitsConsumed = decodeSymbol(outputBase, output3 + 3, stream3bits, stream3bitsConsumed, tableLog, numbersOfBits, symbols);
stream4bitsConsumed = decodeSymbol(outputBase, output4 + 3, stream4bits, stream4bitsConsumed, tableLog, numbersOfBits, symbols);
output1 += SIZE_OF_INT;
output2 += SIZE_OF_INT;
output3 += SIZE_OF_INT;
output4 += SIZE_OF_INT;
BitStream.Loader loader = new BitStream.Loader(inputBase, start1, stream1currentAddress, stream1bits, stream1bitsConsumed);
boolean done = loader.load();
stream1bitsConsumed = loader.getBitsConsumed();
stream1bits = loader.getBits();
stream1currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
loader = new BitStream.Loader(inputBase, start2, stream2currentAddress, stream2bits, stream2bitsConsumed);
done = loader.load();
stream2bitsConsumed = loader.getBitsConsumed();
stream2bits = loader.getBits();
stream2currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
loader = new BitStream.Loader(inputBase, start3, stream3currentAddress, stream3bits, stream3bitsConsumed);
done = loader.load();
stream3bitsConsumed = loader.getBitsConsumed();
stream3bits = loader.getBits();
stream3currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
loader = new BitStream.Loader(inputBase, start4, stream4currentAddress, stream4bits, stream4bitsConsumed);
done = loader.load();
stream4bitsConsumed = loader.getBitsConsumed();
stream4bits = loader.getBits();
stream4currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
}
verify(output1 <= outputStart2 && output2 <= outputStart3 && output3 <= outputStart4, inputAddress, "Input is corrupted");
/// finish streams one by one
decodeTail(inputBase, start1, stream1currentAddress, stream1bitsConsumed, stream1bits, outputBase, output1, outputStart2);
decodeTail(inputBase, start2, stream2currentAddress, stream2bitsConsumed, stream2bits, outputBase, output2, outputStart3);
decodeTail(inputBase, start3, stream3currentAddress, stream3bitsConsumed, stream3bits, outputBase, output3, outputStart4);
decodeTail(inputBase, start4, stream4currentAddress, stream4bitsConsumed, stream4bits, outputBase, output4, outputLimit);
}
private void decodeTail(final Object inputBase, final long startAddress, long currentAddress, int bitsConsumed, long bits, final Object outputBase, long outputAddress, final long outputLimit)
{
int tableLog = this.tableLog;
byte[] numbersOfBits = this.numbersOfBits;
byte[] symbols = this.symbols;
// closer to the end
while (outputAddress < outputLimit) {
BitStream.Loader loader = new BitStream.Loader(inputBase, startAddress, currentAddress, bits, bitsConsumed);
boolean done = loader.load();
bitsConsumed = loader.getBitsConsumed();
bits = loader.getBits();
currentAddress = loader.getCurrentAddress();
if (done) {
break;
}
bitsConsumed = decodeSymbol(outputBase, outputAddress++, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
}
// not more data in bit stream, so no need to reload
while (outputAddress < outputLimit) {
bitsConsumed = decodeSymbol(outputBase, outputAddress++, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
}
verify(isEndOfStream(startAddress, currentAddress, bitsConsumed), startAddress, "Bit stream is not fully consumed");
}
private static int decodeSymbol(Object outputBase, long outputAddress, long bitContainer, int bitsConsumed, int tableLog, byte[] numbersOfBits, byte[] symbols)
{
int value = (int) peekBitsFast(bitsConsumed, bitContainer, tableLog);
UNSAFE.putByte(outputBase, outputAddress, symbols[value]);
return bitsConsumed + numbersOfBits[value];
}
}

View File

@ -1,71 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.nio.Buffer;
final class UnsafeUtil
{
public static final Unsafe UNSAFE;
private static final Field ADDRESS_ACCESSOR;
private UnsafeUtil() {}
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
}
catch (Exception e) {
throw new RuntimeException(e);
}
try {
Field field = Buffer.class.getDeclaredField("address");
field.setAccessible(true);
ADDRESS_ACCESSOR = field;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static long getAddress(Buffer buffer)
{
try {
return (long) ADDRESS_ACCESSOR.get(buffer);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,108 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.nio.ByteBuffer;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.getAddress;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
public class ZstdDecompressor
{
private final ZstdFrameDecompressor decompressor = new ZstdFrameDecompressor();
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
long outputLimit = outputAddress + maxOutputLength;
return decompressor.decompress(input, inputAddress, inputLimit, output, outputAddress, outputLimit);
}
public void decompress(ByteBuffer input, ByteBuffer output)
throws MalformedInputException
{
Object inputBase;
long inputAddress;
long inputLimit;
if (input.isDirect()) {
inputBase = null;
long address = getAddress(input);
inputAddress = address + input.position();
inputLimit = address + input.limit();
}
else if (input.hasArray()) {
inputBase = input.array();
inputAddress = ARRAY_BYTE_BASE_OFFSET + input.arrayOffset() + input.position();
inputLimit = ARRAY_BYTE_BASE_OFFSET + input.arrayOffset() + input.limit();
}
else {
throw new IllegalArgumentException("Unsupported input ByteBuffer implementation " + input.getClass().getName());
}
Object outputBase;
long outputAddress;
long outputLimit;
if (output.isDirect()) {
outputBase = null;
long address = getAddress(output);
outputAddress = address + output.position();
outputLimit = address + output.limit();
}
else if (output.hasArray()) {
outputBase = output.array();
outputAddress = ARRAY_BYTE_BASE_OFFSET + output.arrayOffset() + output.position();
outputLimit = ARRAY_BYTE_BASE_OFFSET + output.arrayOffset() + output.limit();
}
else {
throw new IllegalArgumentException("Unsupported output ByteBuffer implementation " + output.getClass().getName());
}
// HACK: Assure JVM does not collect Slice wrappers while decompressing, since the
// collection may trigger freeing of the underlying memory resulting in a segfault
// There is no other known way to signal to the JVM that an object should not be
// collected in a block, and technically, the JVM is allowed to eliminate these locks.
synchronized (input) {
synchronized (output) {
int written = new ZstdFrameDecompressor().decompress(inputBase, inputAddress, inputLimit, outputBase, outputAddress, outputLimit);
output.position(output.position() + written);
}
}
}
public static long getDecompressedSize(byte[] input, int offset, int length)
{
int baseAddress = ARRAY_BYTE_BASE_OFFSET + offset;
return ZstdFrameDecompressor.getDecompressedSize(input, baseAddress, baseAddress + length);
}
}

View File

@ -1,958 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boydti.fawe.object.io.zstd;
import java.util.Arrays;
import static com.boydti.fawe.object.io.zstd.BitStream.peekBits;
import static com.boydti.fawe.object.io.zstd.UnsafeUtil.UNSAFE;
import static com.boydti.fawe.object.io.zstd.Util.fail;
import static com.boydti.fawe.object.io.zstd.Util.mask;
import static com.boydti.fawe.object.io.zstd.Util.verify;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
class ZstdFrameDecompressor
{
private static final int MIN_MATCH = 3;
private static final int[] DEC_32_TABLE = {4, 1, 2, 1, 4, 4, 4, 4};
private static final int[] DEC_64_TABLE = {0, 0, 0, -1, 0, 1, 2, 3};
private static final int MAGIC_NUMBER = 0xFD2FB528; // v0.5
private static final int MIN_SEQUENCES_SIZE = 1;
private static final int MIN_BLOCK_SIZE = 1 // block type tag
+ 1 // min size of raw or rle length header
+ MIN_SEQUENCES_SIZE;
private static final int MAX_BLOCK_SIZE = 128 * 1024;
private static final int MIN_WINDOW_LOG = 10;
private static final int MAX_WINDOW_SIZE = 1 << 23;
public static final int SIZE_OF_BYTE = 1;
public static final int SIZE_OF_SHORT = 2;
public static final int SIZE_OF_INT = 4;
public static final int SIZE_OF_LONG = 8;
private static final long SIZE_OF_BLOCK_HEADER = 3;
// block types
private static final int RAW_BLOCK = 0;
private static final int RLE_BLOCK = 1;
private static final int COMPRESSED_BLOCK = 2;
// literal block types
private static final int RAW_LITERALS_BLOCK = 0;
private static final int RLE_LITERALS_BLOCK = 1;
private static final int COMPRESSED_LITERALS_BLOCK = 2;
private static final int REPEAT_STATS_LITERALS_BLOCK = 3;
private static final int LONG_NUMBER_OF_SEQUENCES = 0x7F00;
private static final int MAX_LITERALS_LENGTH_SYMBOL = 35;
private static final int MAX_MATCH_LENGTH_SYMBOL = 52;
private static final int MAX_OFFSET_CODE_SYMBOL = 28;
private static final int LITERALS_LENGTH_FSE_LOG = 9;
private static final int MATCH_LENGTH_FSE_LOG = 9;
private static final int OFFSET_CODES_FSE_LOG = 8;
private static final int SET_BASIC = 0;
private static final int SET_RLE = 1;
private static final int SET_COMPRESSED = 2;
private static final int SET_REPEAT = 3;
private static final int[] LITERALS_LENGTH_BASE = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
0x2000, 0x4000, 0x8000, 0x10000};
private static final int[] MATCH_LENGTH_BASE = {
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
private static final int[] OFFSET_CODES_BASE = {
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
private static final int[] LITERALS_LENGTH_BITS = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16};
private static final int[] MATCH_LENGTH_BITS = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16};
private static final FiniteStateEntropy.Table DEFAULT_LITERALS_LENGTH_TABLE = new FiniteStateEntropy.Table(
6,
new int[] {
0, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 32, 0, 0, 32, 0, 32, 0, 32, 0, 0, 32, 0, 32, 0, 32, 0, 0, 16, 32, 0, 0, 48, 16, 32, 32, 32,
32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0},
new byte[] {
0, 0, 1, 3, 4, 6, 7, 9, 10, 12, 14, 16, 18, 19, 21, 22, 24, 25, 26, 27, 29, 31, 0, 1, 2, 4, 5, 7, 8, 10, 11, 13, 16, 17, 19, 20, 22, 23, 25, 25, 26, 28, 30, 0,
1, 2, 3, 5, 6, 8, 9, 11, 12, 15, 17, 18, 20, 21, 23, 24, 35, 34, 33, 32},
new byte[] {
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 4, 4, 5, 6, 6, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
6, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6});
private static final FiniteStateEntropy.Table DEFAULT_OFFSET_CODES_TABLE = new FiniteStateEntropy.Table(
5,
new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0},
new byte[] {0, 6, 9, 15, 21, 3, 7, 12, 18, 23, 5, 8, 14, 20, 2, 7, 11, 17, 22, 4, 8, 13, 19, 1, 6, 10, 16, 28, 27, 26, 25, 24},
new byte[] {5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5});
private static final FiniteStateEntropy.Table DEFAULT_MATCH_LENGTH_TABLE = new FiniteStateEntropy.Table(
6,
new int[] {
0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 48, 16, 32, 32, 32, 32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new byte[] {
0, 1, 2, 3, 5, 6, 8, 10, 13, 16, 19, 22, 25, 28, 31, 33, 35, 37, 39, 41, 43, 45, 1, 2, 3, 4, 6, 7, 9, 12, 15, 18, 21, 24, 27, 30, 32, 34, 36, 38, 40, 42, 44, 1,
1, 2, 4, 5, 7, 8, 11, 14, 17, 20, 23, 26, 29, 52, 51, 50, 49, 48, 47, 46},
new byte[] {
6, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6});
private final byte[] literals = new byte[MAX_BLOCK_SIZE + SIZE_OF_LONG]; // extra space to allow for long-at-a-time copy
// current buffer containing literals
private Object literalsBase;
private long literalsAddress;
private long literalsLimit;
private final int[] previousOffsets = new int[3];
private final FiniteStateEntropy.Table literalsLengthTable = new FiniteStateEntropy.Table(LITERALS_LENGTH_FSE_LOG);
private final FiniteStateEntropy.Table offsetCodesTable = new FiniteStateEntropy.Table(OFFSET_CODES_FSE_LOG);
private final FiniteStateEntropy.Table matchLengthTable = new FiniteStateEntropy.Table(MATCH_LENGTH_FSE_LOG);
private FiniteStateEntropy.Table currentLiteralsLengthTable;
private FiniteStateEntropy.Table currentOffsetCodesTable;
private FiniteStateEntropy.Table currentMatchLengthTable;
private final Huffman huffman = new Huffman();
private final FseTableReader fse = new FseTableReader();
public int decompress(
final Object inputBase,
final long inputAddress,
final long inputLimit,
final Object outputBase,
final long outputAddress,
final long outputLimit)
{
if (outputAddress == outputLimit) {
return 0;
}
reset();
long input = inputAddress;
long output = outputAddress;
input += verifyMagic(inputBase, inputAddress, inputLimit);
FrameHeader frameHeader = readFrameHeader(inputBase, input, inputLimit);
input += frameHeader.headerSize;
boolean lastBlock;
do {
verify(input + SIZE_OF_BLOCK_HEADER <= inputLimit, input, "Not enough input bytes");
// read block header
int header = UNSAFE.getInt(inputBase, input) & 0xFF_FFFF;
input += SIZE_OF_BLOCK_HEADER;
lastBlock = (header & 1) != 0;
int blockType = (header >>> 1) & 0b11;
int blockSize = (header >>> 3) & 0x1F_FFFF; // 21 bits
int decodedSize;
switch (blockType) {
case RAW_BLOCK:
verify(inputAddress + blockSize <= inputLimit, input, "Not enough input bytes");
decodedSize = decodeRawBlock(inputBase, input, blockSize, outputBase, output, outputLimit);
input += blockSize;
break;
case RLE_BLOCK:
verify(inputAddress + 1 <= inputLimit, input, "Not enough input bytes");
decodedSize = decodeRleBlock(blockSize, inputBase, input, outputBase, output, outputLimit);
input += 1;
break;
case COMPRESSED_BLOCK:
verify(inputAddress + blockSize <= inputLimit, input, "Not enough input bytes");
decodedSize = decodeCompressedBlock(inputBase, input, blockSize, outputBase, output, outputLimit, frameHeader.windowSize);
input += blockSize;
break;
default:
throw fail(input, "Invalid block type");
}
output += decodedSize;
}
while (!lastBlock);
if (frameHeader.hasChecksum) {
// TODO checksum
}
return (int) (output - outputAddress);
}
private void reset()
{
previousOffsets[0] = 1;
previousOffsets[1] = 4;
previousOffsets[2] = 8;
currentLiteralsLengthTable = null;
currentOffsetCodesTable = null;
currentMatchLengthTable = null;
}
private static int decodeRawBlock(Object inputBase, long inputAddress, int blockSize, Object outputBase, long outputAddress, long outputLimit)
{
verify(outputAddress + blockSize <= outputLimit, inputAddress, "Output buffer too small");
UNSAFE.copyMemory(inputBase, inputAddress, outputBase, outputAddress, blockSize);
return blockSize;
}
private static int decodeRleBlock(int size, Object inputBase, long inputAddress, Object outputBase, long outputAddress, long outputLimit)
{
verify(outputAddress + size <= outputLimit, inputAddress, "Output buffer too small");
long output = outputAddress;
long value = UNSAFE.getByte(inputBase, inputAddress) & 0xFFL;
int remaining = size;
if (remaining >= SIZE_OF_LONG) {
long packed = value
| (value << 8)
| (value << 16)
| (value << 24)
| (value << 32)
| (value << 40)
| (value << 48)
| (value << 56);
do {
UNSAFE.putLong(outputBase, output, packed);
output += SIZE_OF_LONG;
remaining -= SIZE_OF_LONG;
}
while (remaining >= SIZE_OF_LONG);
}
for (int i = 0; i < remaining; i++) {
UNSAFE.putByte(outputBase, output, (byte) value);
output++;
}
return size;
}
private int decodeCompressedBlock(Object inputBase, final long inputAddress, int blockSize, Object outputBase, long outputAddress, long outputLimit, int windowSize)
{
long inputLimit = inputAddress + blockSize;
long input = inputAddress;
verify(blockSize <= MAX_BLOCK_SIZE, input, "Expected match length table to be present");
verify(blockSize >= MIN_BLOCK_SIZE, input, "Compressed block size too small");
// decode literals
int literalsBlockType = UNSAFE.getByte(inputBase, input) & 0b11;
switch (literalsBlockType) {
case RAW_LITERALS_BLOCK: {
input += decodeRawLiterals(inputBase, input, inputLimit);
break;
}
case RLE_LITERALS_BLOCK: {
input += decodeRleLiterals(inputBase, input, blockSize);
break;
}
case REPEAT_STATS_LITERALS_BLOCK:
verify(huffman.isLoaded(), input, "Dictionary is corrupted");
case COMPRESSED_LITERALS_BLOCK: {
input += decodeCompressedLiterals(inputBase, input, blockSize, literalsBlockType);
break;
}
default:
throw fail(input, "Invalid literals block encoding type");
}
verify(windowSize <= MAX_WINDOW_SIZE, input, "Window size too large (not yet supported)");
return decompressSequences(
inputBase, input, inputAddress + blockSize,
outputBase, outputAddress, outputLimit,
literalsBase, literalsAddress, literalsLimit);
}
private int decompressSequences(
final Object inputBase, final long inputAddress, final long inputLimit,
final Object outputBase, final long outputAddress, final long outputLimit,
final Object literalsBase, final long literalsAddress, final long literalsLimit)
{
final long fastOutputLimit = outputLimit - SIZE_OF_LONG;
long input = inputAddress;
long output = outputAddress;
long literalsInput = literalsAddress;
int size = (int) (inputLimit - inputAddress);
verify(size >= MIN_SEQUENCES_SIZE, input, "Not enough input bytes");
// decode header
int sequenceCount = UNSAFE.getByte(inputBase, input++) & 0xFF;
if (sequenceCount != 0) {
if (sequenceCount == 255) {
verify(input + SIZE_OF_SHORT <= inputLimit, input, "Not enough input bytes");
sequenceCount = (UNSAFE.getShort(inputBase, input) & 0xFFFF) + LONG_NUMBER_OF_SEQUENCES;
input += SIZE_OF_SHORT;
}
else if (sequenceCount > 127) {
verify(input < inputLimit, input, "Not enough input bytes");
sequenceCount = ((sequenceCount - 128) << 8) + (UNSAFE.getByte(inputBase, input++) & 0xFF);
}
verify(input + SIZE_OF_INT <= inputLimit, input, "Not enough input bytes");
byte type = UNSAFE.getByte(inputBase, input++);
int literalsLengthType = (type & 0xFF) >>> 6;
int offsetCodesType = (type >>> 4) & 0b11;
int matchLengthType = (type >>> 2) & 0b11;
input = computeLiteralsTable(literalsLengthType, inputBase, input, inputLimit);
input = computeOffsetsTable(offsetCodesType, inputBase, input, inputLimit);
input = computeMatchLengthTable(matchLengthType, inputBase, input, inputLimit);
// decompress sequences
BitStream.Initializer initializer = new BitStream.Initializer(inputBase, input, inputLimit);
initializer.initialize();
int bitsConsumed = initializer.getBitsConsumed();
long bits = initializer.getBits();
long currentAddress = initializer.getCurrentAddress();
FiniteStateEntropy.Table currentLiteralsLengthTable = this.currentLiteralsLengthTable;
FiniteStateEntropy.Table currentOffsetCodesTable = this.currentOffsetCodesTable;
FiniteStateEntropy.Table currentMatchLengthTable = this.currentMatchLengthTable;
int literalsLengthState = (int) peekBits(bitsConsumed, bits, currentLiteralsLengthTable.log2Size);
bitsConsumed += currentLiteralsLengthTable.log2Size;
int offsetCodesState = (int) peekBits(bitsConsumed, bits, currentOffsetCodesTable.log2Size);
bitsConsumed += currentOffsetCodesTable.log2Size;
int matchLengthState = (int) peekBits(bitsConsumed, bits, currentMatchLengthTable.log2Size);
bitsConsumed += currentMatchLengthTable.log2Size;
int[] previousOffsets = this.previousOffsets;
byte[] literalsLengthNumbersOfBits = currentLiteralsLengthTable.numberOfBits;
int[] literalsLengthNewStates = currentLiteralsLengthTable.newState;
byte[] literalsLengthSymbols = currentLiteralsLengthTable.symbol;
byte[] matchLengthNumbersOfBits = currentMatchLengthTable.numberOfBits;
int[] matchLengthNewStates = currentMatchLengthTable.newState;
byte[] matchLengthSymbols = currentMatchLengthTable.symbol;
byte[] offsetCodesNumbersOfBits = currentOffsetCodesTable.numberOfBits;
int[] offsetCodesNewStates = currentOffsetCodesTable.newState;
byte[] offsetCodesSymbols = currentOffsetCodesTable.symbol;
while (sequenceCount > 0) {
sequenceCount--;
BitStream.Loader loader = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader.load();
bitsConsumed = loader.getBitsConsumed();
bits = loader.getBits();
currentAddress = loader.getCurrentAddress();
if (loader.isOverflow()) {
verify(sequenceCount == 0, input, "Not all sequences were consumed");
break;
}
// decode sequence
int literalsLengthCode = literalsLengthSymbols[literalsLengthState];
int matchLengthCode = matchLengthSymbols[matchLengthState];
int offsetCode = offsetCodesSymbols[offsetCodesState];
int literalsLengthBits = LITERALS_LENGTH_BITS[literalsLengthCode];
int matchLengthBits = MATCH_LENGTH_BITS[matchLengthCode];
int offsetBits = offsetCode;
int offset = OFFSET_CODES_BASE[offsetCode];
if (offsetCode > 0) {
offset += peekBits(bitsConsumed, bits, offsetBits);
bitsConsumed += offsetBits;
}
if (offsetCode <= 1) {
if (literalsLengthCode == 0) {
offset++;
}
if (offset != 0) {
int temp;
if (offset == 3) {
temp = previousOffsets[0] - 1;
}
else {
temp = previousOffsets[offset];
}
if (temp == 0) {
temp = 1;
}
if (offset != 1) {
previousOffsets[2] = previousOffsets[1];
}
previousOffsets[1] = previousOffsets[0];
previousOffsets[0] = temp;
offset = temp;
}
else {
offset = previousOffsets[0];
}
}
else {
previousOffsets[2] = previousOffsets[1];
previousOffsets[1] = previousOffsets[0];
previousOffsets[0] = offset;
}
int matchLength = MATCH_LENGTH_BASE[matchLengthCode];
if (matchLengthCode > 31) {
matchLength += peekBits(bitsConsumed, bits, matchLengthBits);
bitsConsumed += matchLengthBits;
}
int literalsLength = LITERALS_LENGTH_BASE[literalsLengthCode];
if (literalsLengthCode > 15) {
literalsLength += peekBits(bitsConsumed, bits, literalsLengthBits);
bitsConsumed += literalsLengthBits;
}
int totalBits = literalsLengthBits + matchLengthBits + offsetBits;
if (totalBits > 64 - 7 - (LITERALS_LENGTH_FSE_LOG + MATCH_LENGTH_FSE_LOG + OFFSET_CODES_FSE_LOG)) {
BitStream.Loader loader1 = new BitStream.Loader(inputBase, input, currentAddress, bits, bitsConsumed);
loader1.load();
bitsConsumed = loader1.getBitsConsumed();
bits = loader1.getBits();
currentAddress = loader1.getCurrentAddress();
}
int numberOfBits;
numberOfBits = literalsLengthNumbersOfBits[literalsLengthState];
literalsLengthState = (int) (literalsLengthNewStates[literalsLengthState] + peekBits(bitsConsumed, bits, numberOfBits)); // <= 9 bits
bitsConsumed += numberOfBits;
numberOfBits = matchLengthNumbersOfBits[matchLengthState];
matchLengthState = (int) (matchLengthNewStates[matchLengthState] + peekBits(bitsConsumed, bits, numberOfBits)); // <= 9 bits
bitsConsumed += numberOfBits;
numberOfBits = offsetCodesNumbersOfBits[offsetCodesState];
offsetCodesState = (int) (offsetCodesNewStates[offsetCodesState] + peekBits(bitsConsumed, bits, numberOfBits)); // <= 8 bits
bitsConsumed += numberOfBits;
final long literalOutputLimit = output + literalsLength;
final long matchOutputLimit = literalOutputLimit + matchLength;
verify(matchOutputLimit <= outputLimit, input, "Output buffer too small");
verify(literalsInput + literalsLength <= literalsLimit, input, "Input is corrupted");
long matchAddress = literalOutputLimit - offset;
if (literalOutputLimit > fastOutputLimit) {
executeLastSequence(outputBase, output, literalOutputLimit, matchOutputLimit, fastOutputLimit, literalsInput, matchAddress);
}
else {
// copy literals. literalOutputLimit <= fastOutputLimit, so we can copy
// long at a time with over-copy
output = copyLiterals(outputBase, literalsBase, output, literalsInput, literalOutputLimit);
copyMatch(outputBase, fastOutputLimit, output, offset, matchOutputLimit, matchAddress);
}
output = matchOutputLimit;
literalsInput += literalsLength;
}
}
// last literal segment
output = copyLastLiteral(outputBase, literalsBase, literalsLimit, output, literalsInput);
return (int) (output - outputAddress);
}
private long copyLastLiteral(Object outputBase, Object literalsBase, long literalsLimit, long output, long literalsInput)
{
long lastLiteralsSize = literalsLimit - literalsInput;
UNSAFE.copyMemory(literalsBase, literalsInput, outputBase, output, lastLiteralsSize);
output += lastLiteralsSize;
return output;
}
private void copyMatch(Object outputBase, long fastOutputLimit, long output, int offset, long matchOutputLimit, long matchAddress)
{
matchAddress = copyMatchHead(outputBase, output, offset, matchAddress);
output += SIZE_OF_LONG;
copyMatchTail(outputBase, fastOutputLimit, output, matchOutputLimit, matchAddress);
}
private void copyMatchTail(Object outputBase, long fastOutputLimit, long output, long matchOutputLimit, long matchAddress)
{
if (matchOutputLimit > fastOutputLimit) {
while (output < fastOutputLimit) {
UNSAFE.putLong(outputBase, output, UNSAFE.getLong(outputBase, matchAddress));
matchAddress += SIZE_OF_LONG;
output += SIZE_OF_LONG;
}
while (output < matchOutputLimit) {
UNSAFE.putByte(outputBase, output++, UNSAFE.getByte(outputBase, matchAddress++));
}
}
else {
while (output < matchOutputLimit) {
UNSAFE.putLong(outputBase, output, UNSAFE.getLong(outputBase, matchAddress));
matchAddress += SIZE_OF_LONG;
output += SIZE_OF_LONG;
}
}
}
private long copyMatchHead(Object outputBase, long output, int offset, long matchAddress)
{
// copy match
if (offset < 8) {
// 8 bytes apart so that we can copy long-at-a-time below
int increment32 = DEC_32_TABLE[offset];
int decrement64 = DEC_64_TABLE[offset];
UNSAFE.putByte(outputBase, output, UNSAFE.getByte(outputBase, matchAddress));
UNSAFE.putByte(outputBase, output + 1, UNSAFE.getByte(outputBase, matchAddress + 1));
UNSAFE.putByte(outputBase, output + 2, UNSAFE.getByte(outputBase, matchAddress + 2));
UNSAFE.putByte(outputBase, output + 3, UNSAFE.getByte(outputBase, matchAddress + 3));
matchAddress += increment32;
UNSAFE.putInt(outputBase, output + 4, UNSAFE.getInt(outputBase, matchAddress));
matchAddress -= decrement64;
}
else {
UNSAFE.putLong(outputBase, output, UNSAFE.getLong(outputBase, matchAddress));
matchAddress += SIZE_OF_LONG;
}
return matchAddress;
}
private long copyLiterals(Object outputBase, Object literalsBase, long output, long literalsInput, long literalOutputLimit)
{
long literalInput = literalsInput;
do {
UNSAFE.putLong(outputBase, output, UNSAFE.getLong(literalsBase, literalInput));
output += SIZE_OF_LONG;
literalInput += SIZE_OF_LONG;
}
while (output < literalOutputLimit);
output = literalOutputLimit; // correction in case we over-copied
return output;
}
private long computeMatchLengthTable(int matchLengthType, Object inputBase, long input, long inputLimit)
{
switch (matchLengthType) {
case SET_RLE:
verify(input < inputLimit, input, "Not enough input bytes");
byte value = UNSAFE.getByte(inputBase, input++);
verify(value <= MAX_MATCH_LENGTH_SYMBOL, input, "Value exceeds expected maximum value");
FseTableReader.buildRleTable(matchLengthTable, value);
currentMatchLengthTable = matchLengthTable;
break;
case SET_BASIC:
currentMatchLengthTable = DEFAULT_MATCH_LENGTH_TABLE;
break;
case SET_REPEAT:
verify(currentMatchLengthTable != null, input, "Expected match length table to be present");
break;
case SET_COMPRESSED:
input += fse.readFseTable(matchLengthTable, inputBase, input, inputLimit, MAX_MATCH_LENGTH_SYMBOL, MATCH_LENGTH_FSE_LOG);
currentMatchLengthTable = matchLengthTable;
break;
default:
throw fail(input, "Invalid match length encoding type");
}
return input;
}
private long computeOffsetsTable(int offsetCodesType, Object inputBase, long input, long inputLimit)
{
switch (offsetCodesType) {
case SET_RLE:
verify(input < inputLimit, input, "Not enough input bytes");
byte value = UNSAFE.getByte(inputBase, input++);
verify(value <= MAX_OFFSET_CODE_SYMBOL, input, "Value exceeds expected maximum value");
FseTableReader.buildRleTable(offsetCodesTable, value);
currentOffsetCodesTable = offsetCodesTable;
break;
case SET_BASIC:
currentOffsetCodesTable = DEFAULT_OFFSET_CODES_TABLE;
break;
case SET_REPEAT:
verify(currentOffsetCodesTable != null, input, "Expected match length table to be present");
break;
case SET_COMPRESSED:
input += fse.readFseTable(offsetCodesTable, inputBase, input, inputLimit, MAX_OFFSET_CODE_SYMBOL, OFFSET_CODES_FSE_LOG);
currentOffsetCodesTable = offsetCodesTable;
break;
default:
throw fail(input, "Invalid offset code encoding type");
}
return input;
}
private long computeLiteralsTable(int literalsLengthType, Object inputBase, long input, long inputLimit)
{
switch (literalsLengthType) {
case SET_RLE:
verify(input < inputLimit, input, "Not enough input bytes");
byte value = UNSAFE.getByte(inputBase, input++);
verify(value <= MAX_LITERALS_LENGTH_SYMBOL, input, "Value exceeds expected maximum value");
FseTableReader.buildRleTable(literalsLengthTable, value);
currentLiteralsLengthTable = literalsLengthTable;
break;
case SET_BASIC:
currentLiteralsLengthTable = DEFAULT_LITERALS_LENGTH_TABLE;
break;
case SET_REPEAT:
verify(currentLiteralsLengthTable != null, input, "Expected match length table to be present");
break;
case SET_COMPRESSED:
input += fse.readFseTable(literalsLengthTable, inputBase, input, inputLimit, MAX_LITERALS_LENGTH_SYMBOL, LITERALS_LENGTH_FSE_LOG);
currentLiteralsLengthTable = literalsLengthTable;
break;
default:
throw fail(input, "Invalid literals length encoding type");
}
return input;
}
private void executeLastSequence(Object outputBase, long output, long literalOutputLimit, long matchOutputLimit, long fastOutputLimit, long literalInput, long matchAddress)
{
// copy literals
if (output < fastOutputLimit) {
// wild copy
do {
UNSAFE.putLong(outputBase, output, UNSAFE.getLong(literalsBase, literalInput));
output += SIZE_OF_LONG;
literalInput += SIZE_OF_LONG;
}
while (output < fastOutputLimit);
literalInput -= output - fastOutputLimit;
output = fastOutputLimit;
}
while (output < literalOutputLimit) {
UNSAFE.putByte(outputBase, output, UNSAFE.getByte(literalsBase, literalInput));
output++;
literalInput++;
}
// copy match
while (output < matchOutputLimit) {
UNSAFE.putByte(outputBase, output, UNSAFE.getByte(outputBase, matchAddress));
output++;
matchAddress++;
}
}
private int decodeCompressedLiterals(Object inputBase, final long inputAddress, int blockSize, int literalsBlockType)
{
long input = inputAddress;
verify(blockSize >= 5, input, "Not enough input bytes");
// compressed
int compressedSize;
int uncompressedSize;
boolean singleStream = false;
int headerSize;
int type = (UNSAFE.getByte(inputBase, input) >> 2) & 0b11;
switch (type) {
case 0:
singleStream = true;
case 1: {
int header = UNSAFE.getInt(inputBase, input);
headerSize = 3;
uncompressedSize = (header >>> 4) & mask(10);
compressedSize = (header >>> 14) & mask(10);
break;
}
case 2: {
int header = UNSAFE.getInt(inputBase, input);
headerSize = 4;
uncompressedSize = (header >>> 4) & mask(14);
compressedSize = (header >>> 18) & mask(14);
break;
}
case 3: {
// read 5 little-endian bytes
long header = UNSAFE.getByte(inputBase, input) & 0xFF |
(UNSAFE.getInt(inputBase, input + 1) & 0xFFFF_FFFFL) << 8;
headerSize = 5;
uncompressedSize = (int) ((header >>> 4) & mask(18));
compressedSize = (int) ((header >>> 22) & mask(18));
break;
}
default:
throw fail(input, "Invalid literals header size type");
}
verify(uncompressedSize <= MAX_BLOCK_SIZE, input, "Block exceeds maximum size");
verify(headerSize + compressedSize <= blockSize, input, "Input is corrupted");
input += headerSize;
long inputLimit = input + compressedSize;
if (literalsBlockType != REPEAT_STATS_LITERALS_BLOCK) {
input += huffman.readTable(inputBase, input, compressedSize);
}
literalsBase = literals;
literalsAddress = ARRAY_BYTE_BASE_OFFSET;
literalsLimit = ARRAY_BYTE_BASE_OFFSET + uncompressedSize;
if (singleStream) {
huffman.decodeSingleStream(inputBase, input, inputLimit, literals, literalsAddress, literalsLimit);
}
else {
huffman.decode4Streams(inputBase, input, inputLimit, literals, literalsAddress, literalsLimit);
}
return headerSize + compressedSize;
}
private int decodeRleLiterals(Object inputBase, final long inputAddress, int blockSize)
{
long input = inputAddress;
int outputSize;
int type = (UNSAFE.getByte(inputBase, input) >> 2) & 0b11;
switch (type) {
case 0:
case 2:
outputSize = (UNSAFE.getByte(inputBase, input) & 0xFF) >>> 3;
input++;
break;
case 1:
outputSize = (UNSAFE.getShort(inputBase, input) & 0xFFFF) >>> 4;
input += 2;
break;
case 3:
// we need at least 4 bytes (3 for the header, 1 for the payload)
verify(blockSize >= SIZE_OF_INT, input, "Not enough input bytes");
outputSize = (UNSAFE.getInt(inputBase, input) & 0xFF_FFFF) >>> 4;
input += 3;
break;
default:
throw fail(input, "Invalid RLE literals header encoding type");
}
verify(outputSize <= MAX_BLOCK_SIZE, input, "Output exceeds maximum block size");
byte value = UNSAFE.getByte(inputBase, input++);
Arrays.fill(literals, 0, outputSize + SIZE_OF_LONG, value);
literalsBase = literals;
literalsAddress = ARRAY_BYTE_BASE_OFFSET;
literalsLimit = ARRAY_BYTE_BASE_OFFSET + outputSize;
return (int) (input - inputAddress);
}
private int decodeRawLiterals(Object inputBase, final long inputAddress, long inputLimit)
{
long input = inputAddress;
int type = (UNSAFE.getByte(inputBase, input) >> 2) & 0b11;
int literalSize;
switch (type) {
case 0:
case 2:
literalSize = (UNSAFE.getByte(inputBase, input) & 0xFF) >>> 3;
input++;
break;
case 1:
literalSize = (UNSAFE.getShort(inputBase, input) & 0xFFFF) >>> 4;
input += 2;
break;
case 3:
// read 3 little-endian bytes
int header = ((UNSAFE.getByte(inputBase, input) & 0xFF) |
((UNSAFE.getShort(inputBase, input + 1) & 0xFFFF) << 8));
literalSize = header >>> 4;
input += 3;
break;
default:
throw fail(input, "Invalid raw literals header encoding type");
}
verify(input + literalSize <= inputLimit, input, "Not enough input bytes");
// Set literals pointer to [input, literalSize], but only if we can copy 8 bytes at a time during sequence decoding
// Otherwise, copy literals into buffer that's big enough to guarantee that
if (literalSize > (inputLimit - input) - SIZE_OF_LONG) {
literalsBase = literals;
literalsAddress = ARRAY_BYTE_BASE_OFFSET;
literalsLimit = ARRAY_BYTE_BASE_OFFSET + literalSize;
UNSAFE.copyMemory(inputBase, input, literals, literalsAddress, literalSize);
Arrays.fill(literals, literalSize, literalSize + SIZE_OF_LONG, (byte) 0);
}
else {
literalsBase = inputBase;
literalsAddress = input;
literalsLimit = literalsAddress + literalSize;
}
input += literalSize;
return (int) (input - inputAddress);
}
private static FrameHeader readFrameHeader(final Object inputBase, final long inputAddress, final long inputLimit)
{
long input = inputAddress;
verify(input < inputLimit, input, "Not enough input bytes");
int frameHeaderDescriptor = UNSAFE.getByte(inputBase, input++) & 0xFF;
boolean singleSegment = (frameHeaderDescriptor & 0b100000) != 0;
int dictionaryDescriptor = frameHeaderDescriptor & 0b11;
int contentSizeDescriptor = frameHeaderDescriptor >>> 6;
int headerSize = 1 +
(singleSegment ? 0 : 1) +
(dictionaryDescriptor == 0 ? 0 : (1 << (dictionaryDescriptor - 1))) +
(contentSizeDescriptor == 0 ? (singleSegment ? 1 : 0) : (1 << contentSizeDescriptor));
verify(headerSize <= inputLimit - inputAddress, input, "Not enough input bytes");
// decode window size
int windowSize = -1;
if (!singleSegment) {
int windowDescriptor = UNSAFE.getByte(inputBase, input++) & 0xFF;
int exponent = windowDescriptor >>> 3;
int mantissa = windowDescriptor & 0b111;
int base = 1 << (MIN_WINDOW_LOG + exponent);
windowSize = base + (base / 8) * mantissa;
}
// decode dictionary id
long dictionaryId = -1;
switch (dictionaryDescriptor) {
case 1:
dictionaryId = UNSAFE.getByte(inputBase, input) & 0xFF;
input += SIZE_OF_BYTE;
break;
case 2:
dictionaryId = UNSAFE.getShort(inputBase, input) & 0xFFFF;
input += SIZE_OF_SHORT;
break;
case 3:
dictionaryId = UNSAFE.getInt(inputBase, input) & 0xFFFF_FFFFL;
input += SIZE_OF_INT;
break;
}
verify(dictionaryId == -1, input, "Custom dictionaries not supported");
// decode content size
long contentSize = -1;
switch (contentSizeDescriptor) {
case 0:
if (singleSegment) {
contentSize = UNSAFE.getByte(inputBase, input) & 0xFF;
input += SIZE_OF_BYTE;
}
break;
case 1:
contentSize = UNSAFE.getShort(inputBase, input) & 0xFFFF;
contentSize += 256;
input += SIZE_OF_SHORT;
break;
case 2:
contentSize = UNSAFE.getInt(inputBase, input) & 0xFFFF_FFFFL;
input += SIZE_OF_INT;
break;
case 3:
contentSize = UNSAFE.getLong(inputBase, input);
input += SIZE_OF_LONG;
break;
}
boolean hasChecksum = (frameHeaderDescriptor & 0b100) != 0;
return new FrameHeader(
input - inputAddress,
windowSize,
contentSize,
dictionaryId,
hasChecksum);
}
public static long getDecompressedSize(final Object inputBase, final long inputAddress, final long inputLimit)
{
long input = inputAddress;
input += verifyMagic(inputBase, input, inputLimit);
return readFrameHeader(inputBase, input, inputLimit).contentSize;
}
private static int verifyMagic(Object inputBase, long inputAddress, long inputLimit)
{
verify(inputLimit - inputAddress >= 4, inputAddress, "Not enough input bytes");
int magic = UNSAFE.getInt(inputBase, inputAddress);
if (magic != MAGIC_NUMBER) {
throw new MalformedInputException(inputAddress, "Invalid magic prefix: " + Integer.toHexString(magic));
}
return SIZE_OF_INT;
}
}

View File

@ -23,7 +23,6 @@ public class ReflectionUtils {
return t.isInstance(o) ? t.cast(o) : null; return t.isInstance(o) ? t.cast(o) : null;
} }
@SuppressWarnings("unchecked")
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) { public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
try { try {
return addEnum(enumType, enumName, new Class<?>[]{}, new Object[]{}); return addEnum(enumType, enumName, new Class<?>[]{}, new Object[]{});

View File

@ -157,19 +157,6 @@ public class PlayerWrapper extends AbstractPlayerActor {
parent.setGameMode(gameMode); parent.setGameMode(gameMode);
} }
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
@Override @Override
public void findFreePosition(final Location searchPos) { public void findFreePosition(final Location searchPos) {
TaskManager.IMP.sync(new RunnableVal<Boolean>() { TaskManager.IMP.sync(new RunnableVal<Boolean>() {

View File

@ -19,19 +19,13 @@
package com.sk89q.util; package com.sk89q.util;
import sun.reflect.ConstructorAccessor; import java.lang.reflect.Field;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.*;
import java.util.*;
public final class ReflectionUtil { public final class ReflectionUtil {
private ReflectionUtil() { private ReflectionUtil() {
} }
@SuppressWarnings("unchecked")
public static <T> T getField(Object from, String name) { public static <T> T getField(Object from, String name) {
if (from instanceof Class) if (from instanceof Class)
return getField((Class) from, null, name); return getField((Class) from, null, name);

View File

@ -570,6 +570,7 @@ public class LocalSession implements TextureHolder {
newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.REDO); newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.REDO);
return newEditSession; return newEditSession;
} }
return null; return null;
} }
@ -625,14 +626,6 @@ public class LocalSession implements TextureHolder {
return selector; return selector;
} }
/**
* @deprecated use {@link #getRegionSelector(World)}
*/
@Deprecated
public RegionSelector getRegionSelector() {
return selector;
}
/** /**
* Set the region selector. * Set the region selector.
* *
@ -646,16 +639,6 @@ public class LocalSession implements TextureHolder {
this.selector = selector; this.selector = selector;
} }
/**
* Returns true if the region is fully defined.
*
* @return true if a region selection is defined
*/
@Deprecated
public boolean isRegionDefined() {
return selector.isDefined();
}
/** /**
* Returns true if the region is fully defined for the specified world. * Returns true if the region is fully defined for the specified world.
* *
@ -670,14 +653,6 @@ public class LocalSession implements TextureHolder {
return selector.isDefined(); return selector.isDefined();
} }
/**
* @deprecated use {@link #getSelection(World)}
*/
@Deprecated
public Region getRegion() throws IncompleteRegionException {
return selector.getRegion();
}
/** /**
* Get the selection region. If you change the region, you should * Get the selection region. If you change the region, you should
* call learnRegionChanges(). If the selection is defined in * call learnRegionChanges(). If the selection is defined in
@ -907,7 +882,7 @@ public class LocalSession implements TextureHolder {
public BlockVector3 getPlacementPosition(Player player) throws IncompleteRegionException { public BlockVector3 getPlacementPosition(Player player) throws IncompleteRegionException {
checkNotNull(player); checkNotNull(player);
if (!placeAtPos1) { if (!placeAtPos1) {
return player.getBlockIn().toBlockPoint(); return player.getBlockIn().toVector().toBlockPoint();
} }
return selector.getPrimaryPosition(); return selector.getPrimaryPosition();
@ -976,6 +951,12 @@ public class LocalSession implements TextureHolder {
this.pickaxeMode = tool; this.pickaxeMode = tool;
} }
/**
* Get the tool assigned to the item.
*
* @param item the item type
* @return the tool, which may be {@code null}
*/
@Nullable @Nullable
public Tool getTool(ItemType item) { public Tool getTool(ItemType item) {
return tools[item.getInternalId()]; return tools[item.getInternalId()];
@ -1012,11 +993,6 @@ public class LocalSession implements TextureHolder {
return getBrushTool(item.getDefaultState(), null, true); return getBrushTool(item.getDefaultState(), null, true);
} }
@Deprecated
public BrushTool getBrushTool(BaseItem item) throws InvalidToolBindException {
return getBrushTool(item, null, true);
}
public BrushTool getBrushTool(Player player) throws InvalidToolBindException { public BrushTool getBrushTool(Player player) throws InvalidToolBindException {
return getBrushTool(player, true); return getBrushTool(player, true);
} }
@ -1048,7 +1024,6 @@ public class LocalSession implements TextureHolder {
* @param tool the tool to set, which can be {@code null} * @param tool the tool to set, which can be {@code null}
* @throws InvalidToolBindException if the item can't be bound to that item * @throws InvalidToolBindException if the item can't be bound to that item
*/ */
@Deprecated
public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindException { public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindException {
setTool(item.getDefaultState(), tool, null); setTool(item.getDefaultState(), tool, null);
} }
@ -1141,7 +1116,6 @@ public class LocalSession implements TextureHolder {
public void tellVersion(Actor player) { public void tellVersion(Actor player) {
} }
public boolean shouldUseServerCUI() { public boolean shouldUseServerCUI() {
return this.useServerCUI; return this.useServerCUI;
} }
@ -1209,9 +1183,8 @@ public class LocalSession implements TextureHolder {
if (hasCUISupport) { if (hasCUISupport) {
actor.dispatchCUIEvent(event); actor.dispatchCUIEvent(event);
} else if (actor.isPlayer()) { } else if (useServerCUI) {
CUI cui = Fawe.get().getCUI(actor); updateServerCUI(actor);
if (cui != null) cui.dispatchCUIEvent(event);
} }
} }
@ -1243,12 +1216,13 @@ public class LocalSession implements TextureHolder {
CUIRegion tempSel = (CUIRegion) selector; CUIRegion tempSel = (CUIRegion) selector;
if (tempSel.getProtocolVersion() > cuiVersion) { if (tempSel.getProtocolVersion() > cuiVersion) {
dispatchCUIEvent(actor, new SelectionShapeEvent(tempSel.getLegacyTypeID())); actor.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getLegacyTypeID()));
tempSel.describeLegacyCUI(this, actor); tempSel.describeLegacyCUI(this, actor);
} else { } else {
dispatchCUIEvent(actor, new SelectionShapeEvent(tempSel.getTypeID())); actor.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getTypeID()));
tempSel.describeCUI(this, actor); tempSel.describeCUI(this, actor);
} }
} }
} }
@ -1259,6 +1233,11 @@ public class LocalSession implements TextureHolder {
*/ */
public void describeCUI(Actor actor) { public void describeCUI(Actor actor) {
checkNotNull(actor); checkNotNull(actor);
if (!hasCUISupport) {
return;
}
if (selector instanceof CUIRegion) { if (selector instanceof CUIRegion) {
CUIRegion tempSel = (CUIRegion) selector; CUIRegion tempSel = (CUIRegion) selector;
@ -1285,18 +1264,15 @@ public class LocalSession implements TextureHolder {
String[] split = text.split("\\|", 2); String[] split = text.split("\\|", 2);
if (split.length > 1 && split[0].equalsIgnoreCase("v")) { // enough fields and right message if (split.length > 1 && split[0].equalsIgnoreCase("v")) { // enough fields and right message
if (split[1].length() > 4) { if (split[1].length() > 4) {
this.failedCuiAttempts++; this.failedCuiAttempts ++;
return; return;
} }
setCUISupport(true); setCUISupport(true);
try { try {
setCUIVersion(Integer.parseInt(split[1])); setCUIVersion(Integer.parseInt(split[1]));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
String msg = e.getMessage(); WorldEdit.logger.warn("Error while reading CUI init message: " + e.getMessage());
if (msg != null && msg.length() > 256) msg = msg.substring(0, 256); this.failedCuiAttempts ++;
this.failedCuiAttempts++;
WorldEdit.logger.warn("Error while reading CUI init message for player " + uuid + ": " + msg);
} }
} }
} }
@ -1364,7 +1340,6 @@ public class LocalSession implements TextureHolder {
* @param player the player * @param player the player
* @return an edit session * @return an edit session
*/ */
@SuppressWarnings("deprecation")
public EditSession createEditSession(Player player) { public EditSession createEditSession(Player player) {
checkNotNull(player); checkNotNull(player);

View File

@ -23,7 +23,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweVersion; import com.boydti.fawe.FaweVersion;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.*; import com.boydti.fawe.util.IncendoPaster;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
@ -32,16 +32,24 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent; import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
import com.sk89q.worldedit.extension.platform.*; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extension.platform.PlatformManager; import com.sk89q.worldedit.extension.platform.PlatformManager;
import java.io.IOException; import java.io.IOException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TimeZone;
@Command(aliases = {"worldedit", "we", "fawe"}, desc = "Updating, informational, debug and help commands") @Command(aliases = {"worldedit", "we", "fawe"}, desc = "Updating, informational, debug and help commands")
public class WorldEditCommands { public class WorldEditCommands {
@ -54,19 +62,19 @@ public class WorldEditCommands {
} }
@Command( @Command(
aliases = {"version", "ver"}, aliases = { "version", "ver" },
usage = "", usage = "",
desc = "Get WorldEdit/FAWE version", desc = "Get WorldEdit/FAWE version",
min = 0, min = 0,
max = 0, max = 0,
queued = false queued = false
) )
public void version(Actor actor) throws WorldEditException { public void version(Actor actor) throws WorldEditException {
FaweVersion fVer = Fawe.get().getVersion(); FaweVersion fVer = Fawe.get().getVersion();
String fVerStr = fVer == null ? "unknown" : "-" + fVer.build; String fVerStr = fVer == null ? "unknown" : "-" + fVer.build;
actor.print(BBC.getPrefix() + "FastAsyncWorldEdit-1.13" + fVerStr + " by Empire92"); actor.print("FastAsyncWorldEdit-1.13" + fVerStr + " by Empire92");
if (fVer != null) { if (fVer != null) {
actor.printDebug("------------------------------------"); actor.printDebug("----------- Platforms -----------");
FaweVersion version = Fawe.get().getVersion(); FaweVersion version = Fawe.get().getVersion();
Date date = new GregorianCalendar(2000 + version.year, version.month - 1, version.day).getTime(); Date date = new GregorianCalendar(2000 + version.year, version.month - 1, version.day).getTime();
actor.printDebug(" - DATE: " + date.toLocaleString()); actor.printDebug(" - DATE: " + date.toLocaleString());
@ -76,11 +84,13 @@ public class WorldEditCommands {
actor.printDebug("------------------------------------"); actor.printDebug("------------------------------------");
} }
PlatformManager pm = we.getPlatformManager(); PlatformManager pm = we.getPlatformManager();
actor.printDebug("Platforms:");
actor.printDebug("----------- Platforms -----------");
for (Platform platform : pm.getPlatforms()) { for (Platform platform : pm.getPlatforms()) {
actor.printDebug(String.format(" - %s", platform.getPlatformName())); actor.printDebug(String.format("* %s", platform.getPlatformName()));
} }
actor.printDebug("Capabilities:");
actor.printDebug("----------- Capabilities -----------");
for (Capability capability : Capability.values()) { for (Capability capability : Capability.values()) {
Platform platform = pm.queryCapability(capability); Platform platform = pm.queryCapability(capability);
actor.printDebug(String.format(" - %s: %s", capability.name(), platform != null ? platform.getPlatformName() : "NONE")); actor.printDebug(String.format(" - %s: %s", capability.name(), platform != null ? platform.getPlatformName() : "NONE"));
@ -90,11 +100,11 @@ public class WorldEditCommands {
} }
@Command( @Command(
aliases = {"reload"}, aliases = { "reload" },
usage = "", usage = "",
desc = "Reload configuration and translations", desc = "Reload configuration and translations",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.reload") @CommandPermissions("worldedit.reload")
public void reload(Actor actor) throws WorldEditException { public void reload(Actor actor) throws WorldEditException {
@ -102,7 +112,7 @@ public class WorldEditCommands {
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration())); we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
Fawe.get().setupConfigs(); Fawe.get().setupConfigs();
CommandManager.getInstance().register(we.getPlatformManager().queryCapability(Capability.USER_COMMANDS)); CommandManager.getInstance().register(we.getPlatformManager().queryCapability(Capability.USER_COMMANDS));
actor.print(BBC.getPrefix() + "Reloaded FastAsyncWorldEdit configuration and translation files"); actor.print("Configuration and translations reloaded!");
} }
@Command( @Command(
@ -139,11 +149,11 @@ public class WorldEditCommands {
} }
@Command( @Command(
aliases = {"cui"}, aliases = { "cui" },
usage = "", usage = "",
desc = "Complete CUI handshake (internal usage)", desc = "Complete CUI handshake (internal usage)",
min = 0, min = 0,
max = 0 max = 0
) )
public void cui(Player player, LocalSession session) throws WorldEditException { public void cui(Player player, LocalSession session) throws WorldEditException {
session.setCUISupport(true); session.setCUISupport(true);
@ -151,11 +161,11 @@ public class WorldEditCommands {
} }
@Command( @Command(
aliases = {"tz"}, aliases = { "tz" },
usage = "[timezone]", usage = "[timezone]",
desc = "Set your timezone for snapshots", desc = "Set your timezone for snapshots",
min = 1, min = 1,
max = 1 max = 1
) )
public void tz(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void tz(Player player, LocalSession session, CommandContext args) throws WorldEditException {
TimeZone tz = TimeZone.getTimeZone(args.getString(0)); TimeZone tz = TimeZone.getTimeZone(args.getString(0));
@ -165,13 +175,14 @@ public class WorldEditCommands {
} }
@Command( @Command(
aliases = {"help"}, aliases = { "help" },
usage = "[<command>]", usage = "[<command>]",
desc = "Displays help for FAWE commands", desc = "Displays help for FAWE commands",
min = 0, min = 0,
max = -1, max = -1,
queued = false queued = false
) )
@CommandPermissions("worldedit.help")
public void help(Actor actor, CommandContext args) throws WorldEditException { public void help(Actor actor, CommandContext args) throws WorldEditException {
UtilityCommands.help(args, we, actor); UtilityCommands.help(args, we, actor);
} }

View File

@ -42,7 +42,6 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import java.io.File; import java.io.File;
@ -137,7 +136,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
final BlockVector3 pos = BlockVector3.at(x, y, z); final BlockVector3 pos = BlockVector3.at(x, y, z);
final BlockState id = world.getBlock(pos); final BlockState id = world.getBlock(pos);
if (id.getBlockType().getMaterial().isMovementBlocker()) { if (id.getBlockType().getMaterial().isMovementBlocker()) {
setPosition(new Location(world, Vector3.at(x + 0.5, y + + BlockTypeUtil.centralTopLimit(id), z + 0.5))); setPosition(Vector3.at(x + 0.5, y + 1, z + 0.5));
return; return;
} }
@ -158,47 +157,36 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
final int z = pos.getBlockZ(); final int z = pos.getBlockZ();
final Extent world = pos.getExtent(); final Extent world = pos.getExtent();
int maxY = world.getMaxY(); byte free = 0;
if (y >= maxY) return false; byte spots = 0;
BlockMaterial initialMaterial = world.getBlockType(BlockVector3.at(x, y, z)).getMaterial(); while (y <= world.getMaximumPoint().getY() + 2) {
if (!world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
boolean lastState = initialMaterial.isMovementBlocker() && initialMaterial.isFullCube(); ++free;
double height = 1.85;
double freeStart = -1;
for (int level = y + 1; level <= maxY + 2; level++) {
BlockState state;
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
else state = world.getBlock(BlockVector3.at(x, level, z));
BlockType type = state.getBlockType();
BlockMaterial material = type.getMaterial();
if (!material.isFullCube() || !material.isMovementBlocker()) {
if (!lastState) {
lastState = BlockTypeUtil.centralBottomLimit(state) != 1;
continue;
}
if (freeStart == -1) {
freeStart = level + BlockTypeUtil.centralTopLimit(state);
} else {
double bottomLimit = BlockTypeUtil.centralBottomLimit(state);
double space = level + bottomLimit - freeStart;
if (space >= height) {
setPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true;
}
// Not enough room, reset the free position
if (bottomLimit != 1) {
freeStart = -1;
}
}
} else { } else {
freeStart = -1; free = 0;
lastState = true;
} }
if (free == 2) {
++spots;
if (spots == 2) {
final BlockVector3 platform = BlockVector3.at(x, y - 2, z);
final BlockState block = world.getBlock(platform);
final com.sk89q.worldedit.world.block.BlockType type = block.getBlockType();
// Don't get put in lava!
if (type == BlockTypes.LAVA) {
return false;
}
setPosition(platform.toVector3().add(0.5, 1, 0.5));
return true;
}
}
++y;
} }
return false; return false;
} }
@ -206,52 +194,44 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
public boolean descendLevel() { public boolean descendLevel() {
final Location pos = getBlockIn(); final Location pos = getBlockIn();
final int x = pos.getBlockX(); final int x = pos.getBlockX();
int y = Math.max(0, pos.getBlockY()); int y = Math.max(0, pos.getBlockY() - 1);
final int z = pos.getBlockZ(); final int z = pos.getBlockZ();
final Extent world = pos.getExtent(); final Extent world = pos.getExtent();
BlockMaterial initialMaterial = world.getBlockType(BlockVector3.at(x, y, z)).getMaterial(); byte free = 0;
boolean lastState = initialMaterial.isMovementBlocker() && initialMaterial.isFullCube(); while (y >= 1) {
if (!world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
++free;
} else {
free = 0;
}
double height = 1.85; if (free == 2) {
double freeEnd = -1; // So we've found a spot, but we have to drop the player
// lightly and also check to see if there's something to
// stand upon
while (y >= 0) {
final BlockVector3 platform = BlockVector3.at(x, y, z);
final BlockState block = world.getBlock(platform);
final BlockType type = block.getBlockType();
int maxY = world.getMaxY(); // Don't want to end up in lava
if (y <= 2) return false; if (!type.getMaterial().isAir() && type != BlockTypes.LAVA) {
// Found a block!
for (int level = y + 1; level > 0; level--) { setPosition(platform.toVector3().add(0.5, 1, 0.5));
BlockState state;
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
else state = world.getBlock(BlockVector3.at(x, level, z));
BlockType type = state.getBlockType();
BlockMaterial material = type.getMaterial();
if (!material.isFullCube() || !material.isMovementBlocker()) {
if (!lastState) {
lastState = BlockTypeUtil.centralTopLimit(state) != 0;
continue;
}
if (freeEnd == -1) {
freeEnd = level + BlockTypeUtil.centralBottomLimit(state);
} else {
double topLimit = BlockTypeUtil.centralTopLimit(state);
double freeStart = level + topLimit;
double space = freeEnd - freeStart;
if (space >= height) {
setPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true; return true;
} }
// Not enough room, reset the free position
if (topLimit != 0) { --y;
freeEnd = -1;
}
} }
} else {
lastState = true; return false;
freeEnd = -1;
} }
--y;
} }
return false; return false;
} }
@ -326,7 +306,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) { if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) {
getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState()); getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState());
} }
}catch (WorldEditException e) { } catch (WorldEditException e) {
e.printStackTrace(); e.printStackTrace();
} }
setPosition(Vector3.at(x + 0.5, y, z + 0.5)); setPosition(Vector3.at(x + 0.5, y, z + 0.5));
@ -334,12 +314,12 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
@Override @Override
public Location getBlockIn() { public Location getBlockIn() {
return getLocation().setPosition(getLocation().floor()); return getLocation().setPosition(getLocation().toVector().floor());
} }
@Override @Override
public Location getBlockOn() { public Location getBlockOn() {
return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).floor()); return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).toVector().floor());
} }
@Override @Override
@ -393,7 +373,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
if (typeId.hasBlockType()) { if (typeId.hasBlockType()) {
return typeId.getBlockType().getDefaultState().toBaseBlock(); return typeId.getBlockType().getDefaultState().toBaseBlock();
} else { } else {
return BlockTypes.AIR.getDefaultState().toBaseBlock(); throw new NotABlockException();
} }
} }
@ -414,7 +394,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
boolean inFree = false; boolean inFree = false;
while ((block = hitBlox.getNextBlock()) != null) { while ((block = hitBlox.getNextBlock()) != null) {
boolean free = !world.getBlock(block.toBlockPoint()).getBlockType().getMaterial().isMovementBlocker(); boolean free = !world.getBlock(block.toVector().toBlockPoint()).getBlockType().getMaterial().isMovementBlocker();
if (firstBlock) { if (firstBlock) {
firstBlock = false; firstBlock = false;

View File

@ -57,6 +57,7 @@ import java.util.EnumMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -139,9 +140,9 @@ public class PlatformManager {
// Check whether this platform was chosen to be the preferred one // Check whether this platform was chosen to be the preferred one
// for any capability and be sure to remove it // for any capability and be sure to remove it
Iterator<Map.Entry<Capability, Platform>> it = preferences.entrySet().iterator(); Iterator<Entry<Capability, Platform>> it = preferences.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<Capability, Platform> entry = it.next(); Entry<Capability, Platform> entry = it.next();
if (entry.getValue().equals(platform)) { if (entry.getValue().equals(platform)) {
entry.getKey().unload(this, entry.getValue()); entry.getKey().unload(this, entry.getValue());
it.remove(); it.remove();
@ -347,6 +348,7 @@ public class PlatformManager {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (session.hasSuperPickAxe() && player.isHoldingPickAxe()) { if (session.hasSuperPickAxe() && player.isHoldingPickAxe()) {
final BlockTool superPickaxe = session.getSuperPickaxe(); final BlockTool superPickaxe = session.getSuperPickaxe();
if (superPickaxe != null && superPickaxe.canUse(player)) { if (superPickaxe != null && superPickaxe.canUse(player)) {
@ -357,8 +359,8 @@ public class PlatformManager {
return; return;
} }
} }
final Tool tool = session.getTool(player); Tool tool = session.getTool(player);
if (tool != null && tool instanceof DoubleActionBlockTool) { if (tool instanceof DoubleActionBlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
final Player maskedPlayerWrapper = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation()); final Player maskedPlayerWrapper = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
@ -372,6 +374,7 @@ public class PlatformManager {
return; return;
} }
} }
} else if (event.getType() == Interaction.OPEN) { } else if (event.getType() == Interaction.OPEN) {
if (session.isToolControlEnabled() && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) { if (session.isToolControlEnabled() && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
if (!actor.hasPermission("worldedit.selection.pos")) { if (!actor.hasPermission("worldedit.selection.pos")) {
@ -392,12 +395,13 @@ public class PlatformManager {
} }
}, false, true); }, false, true);
} }
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
final Tool tool = session.getTool(player); Tool tool = session.getTool(player);
if (tool != null && tool instanceof BlockTool) { if (tool instanceof BlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
if (fp.checkAction()) { if (fp.checkAction()) {
@ -439,8 +443,8 @@ public class PlatformManager {
// Create a proxy actor with a potentially different world for // Create a proxy actor with a potentially different world for
// making changes to the world // making changes to the world
Player actor = createProxyActor(event.getPlayer()); Player actor = createProxyActor(event.getPlayer());
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap(actor), actor.getLocation(), true); Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap(actor), actor.getLocation(), true);
final LocalSession session = worldEdit.getSessionManager().get(player); LocalSession session = worldEdit.getSessionManager().get(player);
VirtualWorld virtual = session.getVirtualWorld(); VirtualWorld virtual = session.getVirtualWorld();
if (virtual != null) { if (virtual != null) {
@ -451,7 +455,7 @@ public class PlatformManager {
try { try {
switch (event.getInputType()) { switch (event.getInputType()) {
case PRIMARY: { case PRIMARY: {
if (getConfiguration().navigationWandMaxDistance > 0 && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().navigationWand)) { if ((getConfiguration().navigationWandMaxDistance > 0) && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().navigationWand)) {
if (!player.hasPermission("worldedit.navigation.jumpto.tool")) { if (!player.hasPermission("worldedit.navigation.jumpto.tool")) {
return; return;
} }
@ -476,6 +480,7 @@ public class PlatformManager {
return; return;
} }
} }
break; break;
} }
@ -521,5 +526,4 @@ public class PlatformManager {
} }
} }

View File

@ -19,12 +19,9 @@
package com.sk89q.worldedit.extension.platform; package com.sk89q.worldedit.extension.platform;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
@ -36,13 +33,13 @@ import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameMode;
import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull; import javax.annotation.Nullable;
public class PlayerProxy extends AbstractPlayerActor { public class PlayerProxy extends AbstractPlayerActor {
@ -50,7 +47,6 @@ public class PlayerProxy extends AbstractPlayerActor {
private final Actor permActor; private final Actor permActor;
private final Actor cuiActor; private final Actor cuiActor;
private final World world; private final World world;
private Vector3 offset = Vector3.ZERO;
public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) { public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) {
checkNotNull(basePlayer); checkNotNull(basePlayer);
@ -63,10 +59,6 @@ public class PlayerProxy extends AbstractPlayerActor {
this.world = world; this.world = world;
} }
public void setOffset(Vector3 position) {
this.offset = position;
}
@Override @Override
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException { public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
@ -105,13 +97,12 @@ public class PlayerProxy extends AbstractPlayerActor {
@Override @Override
public BaseEntity getState() { public BaseEntity getState() {
throw new UnsupportedOperationException("Can't withPropertyId() on a player"); throw new UnsupportedOperationException("Can't getState() on a player");
} }
@Override @Override
public Location getLocation() { public Location getLocation() {
Location loc = this.basePlayer.getLocation(); return basePlayer.getLocation();
return new Location(loc.getExtent(), loc.add(offset), loc.getDirection());
} }
@Override @Override
@ -194,4 +185,3 @@ public class PlayerProxy extends AbstractPlayerActor {
return basePlayer; return basePlayer;
} }
} }

View File

@ -27,7 +27,6 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
@ -152,7 +151,6 @@ public class ServerCUIHandler {
structureTag.put("showboundingbox", new ByteTag((byte) 1)); structureTag.put("showboundingbox", new ByteTag((byte) 1));
structureTag.put("id", new StringTag(BlockTypes.STRUCTURE_BLOCK.getId())); structureTag.put("id", new StringTag(BlockTypes.STRUCTURE_BLOCK.getId()));
// return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(new CompoundTag(structureTag));
return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(new CompoundTag(structureTag)); return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(new CompoundTag(structureTag));
} }
} }

View File

@ -98,5 +98,4 @@ public class SphereRegionSelector extends EllipsoidRegionSelector {
return "sphere"; return "sphere";
} }
} }