Various minor

Functioning nukkit gui for most commands
Fixes #876
This commit is contained in:
Jesse Boyd 2018-01-24 19:57:08 +11:00
parent ea63c77d7e
commit ad60b90987
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
24 changed files with 735 additions and 394 deletions

View File

@ -7,16 +7,7 @@ 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.regions.ASkyBlockHook;
import com.boydti.fawe.bukkit.regions.FactionsFeature;
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
import com.boydti.fawe.bukkit.regions.FactionsUUIDFeature;
import com.boydti.fawe.bukkit.regions.GriefPreventionFeature;
import com.boydti.fawe.bukkit.regions.PlotMeFeature;
import com.boydti.fawe.bukkit.regions.PreciousStonesFeature;
import com.boydti.fawe.bukkit.regions.ResidenceFeature;
import com.boydti.fawe.bukkit.regions.TownyFeature;
import com.boydti.fawe.bukkit.regions.Worldguard;
import com.boydti.fawe.bukkit.regions.*;
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
import com.boydti.fawe.bukkit.util.BukkitTaskMan;
import com.boydti.fawe.bukkit.util.ItemUtil;
@ -41,10 +32,7 @@ import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.util.Jars;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.*;
import com.boydti.fawe.util.cui.CUI;
import com.boydti.fawe.util.image.ImageViewer;
import com.boydti.fawe.util.metrics.BStats;

View File

@ -31,14 +31,11 @@ import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.block.CauldronLevelChangeEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.NotePlayEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.inventory.BrewEvent;
import org.bukkit.event.inventory.BrewingStandFuelEvent;
import org.bukkit.event.inventory.FurnaceBurnEvent;
import org.bukkit.event.inventory.FurnaceSmeltEvent;
import org.bukkit.event.world.ChunkLoadEvent;
@ -156,14 +153,14 @@ public abstract class ChunkListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void event(BlockPlaceEvent event) { reset(); }
@EventHandler(priority = EventPriority.LOWEST)
public void event(BrewEvent event) { reset(); }
@EventHandler(priority = EventPriority.LOWEST)
public void event(BrewingStandFuelEvent event) { reset(); }
@EventHandler(priority = EventPriority.LOWEST)
public void event(CauldronLevelChangeEvent event) { reset(); }
// @EventHandler(priority = EventPriority.LOWEST)
// public void event(BrewEvent event) { reset(); }
//
// @EventHandler(priority = EventPriority.LOWEST)
// public void event(BrewingStandFuelEvent event) { reset(); }
//
// @EventHandler(priority = EventPriority.LOWEST)
// public void event(CauldronLevelChangeEvent event) { reset(); }
@EventHandler(priority = EventPriority.LOWEST)
public void event(FurnaceBurnEvent event) { reset(); }

View File

@ -302,7 +302,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
}
// Set entities
Set<CompoundTag> entitiesToSpawn = this.getEntities();
Set<UUID> createdEntities = new HashSet<>();
// Set<UUID> createdEntities = new HashSet<>();
if (!entitiesToSpawn.isEmpty()) {
synchronized (BukkitQueue_0.class) {
for (CompoundTag nativeTag : entitiesToSpawn) {
@ -347,7 +347,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
synchronized (BukkitQueue_0.class) {
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
}
createdEntities.add(entity.getUniqueID());
// createdEntities.add(entity.getUniqueID());
}
}
}

View File

@ -734,7 +734,10 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
if (section != null) {
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
if (sky) {
Arrays.fill(section.getSkyLightArray().asBytes(), (byte) 0);
byte[] light = section.getSkyLightArray().asBytes();
if (light != null) {
Arrays.fill(light, (byte) 0);
}
}
return true;
}

View File

@ -18,6 +18,9 @@ permissions:
default: true
fawe.bypass:
default: false
children:
fawe.bypass.regions: true
fawe.limit.*: true
fawe.tips:
default: false
fawe.admin:

View File

