various minor

CFI works without PlotSquared
tab completion
biome tweaks
WIP on anvil
document disallowed-blocks in legacy config
This commit is contained in:
Jesse Boyd 2019-04-11 21:32:32 +10:00
parent 24590199c8
commit 6996a97027
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
18 changed files with 327 additions and 203 deletions

View File

@ -3,10 +3,12 @@ package com.boydti.fawe.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.IFawe;
import com.boydti.fawe.bukkit.chat.BukkitChatManager;
import com.boydti.fawe.bukkit.listener.AsyncTabCompleteListener;
import com.boydti.fawe.bukkit.listener.BrushListener;
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
import com.boydti.fawe.bukkit.listener.CFIPacketListener;
import com.boydti.fawe.bukkit.listener.RenderListener;
import com.boydti.fawe.bukkit.listener.SyncTabCompleteListener;
import com.boydti.fawe.bukkit.regions.ASkyBlockHook;
import com.boydti.fawe.bukkit.regions.FactionsFeature;
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
@ -40,6 +42,7 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.cui.CUI;
import com.boydti.fawe.util.image.ImageViewer;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.world.World;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
@ -127,13 +130,13 @@ public class FaweBukkit implements IFawe, Listener {
new ChunkListener_9();
}
/*try {
try {
Class.forName("com.destroystokyo.paper.event.server.AsyncTabCompleteEvent");
new AsyncTabCompleteListener(WorldEditPlugin.getInstance());
} catch (Throwable ignore)
{
Bukkit.getPluginManager().registerEvents(new AsyncTabCompleteListener(WorldEditPlugin.getInstance()), plugin);
} catch (Throwable ignore) {
ignore.printStackTrace();
Bukkit.getPluginManager().registerEvents(new SyncTabCompleteListener(WorldEditPlugin.getInstance()), plugin);
}*/
}
});
}

View File

@ -32,7 +32,7 @@ public class ATabCompleteListener implements Listener {
CommandSuggestionEvent event = new CommandSuggestionEvent(worldEdit.wrapCommandSender(sender), buffer.substring(index, buffer.length()));
worldEdit.getWorldEdit().getEventBus().post(event);
List<String> suggestions = event.getSuggestions();
if (suggestions != null) {
if (suggestions != null && !suggestions.isEmpty()) {
return suggestions;
}
}

View File

@ -14,14 +14,13 @@ import java.util.List;
public class AsyncTabCompleteListener extends ATabCompleteListener {
public AsyncTabCompleteListener(WorldEditPlugin worldEdit) {
super(worldEdit);
Bukkit.getPluginManager().registerEvents(this, worldEdit);
}
@EventHandler
public void onTabComplete(AsyncTabCompleteEvent event) {
if (event.isCommand()) {
List<String> result = this.onTab(event.getBuffer(), event.getSender());
if (result != null) {
if (result != null && !result.isEmpty()) {
event.setCompletions(result);
event.setHandled(true);
}

View File

@ -18,6 +18,7 @@
limits:
max-blocks-changed:
# Ignored, use FAWE config limits
default: -1
maximum: -1
max-polygonal-points:
@ -29,6 +30,8 @@ limits:
butcher-radius:
default: -1
maximum: -1
# Use either block ids, names, or regex
# Regex supports properties as well (see FAWE mask documentation)
disallowed-blocks: []
use-inventory:

View File

@ -1,43 +1,40 @@
package com.boydti.fawe.command;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Commands;
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
import com.boydti.fawe.object.pattern.PatternExtent;
import com.boydti.fawe.util.*;
import com.boydti.fawe.util.CleanTextureUtil;
import com.boydti.fawe.util.FilteredTextureUtil;
import com.boydti.fawe.util.ImgurUtility;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.TextureUtil;
import com.boydti.fawe.util.chat.Message;
import com.boydti.fawe.util.image.ImageUtil;
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.commands.Auto;
import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotArea;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.MethodCommands;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -47,6 +44,7 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
@ -56,6 +54,8 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayOutputStream;
@ -68,8 +68,11 @@ import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.imageio.ImageIO;
import java.util.function.Consumer;
import java.util.function.Function;
import static com.boydti.fawe.util.image.ImageUtil.load;
@Command(aliases = {"/cfi"}, desc = "Create a world from images: [More Info](https://git.io/v5iDy)")
@ -87,8 +90,11 @@ public class CFICommands extends MethodCommands {
this.dispathcer= dispatcher;
}
private File getFolder(String worldName) {
return new File(PlotSquared.imp().getWorldContainer(), worldName + File.separator + "region");
public static File getFolder(String worldName) {
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING);
List<? extends World> worlds = platform.getWorlds();
FaweQueue queue = SetQueue.IMP.getNewQueue(worlds.get(0), true, false);
return new File(queue.getSaveFolder().getParentFile().getParentFile(), worldName + File.separator + "region");
}
@Command(
@ -174,23 +180,6 @@ public class CFICommands extends MethodCommands {
fp.sendMessage(BBC.getPrefix() + "Cancelled!");
}
@Deprecated
public static void autoClaimFromDatabase(PlotPlayer player, PlotArea area, PlotId start, com.github.intellectualsites.plotsquared.plot.object.RunnableVal<Plot> whenDone) {
final Plot plot = area.getNextFreePlot(player, start);
if (plot == null) {
whenDone.run(null);
return;
}
whenDone.value = plot;
plot.owner = player.getUUID();
DBFunc.createPlotSafe(plot, whenDone, new Runnable() {
@Override
public void run() {
autoClaimFromDatabase(player, area, plot.getId(), whenDone);
}
});
}
@Command(
aliases = {"done", "create"},
usage = "",
@ -199,59 +188,54 @@ public class CFICommands extends MethodCommands {
@CommandPermissions("worldedit.anvil.cfi")
public void done(FawePlayer fp) throws ParameterException, IOException {
CFISettings settings = assertSettings(fp);
HeightMapMCAGenerator generator = settings.getGenerator();
PlotAreaManager manager = PlotSquared.get().getPlotAreaManager();
if (manager instanceof SinglePlotAreaManager) {
SinglePlotAreaManager sManager = (SinglePlotAreaManager) manager;
SinglePlotArea area = sManager.getArea();
PlotPlayer player = PlotPlayer.wrap(fp.parent);
fp.sendMessage(BBC.getPrefix() + "Claiming world");
Plot plot = TaskManager.IMP.sync(new RunnableVal<Plot>() {
@Override
public void run(Plot o) {
int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(area.worldname);
int diff = player.getAllowedPlots() - currentPlots;
if (diff < 1) {
Captions.CANT_CLAIM_MORE_PLOTS_NUM.send(player, -diff);
return;
Function<File, Boolean> function = new Function<File, Boolean>() {
@Override
public Boolean apply(File folder) {
if (folder != null) {
try {
generator.setFolder(folder);
fp.sendMessage(BBC.getPrefix() + "Generating " + folder);
generator.generate();
generator.setPacketViewer(null);
generator.setImageViewer(null);
settings.remove();
fp.sendMessage(BBC.getPrefix() + "Done!");
return true;
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
fp.sendMessage("Unable to generate world... (see console)?");
}
return false;
}
};
if (area.getMeta("lastPlot") == null) {
area.setMeta("lastPlot", new PlotId(0, 0));
}
PlotId lastId = (PlotId) area.getMeta("lastPlot");
while (true) {
lastId = Auto.getNextPlotId(lastId, 1);
if (area.canClaim(player, lastId, lastId)) {
break;
try {
new PlotLoader().load(fp, settings, function);
} catch (Throwable ignore) {
ignore.printStackTrace();
function.apply(generator.getFolder().getParentFile());
}
File folder = generator.getFolder();
if (folder != null) {
World world = FaweAPI.getWorld(folder.getName());
if (world != null) {
if (fp.getWorld() != world) {
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
Location spawn = new Location(world, world.getSpawnPosition().toVector3());
fp.getPlayer().setPosition(spawn);
}
}
area.setMeta("lastPlot", lastId);
this.value = area.getPlot(lastId);
this.value.setOwner(player.getUUID());
});
}
});
if (plot == null) return;
File folder = getFolder(plot.getWorldName());
HeightMapMCAGenerator generator = settings.getGenerator();
generator.setFolder(folder);
fp.sendMessage(BBC.getPrefix() + "Generating");
generator.generate();
generator.setPacketViewer(null);
generator.setImageViewer(null);
settings.remove();
fp.sendMessage(BBC.getPrefix() + "Done!");
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
plot.teleportPlayer(player);
}
});
} else {
fp.sendMessage(BBC.getPrefix() + "Must have the `worlds` component enabled in the PlotSquared config.yml");
} else {
fp.sendMessage("Unable to import world (" + folder.getName() + ") please do so manually");
}
}
}

View File

@ -0,0 +1,96 @@
package com.boydti.fawe.command;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.commands.Auto;
import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotArea;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
import com.sk89q.worldedit.function.pattern.FawePattern;
import com.sk89q.worldedit.util.Location;
import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
import java.util.function.Function;
public class PlotLoader {
@Deprecated
public static void autoClaimFromDatabase(PlotPlayer player, PlotArea area, PlotId start, com.github.intellectualsites.plotsquared.plot.object.RunnableVal<Plot> whenDone) {
final Plot plot = area.getNextFreePlot(player, start);
if (plot == null) {
whenDone.run(null);
return;
}
whenDone.value = plot;
plot.owner = player.getUUID();
DBFunc.createPlotSafe(plot, whenDone, new Runnable() {
@Override
public void run() {
autoClaimFromDatabase(player, area, plot.getId(), whenDone);
}
});
}
public void load(FawePlayer fp, CFICommands.CFISettings settings, Function<File, Boolean> createTask) throws IOException {
PlotAreaManager manager = PlotSquared.get().getPlotAreaManager();
if (manager instanceof SinglePlotAreaManager) {
SinglePlotAreaManager sManager = (SinglePlotAreaManager) manager;
SinglePlotArea area = sManager.getArea();
PlotPlayer player = PlotPlayer.wrap(fp.parent);
fp.sendMessage(BBC.getPrefix() + "Claiming world");
Plot plot = TaskManager.IMP.sync(new RunnableVal<Plot>() {
@Override
public void run(Plot o) {
int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(area.worldname);
int diff = player.getAllowedPlots() - currentPlots;
if (diff < 1) {
Captions.CANT_CLAIM_MORE_PLOTS_NUM.send(player, -diff);
return;
}
if (area.getMeta("lastPlot") == null) {
area.setMeta("lastPlot", new PlotId(0, 0));
}
PlotId lastId = (PlotId) area.getMeta("lastPlot");
while (true) {
lastId = Auto.getNextPlotId(lastId, 1);
if (area.canClaim(player, lastId, lastId)) {
break;
}
}
area.setMeta("lastPlot", lastId);
this.value = area.getPlot(lastId);
this.value.setOwner(player.getUUID());
}
});
if (plot != null) {
File folder = CFICommands.getFolder(plot.getWorldName());
Boolean result = createTask.apply(folder);
if (result == Boolean.TRUE) {
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
plot.teleportPlayer(player);
}
});
}
return;
}
}
createTask.apply(null);
}
}

View File

@ -12,6 +12,7 @@ import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import java.io.DataOutput;
import java.io.DataOutputStream;
@ -21,17 +22,6 @@ import java.util.function.BiConsumer;
public class MCAChunk extends FaweChunk<Void> {
// ids: byte[16][4096]
// data: byte[16][2048]
// skylight: byte[16][2048]
// blocklight: byte[16][2048]
// entities: Map<Short, CompoundTag>
// tiles: List<CompoundTag>
// biomes: byte[256]
// compressedSize: int
// modified: boolean
// deleted: boolean
public int[][] ids;
public byte[][] skyLight;
public byte[][] blockLight;
@ -88,6 +78,9 @@ public class MCAChunk extends FaweChunk<Void> {
}
public void write(NBTOutputStream nbtOut) throws IOException {
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
nbtOut.writeLazyCompoundTag("Level", out -> {
out.writeNamedTag("V", (byte) 1);
@ -224,7 +217,6 @@ public class MCAChunk extends FaweChunk<Void> {
int startIndexShift = startIndex >> 1;
int endIndexShift = endIndex >> 1;
int otherStartIndexShift = otherStartIndex >> 1;
int otherEndIndexShift = otherEndIndex >> 1;
if ((startIndex & 1) != 0) {
startIndexShift++;
otherStartIndexShift++;
@ -233,7 +225,6 @@ public class MCAChunk extends FaweChunk<Void> {
}
if ((endIndex & 1) != 1) {
endIndexShift--;
otherEndIndexShift--;
setNibble(endIndex, thisSkyLight, getNibble(otherEndIndex, otherSkyLight));
setNibble(endIndex, thisBlockLight, getNibble(otherEndIndex, otherBlockLight));
}
@ -365,7 +356,7 @@ public class MCAChunk extends FaweChunk<Void> {
}
if (!other.entities.isEmpty()) {
for (Map.Entry<UUID, CompoundTag> entry : other.entities.entrySet()) {
// TODO
// TODO FIXME
}
}
}
@ -601,27 +592,27 @@ public class MCAChunk extends FaweChunk<Void> {
@Override
public int getBlockCombinedId(int x, int y, int z) {
// TODO FIXME
return 0;
// int layer = y >> 4;
// byte[] idLayer = ids[layer];
// if (idLayer == null) {
// return 0;
// }
// int j = FaweCache.CACHE_J[y][z & 15][x & 15];
// int id = idLayer[j] & 0xFF;
// if (FaweCache.hasData(id)) {
// byte[] dataLayer = data[layer];
// if (dataLayer != null) {
// return (id << 4) + getNibble(j, dataLayer);
// }
// }
// return id << 4;
int layer = y >> 4;
int[] idLayer = ids[layer];
if (idLayer == null) {
return 0;
}
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
return idLayer[j];
}
@Override
public BiomeType[] getBiomeArray() {
return null;
BiomeType[] arr = new BiomeType[256];
for (int i = 0; i < arr.length; i++) {
arr[i] = BiomeTypes.get(biomes[i]);
}
return arr;
}
@Override
public BiomeType getBiomeType(int x, int z) {
return BiomeTypes.get(biomes[(x & 15) + ((z & 15) << 4)]);
}
@Override
@ -730,20 +721,16 @@ public class MCAChunk extends FaweChunk<Void> {
@Override
public void setBlock(int x, int y, int z, int combinedId) {
// TODO FIXME
// setModified();
// int layer = y >> 4;
// byte[] idsLayer = ids[layer];
// if (idsLayer == null) {
// idsLayer = this.ids[layer] = new byte[4096];
// this.data[layer] = new byte[2048];
// this.skyLight[layer] = new byte[2048];
// this.blockLight[layer] = new byte[2048];
// }
// int j = FaweCache.CACHE_J[y][z & 15][x & 15];
// idsLayer[j] = (byte) id;
// byte[] dataLayer = this.data[layer];
// setNibble(j, dataLayer, data);
setModified();
int layer = y >> 4;
int[] idsLayer = ids[layer];
if (idsLayer == null) {
idsLayer = this.ids[layer] = new int[4096];
this.skyLight[layer] = new byte[2048];
this.blockLight[layer] = new byte[2048];
}
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
idsLayer[j] = combinedId;
}
@Override

View File

@ -88,7 +88,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
@Override
public BiomeType getBiome(FaweChunk faweChunk, int x, int z) {
if (faweChunk instanceof MCAChunk) {
return ((MCAChunk) faweChunk).getBiomeArray()[((z & 0xF) << 4 | x & 0xF)];
return ((MCAChunk) faweChunk).getBiomeType(x, z);
} else if (parent != null) {
return parent.getBiomeType(x, z);
} else {

View File

@ -7,7 +7,6 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockID;
@ -207,7 +206,7 @@ public class WritableMCAChunk extends FaweChunk<Void> {
// cleanup
} catch (Throwable e) {
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
System.out.println("======================== exception e");
e.printStackTrace();
throw e;
}
}

View File

@ -169,6 +169,10 @@ public abstract class FaweChunk<T> implements Callable<FaweChunk> {
public abstract BiomeType[] getBiomeArray();
public BiomeType getBiomeType(int x, int z) {
return getBiomeArray()[(x & 15) + ((z & 15) << 4)];
}
public void forEachQueuedBlock(FaweChunkVisitor onEach) {
for (int y = 0; y < HEIGHT; y++) {
for (int z = 0; z < 16; z++) {

View File

@ -266,9 +266,8 @@ public abstract class FaweChangeSet implements ChangeSet {
int bx = cx << 4;
int bz = cz << 4;
synchronized (FaweChangeSet.this) {
// Biome changes
if (previous.getBiomeArray() != null) {
BiomeType[] previousBiomes = previous.getBiomeArray();
BiomeType[] previousBiomes = previous.getBiomeArray();
if (previousBiomes != null) {
BiomeType[] nextBiomes = next.getBiomeArray();
int index = 0;
for (int z = 0; z < 16; z++) {

View File

@ -107,14 +107,12 @@ public class TransformExtent extends BlockTransformExtent {
@Override
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
System.out.println("Set block transform");
return super.setBlock(getPos(x, y, z), transformInverse(block));
}
@Override
public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
System.out.println("Set block transform2");
return super.setBlock(getPos(location), transformInverse(block));
}

View File

@ -1,5 +1,7 @@
package com.boydti.fawe.util;
import com.sk89q.util.StringUtil;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
@ -12,6 +14,7 @@ import java.util.Set;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.IntFunction;
import java.util.function.Predicate;
public class StringMan {
public static String replaceFromMap(final String string, final Map<String, String> replacements) {
@ -323,6 +326,57 @@ public class StringMan {
return true;
}
public static Comparator<String> blockStateComparator(String input) {
return new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return blockStateStringDistance(input, o1) - blockStateStringDistance(input, o2);
}
};
}
public static boolean blockStateMatches(String input, String item) {
return blockStateStringDistance(input, item) != Integer.MAX_VALUE;
}
public static int blockStateStringDistance(String input, String item) {
int distance = 0;
boolean sequentail = false;
int j = 0;
for (int i = 0; i < input.length(); i++) {
char ai = input.charAt(i);
outer:
while (true) {
if (j >= item.length()) return Integer.MAX_VALUE;
char bj = item.charAt(j++);
if (sequentail) {
switch (bj) {
case ':':
case '_':
sequentail = false;
if (bj == ai) break outer;
continue;
}
continue;
}
if (bj != ai) {
distance++;
switch (bj) {
case ':':
case '_':
continue;
default:
sequentail = true;
continue;
}
}
break;
}
}
return distance;
}
public static int getLevenshteinDistance(String s, String t) {
int n = s.length();
int m = t.length();

View File

@ -286,6 +286,7 @@ public final class CommandManager {
.group("/anvil")
.describeAs("Anvil command")
.registerMethods(new AnvilCommands(worldEdit)).parent()
.registerMethods(new CFICommand(worldEdit, builder))
.registerMethods(new BiomeCommands(worldEdit))
.registerMethods(new ChunkCommands(worldEdit))
.registerMethods(new ClipboardCommands(worldEdit))
@ -318,6 +319,7 @@ public final class CommandManager {
.group("superpickaxe", "pickaxe", "sp").describeAs("Super-pickaxe commands")
.registerMethods(new SuperPickaxeCommands(worldEdit))
.parent().graph().getDispatcher();
if (platform != null) {
platform.registerCommands(dispatcher);
}
@ -336,49 +338,34 @@ public final class CommandManager {
this.platform = platform;
// Delay command registration to allow time for other plugins to hook into FAWE
TaskManager.IMP.task(new Runnable() {
@Override
public void run() {
synchronized (CommandManager.this) {
try {
Class.forName("com.github.intellectualsites.plotsquared.plot.PlotSquared");
CFICommand cfi = new CFICommand(worldEdit, builder);
registerCommands(cfi);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
new CommandScriptLoader().load();
} catch (Throwable e) {
e.printStackTrace();
}
try {
new CommandScriptLoader().load();
} catch (Throwable e) {
e.printStackTrace();
}
LocalConfiguration config = platform.getConfiguration();
boolean logging = config.logCommands;
String path = config.logFile;
LocalConfiguration config = platform.getConfiguration();
boolean logging = config.logCommands;
String path = config.logFile;
// Register log
if (!logging || path.isEmpty()) {
dynamicHandler.setHandler(null);
commandLog.setLevel(Level.OFF);
} else {
File file = new File(config.getWorkingDirectory(), path);
commandLog.setLevel(Level.ALL);
// Register log
if (!logging || path.isEmpty()) {
dynamicHandler.setHandler(null);
commandLog.setLevel(Level.OFF);
} else {
File file = new File(config.getWorkingDirectory(), path);
commandLog.setLevel(Level.ALL);
log.info("Logging WorldEdit commands to " + file.getAbsolutePath());
log.info("Logging WorldEdit commands to " + file.getAbsolutePath());
try {
dynamicHandler.setHandler(new FileHandler(file.getAbsolutePath(), true));
} catch (IOException e) {
log.warn("Could not use command log file " + path + ": " + e.getMessage());
}
}
setupDispatcher();
}
try {
dynamicHandler.setHandler(new FileHandler(file.getAbsolutePath(), true));
} catch (IOException e) {
log.warn("Could not use command log file " + path + ": " + e.getMessage());
}
});
}
setupDispatcher();
}
public void unregister() {

View File

@ -229,7 +229,10 @@ public class BlockMaskBuilder {
throw new SuggestInputParseException(input + " does not have: " + property, input, () -> {
Set<PropertyKey> keys = new HashSet<>();
finalTypes.forEach(t -> t.getProperties().stream().forEach(p -> keys.add(p.getKey())));
return keys.stream().map(p -> p.getId()).filter(p -> p.startsWith(property)).collect(Collectors.toList());
return keys.stream().map(p -> p.getId())
.filter(p -> StringMan.blockStateMatches(property, p))
.sorted(StringMan.blockStateComparator(property))
.collect(Collectors.toList());
});
}

View File

@ -228,20 +228,23 @@ public abstract class AParametricCallable implements CommandCallable {
for (;maxConsumedI < parameters.length; maxConsumedI++) {
parameter = parameters[maxConsumedI];
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
// Parse the user input into a method argument
ArgumentStack usedArguments = getScopedContext(parameter, scoped);
if (mayConsumeArguments(maxConsumedI, scoped)) {
// Parse the user input into a method argument
ArgumentStack usedArguments = getScopedContext(parameter, scoped);
usedArguments.mark();
try {
parameter.getBinding().bind(parameter, usedArguments, false);
minConsumedI = maxConsumedI + 1;
} catch (Throwable e) {
while (e.getCause() != null && !(e instanceof ParameterException || e instanceof InvocationTargetException)) e = e.getCause();
consumed = usedArguments.reset();
// Not optional? Then we can't execute this command
if (!parameter.isOptional()) {
if (!(e instanceof MissingParameterException)) minConsumedI = maxConsumedI;
throw e;
usedArguments.mark();
try {
parameter.getBinding().bind(parameter, usedArguments, false);
minConsumedI = maxConsumedI + 1;
} catch (Throwable e) {
while (e.getCause() != null && !(e instanceof ParameterException || e instanceof InvocationTargetException))
e = e.getCause();
consumed = usedArguments.reset();
// Not optional? Then we can't execute this command
if (!parameter.isOptional()) {
if (!(e instanceof MissingParameterException)) minConsumedI = maxConsumedI;
throw e;
}
}
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.world.block;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.object.string.MutableCharSequence;
import com.boydti.fawe.util.StringMan;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.sk89q.jnbt.CompoundTag;
@ -38,6 +39,7 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -121,8 +123,9 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
if (type == null) {
String input = key.toString();
throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypes.values)
.filter(b -> b.getId().contains(input))
.filter(b -> StringMan.blockStateMatches(input, b.getId()))
.map(e1 -> e1.getId())
.sorted(StringMan.blockStateComparator(input))
.collect(Collectors.toList())
);
}
@ -183,7 +186,8 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
throw new SuggestInputParseException("Invalid property " + charSequence + ":" + input + " for type " + type, input, () ->
finalType.getProperties().stream()
.map(p -> p.getName())
.filter(p -> p.startsWith(input))
.filter(p -> StringMan.blockStateMatches(input, p))
.sorted(StringMan.blockStateComparator(input))
.collect(Collectors.toList()));
} else {
throw new SuggestInputParseException("No operator for " + state, "", () -> Arrays.asList("="));

View File

@ -912,8 +912,9 @@ public final class BlockTypes {
}
throw new SuggestInputParseException("Does not match a valid block type: " + inputLower, inputLower, () -> Stream.of(BlockTypes.values)
.filter(b -> b.getId().contains(inputLower))
.filter(b -> StringMan.blockStateMatches(inputLower, b.getId()))
.map(e1 -> e1.getId())
.sorted(StringMan.blockStateComparator(inputLower))
.collect(Collectors.toList())
);
}