@ -257,7 +257,8 @@ public enum BBC {
WORLDEDIT_CANCEL_REASON_MAX_TILES("Too many blockstates", "Cancel"),
WORLDEDIT_CANCEL_REASON_MAX_ENTITIES("Too many entities", "Cancel"),
WORLDEDIT_CANCEL_REASON_MAX_ITERATIONS("Max iterations", "Cancel"),
WORLDEDIT_CANCEL_REASON_MAX_FAILS("Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
WORLDEDIT_CANCEL_REASON_OUTSIDE_WORLD("Cancel", "Outside world"),
WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION("Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
WORLDEDIT_CANCEL_REASON_NO_REGION("No allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
WORLDEDIT_FAILED_LOAD_CHUNK("&cSkipped loading chunk: &7%s0;%s1&c. Try increasing chunk-wait.", "Cancel"),

View File

@ -408,7 +408,7 @@ public class Settings extends Config {
public FaweLimit getLimit(FawePlayer player) {
FaweLimit limit;
if (player.hasWorldEditBypass()) {
if (player.hasPermission("fawe.limit.*") || player.hasPermission("fawe.bypass")) {
limit = FaweLimit.MAX.copy();
} else {
limit = new FaweLimit();

View File

@ -191,7 +191,7 @@ public abstract class FawePlayer<T> extends Metadatable {
if (allowed.length == 0) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_NO_REGION);
} else if (!WEManager.IMP.regionContains(wrappedSelection, allowedSet)) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
}

View File

@ -57,7 +57,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
if (!contains(location)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return false;
}
@ -68,7 +68,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return false;
}
@ -79,7 +79,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public boolean setBiome(Vector2D position, BaseBiome biome) {
if (!contains(position)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return false;
}
@ -90,7 +90,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public BaseBiome getBiome(Vector2D position) {
if (!contains(position)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return EditSession.nullBiome;
}
@ -101,7 +101,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public BaseBlock getBlock(Vector position) {
if (!contains(position)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return EditSession.nullBlock;
}
@ -112,7 +112,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public BaseBlock getLazyBlock(Vector position) {
if (!contains(position)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return EditSession.nullBlock;
}
@ -123,7 +123,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public BaseBlock getLazyBlock(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return EditSession.nullBlock;
}
@ -134,7 +134,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public int getBlockLight(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return 0;
}
@ -145,7 +145,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public int getBrightness(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return 0;
}
@ -156,7 +156,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public int getLight(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return 0;
}
@ -167,7 +167,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public int getOpacity(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return 0;
}
@ -178,7 +178,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public int getSkyLight(int x, int y, int z) {
if (!contains(x, y, z)) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return 0;
}
@ -190,7 +190,7 @@ public abstract class FaweRegionExtent extends ResettableExtent {
public Entity createEntity(Location location, BaseEntity entity) {
if (!contains(location.getBlockX(), location.getBlockY(), location.getBlockZ())) {
if (!limit.MAX_FAILS()) {
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
return null;
}

View File

@ -121,6 +121,7 @@ public class PlotSquaredFeature extends FaweMaskManager {
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) {
return null;
}
return new FaweMask(pos1, pos2) {
@Override
public String getName() {

View File

@ -88,7 +88,7 @@ public class WEManager {
* @return
*/
public RegionWrapper[] getMask(final FawePlayer<?> player, FaweMaskManager.MaskType type) {
if (player.hasPermission("fawe.bypass") || !Settings.IMP.REGION_RESTRICTIONS) {
if (!Settings.IMP.REGION_RESTRICTIONS || player.hasPermission("fawe.bypass") || player.hasPermission("fawe.bypass.regions")) {
return new RegionWrapper[]{RegionWrapper.GLOBAL()};
}
FaweLocation loc = player.getLocation();

View File

@ -69,7 +69,7 @@ public class UsageMessage extends Message {
}
}
public String separateArg(String arg) {
protected String separateArg(String arg) {
return " " + arg;
}

View File

@ -2,7 +2,7 @@ package com.boydti.fawe.util.gui;
import com.boydti.fawe.object.FawePlayer;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.Nullable;
@ -25,5 +25,7 @@ public interface FormBuilder<T> {
FormBuilder addToggle(String text, boolean def);
void display(FawePlayer<T> fp, Consumer<List<String>> response);
FormBuilder setResponder(Consumer<Map<Integer, Object>> handler);
void display(FawePlayer<T> fp);
}

View File

@ -0,0 +1,11 @@
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Step {
Class clazz() default Link.class;
double value() default 1;
}

View File

@ -0,0 +1,25 @@
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface SuggestedRange {
Class clazz() default Link.class;
String value();
/**
* The minimum value that the number can be at, inclusive.
*
* @return the minimum value
*/
double min() default Double.MIN_VALUE;
/**
* The maximum value that the number can be at, inclusive.
*
* @return the maximum value
*/
double max() default Double.MAX_VALUE;
}

View File

@ -344,7 +344,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
if (allowedRegions == null) {
if (player != null && !player.hasWorldEditBypass() && !(queue instanceof HeightMapMCAGenerator)) {
if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions") && !(queue instanceof HeightMapMCAGenerator)) {
allowedRegions = player.getCurrentRegions();
}
}
@ -1376,8 +1376,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (used.MAX_FAILS > 0) {
if (used.MAX_CHANGES > 0 || used.MAX_ENTITIES > 0) {
BBC.WORLDEDIT_SOME_FAILS.send(player, used.MAX_FAILS);
} else if (new ExtentTraverser(this).findAndGet(FaweRegionExtent.class) != null){
BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION.send(player);
} else {
BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS.send(player);
BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_WORLD.send(player);
}
}
// Reset limit
@ -3452,7 +3454,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
Vector max = region.getMaximumPoint();
Vector min = region.getMinimumPoint();
if (!fe.contains(max.getBlockX(), max.getBlockY(), max.getBlockZ()) && !fe.contains(min.getBlockX(), min.getBlockY(), min.getBlockZ())) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS);
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION);
}
}
final Set<Vector2D> chunks = region.getChunks();

View File

@ -25,59 +25,19 @@ import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.brush.BlendBall;
import com.boydti.fawe.object.brush.BlobBrush;
import com.boydti.fawe.object.brush.BrushSettings;
import com.boydti.fawe.object.brush.CatenaryBrush;
import com.boydti.fawe.object.brush.CircleBrush;
import com.boydti.fawe.object.brush.CommandBrush;
import com.boydti.fawe.object.brush.CopyPastaBrush;
import com.boydti.fawe.object.brush.ErodeBrush;
import com.boydti.fawe.object.brush.FlattenBrush;
import com.boydti.fawe.object.brush.HeightBrush;
import com.boydti.fawe.object.brush.LayerBrush;
import com.boydti.fawe.object.brush.LineBrush;
import com.boydti.fawe.object.brush.PopulateSchem;
import com.boydti.fawe.object.brush.RaiseBrush;
import com.boydti.fawe.object.brush.RecurseBrush;
import com.boydti.fawe.object.brush.ScatterBrush;
import com.boydti.fawe.object.brush.ScatterCommand;
import com.boydti.fawe.object.brush.ScatterOverlayBrush;
import com.boydti.fawe.object.brush.ShatterBrush;
import com.boydti.fawe.object.brush.SplatterBrush;
import com.boydti.fawe.object.brush.SplineBrush;
import com.boydti.fawe.object.brush.StencilBrush;
import com.boydti.fawe.object.brush.SurfaceSphereBrush;
import com.boydti.fawe.object.brush.SurfaceSpline;
import com.boydti.fawe.object.brush.*;
import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
import com.boydti.fawe.object.brush.sweep.SweepBrush;
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
import com.boydti.fawe.object.mask.IdMask;
import com.boydti.fawe.util.ColorUtil;
import com.boydti.fawe.util.MathMan;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.command.tool.brush.ButcherBrush;
import com.sk89q.worldedit.command.tool.brush.ClipboardBrush;
import com.sk89q.worldedit.command.tool.brush.CylinderBrush;
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
import com.sk89q.worldedit.command.tool.brush.HollowCylinderBrush;
import com.sk89q.worldedit.command.tool.brush.HollowSphereBrush;
import com.sk89q.worldedit.command.tool.brush.SmoothBrush;
import com.sk89q.worldedit.command.tool.brush.SphereBrush;
import com.sk89q.worldedit.command.tool.brush.*;
import com.sk89q.worldedit.command.util.CreatureButcher;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -93,11 +53,7 @@ import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
@ -337,7 +293,7 @@ public class BrushCommands extends MethodCommands {
max = 2
)
@CommandPermissions("worldedit.brush.sphere")
public BrushSettings sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException {
public BrushSettings sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") @Range(min=0) double radius, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
Brush brush;
@ -393,12 +349,12 @@ public class BrushCommands extends MethodCommands {
max = -1
)
@CommandPermissions("worldedit.brush.stencil")
public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException {
public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
InputStream stream = getHeightmapStream(filename);
InputStream stream = getHeightmapStream(image);
HeightBrush brush;
try {
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, image.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
} catch (EmptyClipboardException ignore) {
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null);
}
@ -705,8 +661,8 @@ public class BrushCommands extends MethodCommands {
max = 4
)
@CommandPermissions("worldedit.brush.height")
public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, filename, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
}
@Command(
@ -723,8 +679,8 @@ public class BrushCommands extends MethodCommands {
max = 4
)
@CommandPermissions("worldedit.brush.height")
public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context);
public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context);
}
@Command(
@ -740,8 +696,8 @@ public class BrushCommands extends MethodCommands {
max = 4
)
@CommandPermissions("worldedit.brush.height")
public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
}
private InputStream getHeightmapStream(String filename) {
@ -775,19 +731,19 @@ public class BrushCommands extends MethodCommands {
return null;
}
private BrushSettings terrainBrush(Player player, LocalSession session, double radius, String filename, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException {
private BrushSettings terrainBrush(Player player, LocalSession session, double radius, String image, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
InputStream stream = getHeightmapStream(filename);
InputStream stream = getHeightmapStream(image);
HeightBrush brush;
if (flat) {
try {
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape);
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth, image.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape);
} catch (EmptyClipboardException ignore) {
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth, null, shape);
}
} else {
try {
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, image.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
} catch (EmptyClipboardException ignore) {
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, null);
}

View File

@ -0,0 +1,244 @@
package com.sk89q.worldedit.command;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.util.StringMan;
import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.DelegateCallable;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public abstract class HelpBuilder implements Runnable {
private final CommandCallable callable;
private final CommandContext args;
private final String prefix;
private final int perPage;
public HelpBuilder(CommandCallable callable, CommandContext args, final String prefix, int perPage) {
if (callable == null) {
callable = WorldEdit.getInstance().getPlatformManager().getCommandManager().getDispatcher();
}
this.callable = callable;
this.args = args;
this.prefix = prefix;
this.perPage = perPage;
}
@Override
public void run() {
try {
CommandCallable callable = this.callable;
int page = -1;
String category = null;
int effectiveLength = args.argsLength();
// Detect page from args
try {
if (effectiveLength > 0) {
page = args.getInteger(args.argsLength() - 1);
if (page <= 0) {
page = 1;
} else {
page--;
}
effectiveLength--;
}
} catch (NumberFormatException ignored) {
}
boolean isRootLevel = true;
List<String> visited = new ArrayList<String>();
// Create the message
if (callable instanceof Dispatcher) {
Dispatcher dispatcher = (Dispatcher) callable;
// Get a list of aliases
List<CommandMapping> aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
List<String> prefixes = Collections.nCopies(aliases.size(), "");
// Group by callable
if (page == -1 || effectiveLength > 0) {
Map<String, Map<CommandMapping, String>> grouped = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (CommandMapping mapping : aliases) {
CommandCallable c = mapping.getCallable();
String group;
if (c instanceof DelegateCallable) {
c = ((DelegateCallable) c).getParent();
}
if (c instanceof ParametricCallable) {
Object obj = ((ParametricCallable) c).getObject();
Command command = obj.getClass().getAnnotation(Command.class);
if (command != null && command.aliases().length != 0) {
group = command.aliases()[0];
} else {
group = obj.getClass().getSimpleName().replaceAll("Commands", "").replaceAll("Util$", "");
}
} else if (c instanceof Dispatcher) {
group = mapping.getPrimaryAlias();
} else {
group = "Unsorted";
}
group = group.replace("/", "");
group = StringMan.toProperCase(group);
Map<CommandMapping, String> queue = grouped.get(group);
if (queue == null) {
queue = new LinkedHashMap<>();
grouped.put(group, queue);
}
if (c instanceof Dispatcher) {
for (CommandMapping m : ((Dispatcher) c).getCommands()) {
queue.put(m, mapping.getPrimaryAlias() + " ");
}
} else {
// Sub commands get priority
queue.putIfAbsent(mapping, "");
}
}
if (effectiveLength > 0) {
String cat = args.getString(0);
Map<CommandMapping, String> mappings = effectiveLength == 1 ? grouped.get(cat) : null;
if (mappings == null) {
// Drill down to the command
for (int i = 0; i < effectiveLength; i++) {
String command = args.getString(i);
if (callable instanceof Dispatcher) {
// Chop off the beginning / if we're are the root level
if (isRootLevel && command.length() > 1 && command.charAt(0) == '/') {
command = command.substring(1);
}
CommandMapping mapping = UtilityCommands.detectCommand((Dispatcher) callable, command, isRootLevel);
if (mapping != null) {
callable = mapping.getCallable();
} else {
if (isRootLevel) {
Set<String> found = new HashSet<>();
String arg = args.getString(i).toLowerCase();
String closest = null;
int distance = Integer.MAX_VALUE;
for (CommandMapping map : aliases) {
String desc = map.getDescription().getDescription();
if (desc == null) desc = map.getDescription().getHelp();
if (desc == null) desc = "";
String[] descSplit = desc.replaceAll("[^A-Za-z0-9]", "").toLowerCase().split(" ");
for (String alias : map.getAllAliases()) {
if (alias.equals(arg)) {
closest = map.getPrimaryAlias();
distance = 0;
found.add(map.getPrimaryAlias());
} else if (alias.contains(arg)) {
closest = map.getPrimaryAlias();
distance = 1;
found.add(map.getPrimaryAlias());
} else if (StringMan.isEqualIgnoreCaseToAny(arg, descSplit)) {
closest = map.getPrimaryAlias();
distance = 1;
found.add(map.getPrimaryAlias());
} else {
int currentDist = StringMan.getLevenshteinDistance(alias, arg);
if (currentDist < distance) {
distance = currentDist;
closest = map.getPrimaryAlias();
}
}
}
}
found.add(closest);
displayFailure(BBC.HELP_SUGGEST.f(arg, StringMan.join(found, ", ")));
return;
} else {
String msg = String.format("The sub-command '%s' under '%s' could not be found.",
command, Joiner.on(" ").join(visited));
displayFailure(msg);
return;
}
}
visited.add(args.getString(i));
isRootLevel = false;
} else {
String msg = String.format("'%s' has no sub-commands. (Maybe '%s' is for a parameter?)",
Joiner.on(" ").join(visited), command);
displayFailure(msg);
return;
}
}
if (!(callable instanceof Dispatcher)) {
// TODO interactive box
String cmd = (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited);
displayUsage(callable, cmd);
return;
}
dispatcher = (Dispatcher) callable;
aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
prefixes = Collections.nCopies(aliases.size(), "");
} else {
aliases = new ArrayList<>();
prefixes = new ArrayList<>();
for (Map.Entry<CommandMapping, String> entry : mappings.entrySet()) {
aliases.add(entry.getKey());
prefixes.add(entry.getValue());
}
}
page = Math.max(0, page);
} else if (grouped.size() > 1) {
displayCategories(grouped);
return;
}
}
// else
{
Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
// Calculate pagination
int offset = perPage * Math.max(0, page);
int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage);
// Box
if (offset >= aliases.size()) {
displayFailure(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal));
} else {
int end = Math.min(offset + perPage, aliases.size());
List<CommandMapping> subAliases = aliases.subList(offset, end);
List<String> subPrefixes = prefixes.subList(offset, end);
Map<CommandMapping, String> commandMap = new LinkedHashMap<>();
for (int i = 0; i < subAliases.size(); i++) {
commandMap.put(subAliases.get(i), subPrefixes.get(i));
}
String visitedString = Joiner.on(" ").join(visited);
displayCommands(commandMap, visitedString, page, pageTotal, effectiveLength);
}
}
} else {
String cmd = (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited);
displayUsage(callable, cmd);
}
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public abstract void displayFailure(String message);
public abstract void displayUsage(CommandCallable callable, String command);
public abstract void displayCategories(Map<String, Map<CommandMapping, String>> categories);
public abstract void displayCommands(Map<CommandMapping, String> commandMap, String visited, int page, int pageTotal, int effectiveLength);
}

View File

@ -27,29 +27,21 @@ import com.boydti.fawe.config.Commands;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RunnableVal3;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.chat.Message;
import com.boydti.fawe.util.chat.UsageMessage;
import com.boydti.fawe.util.gui.FormBuilder;
import com.google.common.base.Joiner;
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.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.command.util.CreatureButcher;
import com.sk89q.worldedit.command.util.EntityRemover;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
@ -70,37 +62,18 @@ import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.DelegateCallable;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.*;
import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
import com.sk89q.worldedit.world.World;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@ -617,7 +590,7 @@ public class UtilityCommands extends MethodCommands {
help(args, worldEdit, actor);
}
private static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) {
protected static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) {
CommandMapping mapping;
// First try the command as entered
@ -896,262 +869,341 @@ public class UtilityCommands extends MethodCommands {
desc = "Open the GUI"
)
@Logging(PLACEMENT)
public void gui(FawePlayer fp, LocalSession session, CommandContext args) throws WorldEditException {
public void gui(Actor actor, FawePlayer fp, LocalSession session, CommandContext args) throws WorldEditException {
FormBuilder gui = Fawe.imp().getFormBuilder();
if (gui == null) throw new UnsupportedOperationException("Not implemented");
Dispatcher callable = worldEdit.getPlatformManager().getCommandManager().getDispatcher();
CommandLocals locals = args.getLocals();
// TODO build form
String prefix = Commands.getAlias(UtilityCommands.class, "/gui");
// TODO sort commands by most used
gui.display(fp, new Consumer<List<String>>() {
new HelpBuilder(callable, args, prefix, Integer.MAX_VALUE) {
@Override
public void accept(List<String> strings) {
public void displayFailure(String message) {
gui.setTitle("Error");
gui.addLabel(message);
}
});
}
private void help(CommandCallable callable) {
@Override
public void displayUsage(CommandCallable callable, String commandString) {
gui.setTitle(commandString);
if (callable instanceof Dispatcher) {
Dispatcher dispathcer = (Dispatcher) callable;
dispathcer.getCommands();
gui.addLabel("Dispatcher not implemented for " + commandString);
} else {
Description cmdDesc = callable.getDescription();
List<Parameter> params = cmdDesc.getParameters();
String[] suggested = new String[params.size()];
if (cmdDesc.getUsage() != null) {
String[] usageArgs = cmdDesc.getUsage().split(" ", params.size());
for (int i = 0; i < usageArgs.length; i++) {
String arg = usageArgs[i];
String[] splitSug = arg.split("=");
if (splitSug.length == 2) {
suggested[i] = splitSug[1];
}
}
}
for (int i = 0 ; i < params.size(); i++) {
String[] def = params.get(i).getDefaultValue();
if (def != null && def.length != 0) {
suggested[i] = def[0];
}
}
String help = cmdDesc.getHelp();
if (help == null || help.isEmpty()) help = cmdDesc.getDescription();
gui.addLabel(BBC.color("&2" + help + "\n"));
List<String> flags = new ArrayList<>();
for (int i = 0; i < params.size(); i++) {
Parameter param = params.get(i);
String name = param.getName();
boolean optional = param.isValueFlag() || param.isOptional();
String[] def = param.getDefaultValue();
if (param.getFlag() != null) {
flags.add("-" + param.getFlag() + " ");
} else {
flags.add("");
}
if (param instanceof ParameterData) {
ParameterData pd = (ParameterData) param;
Type type = pd.getType();
String suggestion = suggested[i];
String color = optional ? "3" : "c";
StringBuilder label = new StringBuilder(BBC.color("&" + color + name + ": "));
// if (suggested[i] != null) label.append(" e.g. " + suggestion);
Range range = MainUtil.getOf(pd.getModifiers(), Range.class);
double min = 0;
double max = 100;
if (range != null) {
min = range.min();
max = range.max();
} else {
SuggestedRange suggestedRange = MainUtil.getOf(pd.getModifiers(), SuggestedRange.class);
if (suggestedRange != null) {
min = suggestedRange.min();
max = suggestedRange.max();
} else if (name.equalsIgnoreCase("radius") || name.equalsIgnoreCase("size")) {
max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
}
}
int step = 1;
Step stepSizeAnn = MainUtil.getOf(pd.getModifiers(), Step.class);
if (stepSizeAnn != null) {
double stepVal = stepSizeAnn.value();
step = Math.max(1, (int) stepVal);
}
/*
BaseBiome
Vector
Vector2D
*/
switch (type.getTypeName()) {
case "double":
case "java.lang.Double": {
double value = suggestion != null ? Double.parseDouble(suggestion) : min;
gui.addSlider("\n" + label.toString(), min, max, 1, value);
break;
}
case "int":
case "java.lang.Integer": {
int value = suggestion != null ? Integer.parseInt(suggestion) : (int) min;
gui.addSlider("\n" + label.toString(), min, max, 1, value);
break;
}
case "boolean":
case "java.lang.Boolean": {
boolean value = suggestion != null ? Boolean.parseBoolean(suggestion) : false;
gui.addToggle(label.toString(), value);
break;
}
case "com.sk89q.worldedit.patterns.Pattern": {
gui.addInput("\n" + label.toString(), "stone", "wood");
break;
}
case "com.sk89q.worldedit.blocks.BaseBlock": {
gui.addInput("\n" + label.toString(), "stone", "wood");
break;
}
case "com.sk89q.worldedit.function.mask.Mask": {
gui.addInput("\n" + label.toString(), "stone", "wood");
break;
}
default:
case "java.lang.String": {
// TODO
// clipboard
// schematic
// image
if (suggestion == null) suggestion = "";
gui.addInput("\n" + label.toString(), suggestion, suggestion);
break;
}
}
} else {
throw new UnsupportedOperationException("Unsupported callable: " + callable.getClass() + " | " + param.getClass());
}
}
gui.setResponder(new Consumer<Map<Integer, Object>>() {
@Override
public void accept(Map<Integer, Object> response) {
int index = 0;
StringBuilder command = new StringBuilder(commandString);
for (Map.Entry<Integer, Object> arg : response.entrySet()) {
String argValue = arg.getValue().toString();
String flag = flags.get(index);
if (!flag.isEmpty()) {
if (argValue.equalsIgnoreCase("false")) continue;
if (argValue.equalsIgnoreCase("true")) argValue = "";
}
command.append(" " + flag + argValue);
index++;
}
CommandEvent event = new CommandEvent(actor, command.toString());
CommandManager.getInstance().handleCommand(event);
}
});
}
}
@Override
public void displayCategories(Map<String, Map<CommandMapping, String>> categories) {
gui.setTitle(BBC.HELP_HEADER_CATEGORIES.s());
List<String> categoryList = new ArrayList<>();
for (Map.Entry<String, Map<CommandMapping, String>> categoryEntry : categories.entrySet()) {
String category = categoryEntry.getKey();
categoryList.add(category);
Map<CommandMapping, String> commandMap = categoryEntry.getValue();
int size = commandMap.size();
String plural = size == 1 ? "command" : "commands";
gui.addButton(BBC.HELP_ITEM_ALLOWED.f(category, "(" + size + " " + plural + ")"), null);
}
gui.setResponder(new Consumer<Map<Integer, Object>>() {
@Override
public void accept(Map<Integer, Object> response) {
if (response.isEmpty()) {
// ??
throw new IllegalArgumentException("No response for categories");
} else {
Map.Entry<Integer, Object> clicked = response.entrySet().iterator().next();
String category = categoryList.get(clicked.getKey());
String arguments = prefix + " " + category;
CommandEvent event = new CommandEvent(actor, arguments);
CommandManager.getInstance().handleCommand(event);
}
}
});
}
@Override
public void displayCommands(Map<CommandMapping, String> commandMap, String visited, int page, int pageTotal, int effectiveLength) {
gui.setTitle(BBC.HELP_HEADER_SUBCOMMANDS.s());
String baseCommand = prefix;
if (effectiveLength > 0) baseCommand += " " + args.getString(0, effectiveLength - 1);
CommandLocals locals = args.getLocals();
if (!visited.isEmpty()) {
visited = visited + " ";
}
List<String> commands = new ArrayList<>();
for (Map.Entry<CommandMapping, String> cmdEntry : commandMap.entrySet()) {
CommandMapping mapping = cmdEntry.getKey();
String subPrefix = cmdEntry.getValue();
StringBuilder helpCmd = new StringBuilder();
helpCmd.append(prefix);
helpCmd.append(" ");
helpCmd.append(subPrefix);
CommandCallable c = mapping.getCallable();
helpCmd.append(visited);
helpCmd.append(mapping.getPrimaryAlias());
String s2 = mapping.getDescription().getDescription();
if (c.testPermission(locals)) {
// gui.addLabel(s2);
gui.addButton(helpCmd.toString(), null);
commands.add(helpCmd.toString());
}
}
gui.setResponder(new Consumer<Map<Integer, Object>>() {
@Override
public void accept(Map<Integer, Object> response) {
if (response.isEmpty()) {
// ??
throw new IllegalArgumentException("No response for command list: " + prefix);
} else {
Map.Entry<Integer, Object> clicked = response.entrySet().iterator().next();
int index = clicked.getKey();
String cmd = commands.get(index);
CommandEvent event = new CommandEvent(actor, cmd);
CommandManager.getInstance().handleCommand(event);
}
}
});
}
}.run();
gui.display(fp);
}
public static void help(CommandContext args, WorldEdit we, Actor actor, String prefix, CommandCallable callable) {
try {
if (callable == null) {
callable = we.getPlatformManager().getCommandManager().getDispatcher();
final int perPage = actor instanceof Player ? 12 : 20; // More pages for console
HelpBuilder builder = new HelpBuilder(callable, args, prefix, perPage) {
@Override
public void displayFailure(String message) {
actor.printError(message);
}
CommandLocals locals = args.getLocals();
int page = -1;
String category = null;
final int perPage = actor instanceof Player ? 12 : 20; // More pages for console
int effectiveLength = args.argsLength();
@Override
public void displayUsage(CommandCallable callable, String command) {
new UsageMessage(callable, command).send(actor);
}
// Detect page from args
try {
if (effectiveLength > 0) {
page = args.getInteger(args.argsLength() - 1);
if (page <= 0) {
page = 1;
@Override
public void displayCategories(Map<String, Map<CommandMapping, String>> categories) {
Message msg = new Message();
msg.prefix().text(BBC.HELP_HEADER_CATEGORIES).newline();
boolean first = true;
for (Map.Entry<String, Map<CommandMapping, String>> entry : categories.entrySet()) {
String s1 = Commands.getAlias(UtilityCommands.class, "/help") + " " + entry.getKey();
String s2 = entry.getValue().size() + "";
msg.text(BBC.HELP_ITEM_ALLOWED, "&a" + s1, s2);
msg.tooltip(StringMan.join(entry.getValue().keySet(), ", ", cm -> cm.getPrimaryAlias()));
msg.command(s1);
msg.newline();
}
msg.text(BBC.HELP_FOOTER).link("https://git.io/vSKE5").newline();
msg.paginate((prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") : prefix), 0, 1);
msg.send(actor);
}
@Override
public void displayCommands(Map<CommandMapping, String> commandMap, String visited, int page, int pageTotal, int effectiveLength) {
Message msg = new Message();
msg.prefix().text(BBC.HELP_HEADER, page + 1, pageTotal).newline();
CommandLocals locals = args.getLocals();
if (!visited.isEmpty()) {
visited = visited + " ";
}
// Add each command
for (Map.Entry<CommandMapping, String> cmdEntry : commandMap.entrySet()) {
CommandMapping mapping = cmdEntry.getKey();
String subPrefix = cmdEntry.getValue();
StringBuilder s1 = new StringBuilder();
s1.append(prefix);
s1.append(subPrefix);
CommandCallable c = mapping.getCallable();
s1.append(visited);
s1.append(mapping.getPrimaryAlias());
String s2 = mapping.getDescription().getDescription();
if (c.testPermission(locals)) {
msg.text(BBC.HELP_ITEM_ALLOWED, s1, s2);
String helpCmd = (prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") + " " : "") + s1;
msg.cmdTip(helpCmd);
msg.newline();
} else {
page--;
msg.text(BBC.HELP_ITEM_DENIED, s1, s2).newline();
}
effectiveLength--;
}
} catch (NumberFormatException ignored) {
if (args.argsLength() == 0) {
msg.text(BBC.HELP_FOOTER).newline();
}
String baseCommand = (prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") : prefix);
if (effectiveLength > 0) baseCommand += " " + args.getString(0, effectiveLength - 1);
msg.paginate(baseCommand, page + 1, pageTotal);
msg.send(actor);
}
};
boolean isRootLevel = true;
List<String> visited = new ArrayList<String>();
// Create the message
if (callable instanceof Dispatcher) {
Dispatcher dispatcher = (Dispatcher) callable;
// Get a list of aliases
List<CommandMapping> aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
List<String> prefixes = Collections.nCopies(aliases.size(), "");
// Group by callable
if (page == -1 || effectiveLength > 0) {
Map<String, Map<CommandMapping, String>> grouped = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (CommandMapping mapping : aliases) {
CommandCallable c = mapping.getCallable();
String group;
if (c instanceof DelegateCallable) {
c = ((DelegateCallable) c).getParent();
}
if (c instanceof ParametricCallable) {
Object obj = ((ParametricCallable) c).getObject();
Command command = obj.getClass().getAnnotation(Command.class);
if (command != null && command.aliases().length != 0) {
group = command.aliases()[0];
} else {
group = obj.getClass().getSimpleName().replaceAll("Commands", "").replaceAll("Util$", "");
}
} else if (c instanceof Dispatcher) {
group = mapping.getPrimaryAlias();
} else {
group = "Unsorted";
}
group = group.replace("/", "");
group = StringMan.toProperCase(group);
Map<CommandMapping, String> queue = grouped.get(group);
if (queue == null) {
queue = new LinkedHashMap<>();
grouped.put(group, queue);
}
if (c instanceof Dispatcher) {
for (CommandMapping m : ((Dispatcher) c).getCommands()) {
queue.put(m, mapping.getPrimaryAlias() + " ");
}
} else {
// Sub commands get priority
queue.putIfAbsent(mapping, "");
}
}
if (effectiveLength > 0) {
String cat = args.getString(0);
Map<CommandMapping, String> mappings = effectiveLength == 1 ? grouped.get(cat) : null;
if (mappings == null) {
// Drill down to the command
for (int i = 0; i < effectiveLength; i++) {
String command = args.getString(i);
if (callable instanceof Dispatcher) {
// Chop off the beginning / if we're are the root level
if (isRootLevel && command.length() > 1 && command.charAt(0) == '/') {
command = command.substring(1);
}
CommandMapping mapping = detectCommand((Dispatcher) callable, command, isRootLevel);
if (mapping != null) {
callable = mapping.getCallable();
} else {
if (isRootLevel) {
Set<String> found = new HashSet<>();
String arg = args.getString(i).toLowerCase();
String closest = null;
int distance = Integer.MAX_VALUE;
for (CommandMapping map : aliases) {
String desc = map.getDescription().getDescription();
if (desc == null) desc = map.getDescription().getHelp();
if (desc == null) desc = "";
String[] descSplit = desc.replaceAll("[^A-Za-z0-9]", "").toLowerCase().split(" ");
for (String alias : map.getAllAliases()) {
if (alias.equals(arg)) {
closest = map.getPrimaryAlias();
distance = 0;
found.add(map.getPrimaryAlias());
} else if (alias.contains(arg)) {
closest = map.getPrimaryAlias();
distance = 1;
found.add(map.getPrimaryAlias());
} else if (StringMan.isEqualIgnoreCaseToAny(arg, descSplit)) {
closest = map.getPrimaryAlias();
distance = 1;
found.add(map.getPrimaryAlias());
} else {
int currentDist = StringMan.getLevenshteinDistance(alias, arg);
if (currentDist < distance) {
distance = currentDist;
closest = map.getPrimaryAlias();
}
}
}
}
found.add(closest);
BBC.HELP_SUGGEST.send(actor, arg, StringMan.join(found, ", "));
return;
} else {
actor.printError(String.format("The sub-command '%s' under '%s' could not be found.",
command, Joiner.on(" ").join(visited)));
return;
}
}
visited.add(args.getString(i));
isRootLevel = false;
} else {
actor.printError(String.format("'%s' has no sub-commands. (Maybe '%s' is for a parameter?)",
Joiner.on(" ").join(visited), command));
return;
}
}
if (!(callable instanceof Dispatcher)) {
// TODO interactive box
new UsageMessage(callable, (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited)).send(actor);
return;
}
dispatcher = (Dispatcher) callable;
aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
prefixes = Collections.nCopies(aliases.size(), "");
} else {
aliases = new ArrayList<>();
prefixes = new ArrayList<>();
for (Map.Entry<CommandMapping, String> entry : mappings.entrySet()) {
aliases.add(entry.getKey());
prefixes.add(entry.getValue());
}
}
page = Math.max(0, page);
} else if (grouped.size() > 1) {
Message msg = new Message();
msg.prefix().text(BBC.HELP_HEADER_CATEGORIES).newline();
boolean first = true;
for (Map.Entry<String, Map<CommandMapping, String>> entry : grouped.entrySet()) {
String s1 = Commands.getAlias(UtilityCommands.class, "/help") + " " + entry.getKey();
String s2 = entry.getValue().size() + "";
msg.text(BBC.HELP_ITEM_ALLOWED, "&a" + s1, s2);
msg.tooltip(StringMan.join(entry.getValue().keySet(), ", ", cm -> cm.getPrimaryAlias()));
msg.command(s1);
msg.newline();
}
msg.text(BBC.HELP_FOOTER).link("https://git.io/vSKE5").newline();
msg.paginate((prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") : prefix), 0, 1);
msg.send(actor);
return;
}
}
// else
{
Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
// Calculate pagination
int offset = perPage * Math.max(0, page);
int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage);
// Box
Message msg = new Message();
if (offset >= aliases.size()) {
msg.text("&c").text(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal));
} else {
msg.prefix().text(BBC.HELP_HEADER, page + 1, pageTotal).newline();
int end = Math.min(offset + perPage, aliases.size());
List<CommandMapping> subAliases = aliases.subList(offset, end);
List<String> subPrefixes = prefixes.subList(offset, end);
boolean first = true;
// Add each command
for (int i = 0; i < subAliases.size(); i++) {
StringBuilder s1 = new StringBuilder();
s1.append(prefix);
s1.append(subPrefixes.get(i));
CommandMapping mapping = subAliases.get(i);
CommandCallable c = mapping.getCallable();
if (!visited.isEmpty()) {
s1.append(Joiner.on(" ").join(visited));
s1.append(" ");
}
s1.append(mapping.getPrimaryAlias());
String s2 = mapping.getDescription().getDescription();
if (c.testPermission(locals)) {
msg.text(BBC.HELP_ITEM_ALLOWED, s1, s2);
String helpCmd = (prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") + " " : "") + s1;
msg.cmdTip(helpCmd);
msg.newline();
} else {
msg.text(BBC.HELP_ITEM_DENIED, s1, s2).newline();
}
}
if (args.argsLength() == 0) {
msg.text(BBC.HELP_FOOTER).newline();
}
String baseCommand = (prefix.equals("/") ? Commands.getAlias(UtilityCommands.class, "/help") : prefix);
if (effectiveLength > 0) baseCommand += " " + args.getString(0, effectiveLength - 1);
msg.paginate(baseCommand, page + 1, pageTotal);
}
msg.send(actor);
}
} else {
new UsageMessage(callable, (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited)).send(actor);
}
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
builder.run();
}
public static Class<UtilityCommands> inject() {

View File

@ -19,12 +19,14 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkNotNull;
public class NukkitFormBuilder implements FormBuilder<Player> {
private Consumer<Map<Integer, Object>> response;
private final List<Element> elements;
private final List<ElementButton> buttons;
private String title = "";
@ -125,22 +127,29 @@ public class NukkitFormBuilder implements FormBuilder<Player> {
}
@Override
public void display(FawePlayer<Player> fp, Consumer<List<String>> response) {
public FormBuilder setResponder(Consumer<Map<Integer, Object>> handler) {
this.response = handler;
return this;
}
@Override
public void display(FawePlayer<Player> fp) {
FormWindow window;
if (buttons.isEmpty()) {
if (icon == null) {
window = new FormWindowCustom("Title", elements);
window = new FormWindowCustom(title, elements);
} else {
window = new FormWindowCustom("Title", elements, icon);
window = new FormWindowCustom(title, elements, icon);
}
} else {
window = new FormWindowSimple("Title", "", buttons);
window = new FormWindowSimple(title, "", buttons);
}
if (response != null) {
window = new ResponseFormWindow(window, response);
}
Player player = fp.parent;
player.showFormWindow(window);
}

View File

@ -1,22 +1,22 @@
package com.boydti.fawe.nukkit.core.gui;
import cn.nukkit.form.window.FormWindow;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkNotNull;
public class ResponseFormWindow extends DelegateFormWindow {
private final Consumer<List<String>> task;
private final Consumer<Map<Integer, Object>> task;
public ResponseFormWindow(FormWindow parent, Consumer<List<String>> onResponse) {
public ResponseFormWindow(FormWindow parent, Consumer<Map<Integer, Object>> onResponse) {
super(parent);
checkNotNull(onResponse);
this.task = onResponse;
}
public void respond(List<String> response) {
task.accept(response);
public void respond(Map<Integer, Object> response) {
if (task != null) task.accept(response);
}
}

View File

@ -6,12 +6,19 @@ import cn.nukkit.event.EventHandler;
import cn.nukkit.event.Listener;
import cn.nukkit.event.player.PlayerFormRespondedEvent;
import cn.nukkit.event.player.PlayerQuitEvent;
import cn.nukkit.form.element.ElementButton;
import cn.nukkit.form.response.FormResponse;
import cn.nukkit.form.response.FormResponseCustom;
import cn.nukkit.form.response.FormResponseData;
import cn.nukkit.form.response.FormResponseSimple;
import cn.nukkit.form.window.FormWindow;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.IFawe;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.nukkit.core.NukkitTaskManager;
import com.boydti.fawe.nukkit.core.NukkitWorldEdit;
import com.boydti.fawe.nukkit.core.gui.NukkitFormBuilder;
import com.boydti.fawe.nukkit.core.gui.ResponseFormWindow;
import com.boydti.fawe.nukkit.listener.BrushListener;
import com.boydti.fawe.nukkit.optimization.queue.NukkitQueue;
import com.boydti.fawe.object.FaweChunk;
@ -26,6 +33,9 @@ import com.sk89q.worldedit.world.World;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
@ -72,6 +82,40 @@ public class FaweNukkit implements IFawe, Listener {
@EventHandler
public void onFormSubmit(PlayerFormRespondedEvent event) {
FormWindow window = event.getWindow();
if (window instanceof ResponseFormWindow) {
ResponseFormWindow responseWindow = (ResponseFormWindow) window;
FormResponse response = event.getResponse();
if (response instanceof FormResponseSimple) {
FormResponseSimple simple = (FormResponseSimple) response;
ElementButton button = simple.getClickedButton();
int index = simple.getClickedButtonId();
System.out.println("Simple: " + index);
responseWindow.respond(Collections.singletonMap(index, "true"));
} else if (response instanceof FormResponseCustom) {
FormResponseCustom custom = (FormResponseCustom) response;
HashMap<Integer, Object> responses = custom.getResponses();
HashMap<Integer, Object> parsedResponses = new HashMap<>();
for (Map.Entry<Integer, Object> responseEntry : responses.entrySet()) {
int index = responseEntry.getKey();
Object value = responseEntry.getValue();
if (value instanceof FormResponseData) {
value = ((FormResponseData) value).getElementContent();
} else if (value instanceof Float) {
value = (double) (float) value;
}
parsedResponses.put(index, value);
}
responseWindow.respond(parsedResponses);
System.out.println("Custom: " + parsedResponses);
}
}
// TODO
}

View File

@ -36,7 +36,7 @@ public class FaweNukkitPlayer extends FawePlayer<Player> {
@Override
public void setPermission(final String perm, final boolean flag) {
this.parent.addAttachment(Fawe.<FaweNukkit> imp().getPlugin()).setPermission("fawe.bypass", flag);
this.parent.addAttachment(Fawe.<FaweNukkit> imp().getPlugin()).setPermission(perm, flag);
}

View File

@ -10,6 +10,9 @@ permissions:
default: true
fawe.bypass:
default: false
children:
fawe.bypass.regions: true
fawe.limit.*: true
fawe.tips:
default: false
fawe.admin: