mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-01 02:46:41 +00:00
Major command changes that don't work yet.
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.util;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -47,7 +48,7 @@ public class Location extends Vector3 {
|
||||
* @param extent the extent
|
||||
*/
|
||||
public Location(Extent extent) {
|
||||
this(extent, Vector3.ZERO, Vector3.ZERO);
|
||||
this(extent, Vector3.ZERO, 0f, 90f);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +61,7 @@ public class Location extends Vector3 {
|
||||
* @param z the Z coordinate
|
||||
*/
|
||||
public Location(Extent extent, double x, double y, double z) {
|
||||
this(extent, Vector3.at(x, y, z), Vector3.ZERO);
|
||||
this(extent, Vector3.at(x, y, z), 0f, 90f);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +72,7 @@ public class Location extends Vector3 {
|
||||
* @param position the position vector
|
||||
*/
|
||||
public Location(Extent extent, Vector3 position) {
|
||||
this(extent, position, Vector3.ZERO);
|
||||
this(extent, position, 0f, 90f);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,7 +125,6 @@ public class Location extends Vector3 {
|
||||
* @param yaw the yaw, in degrees
|
||||
* @param pitch the pitch, in degrees
|
||||
*/
|
||||
|
||||
public Location(Extent extent, Vector3 position, float yaw, float pitch) {
|
||||
super(position);
|
||||
checkNotNull(extent);
|
||||
@ -292,6 +292,18 @@ public class Location extends Vector3 {
|
||||
return new Location(extent, position, yaw, pitch);
|
||||
}
|
||||
|
||||
@Override public Location clampY(int min, int max) {
|
||||
checkArgument(min <= max, "minimum cannot be greater than maximum");
|
||||
if (y < min) {
|
||||
return new Location(extent, x, min, z);
|
||||
}
|
||||
if (y > max) {
|
||||
return new Location(extent, x, max, z);
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@ -309,8 +321,4 @@ public class Location extends Vector3 {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,6 @@ import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
import org.slf4j.Logger;
|
||||
@ -104,7 +102,6 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
||||
}
|
||||
superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
|
||||
superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
|
||||
noDoubleSlash = getBool("no-double-slash", noDoubleSlash);
|
||||
useInventory = getBool("use-inventory", useInventory);
|
||||
useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
|
||||
useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
|
||||
|
@ -92,8 +92,6 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
superPickaxeManyDrop = config.getBoolean(
|
||||
"super-pickaxe.many-drop-items", superPickaxeManyDrop);
|
||||
|
||||
noDoubleSlash = config.getBoolean("no-double-slash", noDoubleSlash);
|
||||
|
||||
useInventory = config.getBoolean("use-inventory.enable", useInventory);
|
||||
useInventoryOverride = config.getBoolean("use-inventory.allow-override",
|
||||
useInventoryOverride);
|
||||
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit.util.command.fluent;
|
||||
|
||||
import com.boydti.fawe.config.Commands;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.worldedit.util.command.CallableProcessor;
|
||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
import com.sk89q.worldedit.util.command.CommandMapping;
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||
|
||||
/**
|
||||
* Used to convert a recognized {@link Throwable} into an appropriate
|
||||
* {@link CommandException}.
|
||||
*
|
||||
* <p>Methods (when invoked by a {@link ParametricBuilder}-created command) may throw
|
||||
* relevant exceptions that are not caught by the command manager, but translate
|
||||
* into reasonable exceptions for an application. However, unknown exceptions are
|
||||
* normally simply wrapped in a {@link WrappedCommandException} and bubbled up. Only
|
||||
* normal {@link CommandException}s will be printed correctly, so a converter translates
|
||||
* one of these unknown exceptions into an appropriate {@link CommandException}.</p>
|
||||
*
|
||||
* <p>This also allows the code calling the command to not need be aware of these
|
||||
* application-specific exceptions, as they will all be converted to
|
||||
* {@link CommandException}s that are handled normally.</p>
|
||||
*/
|
||||
public interface ExceptionConverter {
|
||||
|
||||
/**
|
||||
* Attempt to convert the given throwable into a {@link CommandException}.
|
||||
*
|
||||
* <p>If the exception is not recognized, then nothing should be thrown.</p>
|
||||
*
|
||||
* @param t the throwable
|
||||
* @throws CommandException a command exception
|
||||
*/
|
||||
void convert(Throwable t) throws CommandException;
|
||||
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation of an {@link ExceptionConverter} that automatically calls
|
||||
* the correct method defined on this object.
|
||||
*
|
||||
* <p>Only public methods will be used. Methods will be called in order of decreasing
|
||||
* levels of inheritance (between classes where one inherits the other). For two
|
||||
* different inheritance branches, the order between them is undefined.</p>
|
||||
*/
|
||||
public abstract class ExceptionConverterHelper implements ExceptionConverter {
|
||||
|
||||
private final List<ExceptionHandler> handlers;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ExceptionConverterHelper() {
|
||||
List<ExceptionHandler> handlers = new ArrayList<>();
|
||||
|
||||
for (Method method : this.getClass().getMethods()) {
|
||||
if (method.getAnnotation(ExceptionMatch.class) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] parameters = method.getParameterTypes();
|
||||
if (parameters.length == 1) {
|
||||
Class<?> cls = parameters[0];
|
||||
if (Throwable.class.isAssignableFrom(cls)) {
|
||||
handlers.add(new ExceptionHandler(
|
||||
(Class<? extends Throwable>) cls, method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(handlers);
|
||||
|
||||
this.handlers = handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convert(Throwable t) throws CommandException {
|
||||
Class<?> throwableClass = t.getClass();
|
||||
for (ExceptionHandler handler : handlers) {
|
||||
if (handler.cls.isAssignableFrom(throwableClass)) {
|
||||
try {
|
||||
handler.method.invoke(this, t);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof CommandException) {
|
||||
throw (CommandException) e.getCause();
|
||||
}
|
||||
throw new WrappedCommandException(e);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new WrappedCommandException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExceptionHandler implements Comparable<ExceptionHandler> {
|
||||
final Class<? extends Throwable> cls;
|
||||
final Method method;
|
||||
|
||||
private ExceptionHandler(Class<? extends Throwable> cls, Method method) {
|
||||
this.cls = cls;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ExceptionHandler o) {
|
||||
if (cls.equals(o.cls)) {
|
||||
return 0;
|
||||
} else if (cls.isAssignableFrom(o.cls)) {
|
||||
return 1;
|
||||
} else if (o.cls.isAssignableFrom(cls)) {
|
||||
return -1;
|
||||
} else {
|
||||
return cls.getCanonicalName().compareTo(o.cls.getCanonicalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package com.sk89q.worldedit.util.command.parametric;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
|
||||
import com.google.common.primitives.Chars;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.util.command.MissingParameterException;
|
||||
@ -41,7 +41,7 @@ public class LegacyCommandsHandler extends AbstractInvokeListener implements Inv
|
||||
|
||||
@Override
|
||||
public void preProcess(Object object, Method method,
|
||||
ParameterData[] parameters, CommandContext context)
|
||||
ParameterData[] parameters, CommandContext context)
|
||||
throws CommandException, ParameterException {
|
||||
}
|
||||
|
||||
@ -50,12 +50,12 @@ public class LegacyCommandsHandler extends AbstractInvokeListener implements Inv
|
||||
ParameterData[] parameters, Object[] args, CommandContext context)
|
||||
throws ParameterException {
|
||||
Command annotation = method.getAnnotation(Command.class);
|
||||
|
||||
|
||||
if (annotation != null) {
|
||||
if (context.argsLength() < annotation.min()) {
|
||||
throw new MissingParameterException();
|
||||
}
|
||||
|
||||
|
||||
if (annotation.max() != -1 && context.argsLength() > annotation.max()) {
|
||||
throw new UnconsumedParameterException(
|
||||
context.getRemainingString(annotation.max()));
|
||||
@ -73,21 +73,21 @@ public class LegacyCommandsHandler extends AbstractInvokeListener implements Inv
|
||||
public void updateDescription(Object object, Method method,
|
||||
ParameterData[] parameters, SimpleDescription description) {
|
||||
Command annotation = method.getAnnotation(Command.class);
|
||||
|
||||
|
||||
// Handle the case for old commands where no usage is set and all of its
|
||||
// parameters are provider bindings, so its usage information would
|
||||
// be blank and would imply that there were no accepted parameters
|
||||
if (annotation != null && annotation.usage().isEmpty()
|
||||
if (annotation != null && annotation.usage().isEmpty()
|
||||
&& (annotation.min() > 0 || annotation.max() > 0)) {
|
||||
boolean hasUserParameters = false;
|
||||
|
||||
|
||||
for (ParameterData parameter : parameters) {
|
||||
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
|
||||
hasUserParameters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!hasUserParameters) {
|
||||
description.overrideUsage("(unknown usage information)");
|
||||
}
|
||||
|
@ -19,13 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.boydti.fawe.command.FawePrimitiveBinding;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.command.FawePrimitiveBinding;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
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;
|
||||
@ -42,11 +40,11 @@ import com.sk89q.worldedit.util.command.binding.PrimitiveBindings;
|
||||
import com.sk89q.worldedit.util.command.binding.StandardBindings;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.thoughtworks.paranamer.Paranamer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
|
||||
/**
|
||||
* Creates commands using annotations placed on methods and individual parameters of
|
||||
|
@ -20,7 +20,7 @@
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.google.common.primitives.Chars;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
|
@ -1,271 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ColorCodeBuilder {
|
||||
|
||||
private static final ColorCodeBuilder instance = new ColorCodeBuilder();
|
||||
private static final Joiner newLineJoiner = Joiner.on("\n");
|
||||
public static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47;
|
||||
|
||||
/**
|
||||
* Convert a message into color-coded text.
|
||||
*
|
||||
* @param message the message
|
||||
* @return a list of lines
|
||||
*/
|
||||
public String[] build(StyledFragment message) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
buildFragment(builder, message, message.getStyle(), new StyleSet());
|
||||
return builder.toString().split("\r?\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a fragment.
|
||||
*
|
||||
* @param builder the string builder
|
||||
* @param message the message
|
||||
* @param parentStyle the parent style
|
||||
* @param lastStyle the last style
|
||||
* @return the last style used
|
||||
*/
|
||||
private StyleSet buildFragment(StringBuilder builder, StyledFragment message, StyleSet parentStyle, StyleSet lastStyle) {
|
||||
for (Fragment node : message.getChildren()) {
|
||||
if (node instanceof StyledFragment) {
|
||||
StyledFragment fragment = (StyledFragment) node;
|
||||
lastStyle = buildFragment(
|
||||
builder, fragment,
|
||||
parentStyle.extend(message.getStyle()), lastStyle);
|
||||
} else {
|
||||
StyleSet style = parentStyle.extend(message.getStyle());
|
||||
builder.append(getAdditive(style, lastStyle));
|
||||
builder.append(node);
|
||||
lastStyle = style;
|
||||
}
|
||||
}
|
||||
|
||||
return lastStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatting codes.
|
||||
*
|
||||
* @param style the style
|
||||
* @return the color codes
|
||||
*/
|
||||
public static String getFormattingCode(StyleSet style) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (style.isBold()) {
|
||||
builder.append(Style.BOLD);
|
||||
}
|
||||
if (style.isItalic()) {
|
||||
builder.append(Style.ITALIC);
|
||||
}
|
||||
if (style.isUnderline()) {
|
||||
builder.append(Style.UNDERLINE);
|
||||
}
|
||||
if (style.isStrikethrough()) {
|
||||
builder.append(Style.STRIKETHROUGH);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatting and color codes.
|
||||
*
|
||||
* @param style the style
|
||||
* @return the color codes
|
||||
*/
|
||||
public static String getCode(StyleSet style) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(getFormattingCode(style));
|
||||
if (style.getColor() != null) {
|
||||
builder.append(style.getColor());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the additional color codes needed to set the given style when the current
|
||||
* style is the other given one.
|
||||
*
|
||||
* @param resetTo the style to reset to
|
||||
* @param resetFrom the style to reset from
|
||||
* @return the color codes
|
||||
*/
|
||||
public static String getAdditive(StyleSet resetTo, StyleSet resetFrom) {
|
||||
if (!resetFrom.hasFormatting() && resetTo.hasFormatting()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(getFormattingCode(resetTo));
|
||||
if (resetFrom.getColor() != resetTo.getColor()) {
|
||||
builder.append(resetTo.getColor());
|
||||
}
|
||||
return builder.toString();
|
||||
} else if (!resetFrom.hasEqualFormatting(resetTo) ||
|
||||
(resetFrom.getColor() != null && resetTo.getColor() == null)) {
|
||||
// Have to set reset code and add back all the formatting codes
|
||||
return Style.RESET + getCode(resetTo);
|
||||
} else {
|
||||
if (resetFrom.getColor() != resetTo.getColor()) {
|
||||
return String.valueOf(resetTo.getColor());
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Word wrap the given text and maintain color codes throughout lines.
|
||||
*
|
||||
* <p>This is borrowed from Bukkit.</p>
|
||||
*
|
||||
* @param rawString the raw string
|
||||
* @param lineLength the maximum line length
|
||||
* @return a list of lines
|
||||
*/
|
||||
private String[] wordWrap(String rawString, int lineLength) {
|
||||
// A null string is a single line
|
||||
if (rawString == null) {
|
||||
return new String[] {""};
|
||||
}
|
||||
|
||||
// A string shorter than the lineWidth is a single line
|
||||
if (rawString.length() <= lineLength && !rawString.contains("\n")) {
|
||||
return new String[] {rawString};
|
||||
}
|
||||
|
||||
char[] rawChars = (rawString + ' ').toCharArray(); // add a trailing space to trigger pagination
|
||||
StringBuilder word = new StringBuilder();
|
||||
StringBuilder line = new StringBuilder();
|
||||
List<String> lines = new LinkedList<>();
|
||||
int lineColorChars = 0;
|
||||
|
||||
for (int i = 0; i < rawChars.length; i++) {
|
||||
char c = rawChars[i];
|
||||
|
||||
// skip chat color modifiers
|
||||
if (c == Style.COLOR_CHAR) {
|
||||
word.append(Style.getByChar(rawChars[i + 1]));
|
||||
lineColorChars += 2;
|
||||
i++; // Eat the next character as we have already processed it
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ' ' || c == '\n') {
|
||||
if (line.length() == 0 && word.length() > lineLength) { // special case: extremely long word begins a line
|
||||
String wordStr = word.toString();
|
||||
String transformed;
|
||||
if ((transformed = transform(wordStr)) != null) {
|
||||
line.append(transformed);
|
||||
} else {
|
||||
lines.addAll(Arrays.asList(word.toString().split("(?<=\\G.{" + lineLength + "})")));
|
||||
}
|
||||
} else if (line.length() + word.length() - lineColorChars == lineLength) { // Line exactly the correct length...newline
|
||||
line.append(' ');
|
||||
line.append(word);
|
||||
lines.add(line.toString());
|
||||
line = new StringBuilder();
|
||||
lineColorChars = 0;
|
||||
} else if (line.length() + 1 + word.length() - lineColorChars > lineLength) { // Line too long...break the line
|
||||
String wordStr = word.toString();
|
||||
String transformed;
|
||||
if (word.length() > lineLength && (transformed = transform(wordStr)) != null) {
|
||||
if (line.length() + 1 + transformed.length() - lineColorChars > lineLength) {
|
||||
lines.add(line.toString());
|
||||
line = new StringBuilder(transformed);
|
||||
lineColorChars = 0;
|
||||
} else {
|
||||
if (line.length() > 0) {
|
||||
line.append(' ');
|
||||
}
|
||||
line.append(transformed);
|
||||
}
|
||||
} else {
|
||||
for (String partialWord : wordStr.split("(?<=\\G.{" + lineLength + "})")) {
|
||||
lines.add(line.toString());
|
||||
line = new StringBuilder(partialWord);
|
||||
}
|
||||
lineColorChars = 0;
|
||||
}
|
||||
} else {
|
||||
if (line.length() > 0) {
|
||||
line.append(' ');
|
||||
}
|
||||
line.append(word);
|
||||
}
|
||||
word = new StringBuilder();
|
||||
|
||||
if (c == '\n') { // Newline forces the line to flush
|
||||
lines.add(line.toString());
|
||||
line = new StringBuilder();
|
||||
}
|
||||
} else {
|
||||
word.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(line.length() > 0) { // Only add the last line if there is anything to add
|
||||
lines.add(line.toString());
|
||||
}
|
||||
|
||||
// Iterate over the wrapped lines, applying the last color from one line to the beginning of the next
|
||||
if (lines.get(0).isEmpty() || lines.get(0).charAt(0) != Style.COLOR_CHAR) {
|
||||
lines.set(0, Style.WHITE + lines.get(0));
|
||||
}
|
||||
for (int i = 1; i < lines.size(); i++) {
|
||||
final String pLine = lines.get(i-1);
|
||||
final String subLine = lines.get(i);
|
||||
|
||||
char color = pLine.charAt(pLine.lastIndexOf(Style.COLOR_CHAR) + 1);
|
||||
if (subLine.isEmpty() || subLine.charAt(0) != Style.COLOR_CHAR) {
|
||||
lines.set(i, Style.getByChar(color) + subLine);
|
||||
}
|
||||
}
|
||||
|
||||
return lines.toArray(new String[lines.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for transforming a word, such as a URL.
|
||||
*
|
||||
* @param word the word
|
||||
* @return the transformed value, or null to do nothing
|
||||
*/
|
||||
protected String transform(String word) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given styled fragment into color codes.
|
||||
*
|
||||
* @param fragment the fragment
|
||||
* @return color codes
|
||||
*/
|
||||
public static String asColorCodes(StyledFragment fragment) {
|
||||
return newLineJoiner.join(instance.build(fragment));
|
||||
}
|
||||
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting;
|
||||
|
||||
/**
|
||||
* A fragment of text.
|
||||
*/
|
||||
public class Fragment {
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
Fragment() {
|
||||
}
|
||||
|
||||
public Fragment append(String str) {
|
||||
builder.append(Style.stripColor(str));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(Object obj) {
|
||||
append(String.valueOf(obj));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(StringBuffer sb) {
|
||||
append(String.valueOf(sb));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(CharSequence s) {
|
||||
append(String.valueOf(s));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(boolean b) {
|
||||
append(String.valueOf(b));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(char c) {
|
||||
append(String.valueOf(c));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(int i) {
|
||||
append(String.valueOf(i));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(long lng) {
|
||||
append(String.valueOf(lng));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(float f) {
|
||||
append(String.valueOf(f));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment append(double d) {
|
||||
append(String.valueOf(d));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Fragment newLine() {
|
||||
append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* All supported color values for chat.
|
||||
*
|
||||
* <p>From Bukkit.</p>
|
||||
*/
|
||||
public enum Style {
|
||||
/**
|
||||
* Represents black
|
||||
*/
|
||||
BLACK('0', 0x00),
|
||||
/**
|
||||
* Represents dark blue
|
||||
*/
|
||||
BLUE_DARK('1', 0x1),
|
||||
/**
|
||||
* Represents dark green
|
||||
*/
|
||||
GREEN_DARK('2', 0x2),
|
||||
/**
|
||||
* Represents dark blue (aqua)
|
||||
*/
|
||||
CYAN_DARK('3', 0x3),
|
||||
/**
|
||||
* Represents dark red
|
||||
*/
|
||||
RED_DARK('4', 0x4),
|
||||
/**
|
||||
* Represents dark purple
|
||||
*/
|
||||
PURPLE_DARK('5', 0x5),
|
||||
/**
|
||||
* Represents gold
|
||||
*/
|
||||
YELLOW_DARK('6', 0x6),
|
||||
/**
|
||||
* Represents gray
|
||||
*/
|
||||
GRAY('7', 0x7),
|
||||
/**
|
||||
* Represents dark gray
|
||||
*/
|
||||
GRAY_DARK('8', 0x8),
|
||||
/**
|
||||
* Represents blue
|
||||
*/
|
||||
BLUE('9', 0x9),
|
||||
/**
|
||||
* Represents green
|
||||
*/
|
||||
GREEN('a', 0xA),
|
||||
/**
|
||||
* Represents aqua
|
||||
*/
|
||||
CYAN('b', 0xB),
|
||||
/**
|
||||
* Represents red
|
||||
*/
|
||||
RED('c', 0xC),
|
||||
/**
|
||||
* Represents light purple
|
||||
*/
|
||||
PURPLE('d', 0xD),
|
||||
/**
|
||||
* Represents yellow
|
||||
*/
|
||||
YELLOW('e', 0xE),
|
||||
/**
|
||||
* Represents white
|
||||
*/
|
||||
WHITE('f', 0xF),
|
||||
/**
|
||||
* Represents magical characters that change around randomly
|
||||
*/
|
||||
RANDOMIZE('k', 0x10, true),
|
||||
/**
|
||||
* Makes the text bold.
|
||||
*/
|
||||
BOLD('l', 0x11, true),
|
||||
/**
|
||||
* Makes a line appear through the text.
|
||||
*/
|
||||
STRIKETHROUGH('m', 0x12, true),
|
||||
/**
|
||||
* Makes the text appear underlined.
|
||||
*/
|
||||
UNDERLINE('n', 0x13, true),
|
||||
/**
|
||||
* Makes the text italic.
|
||||
*/
|
||||
ITALIC('o', 0x14, true),
|
||||
/**
|
||||
* Resets all previous chat colors or formats.
|
||||
*/
|
||||
RESET('r', 0x15);
|
||||
|
||||
/**
|
||||
* The special character which prefixes all chat color codes. Use this if you need to dynamically
|
||||
* convert color codes from your custom format.
|
||||
*/
|
||||
public static final char COLOR_CHAR = '\u00A7';
|
||||
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + COLOR_CHAR + "[0-9A-FK-OR]");
|
||||
|
||||
private final int intCode;
|
||||
private final char code;
|
||||
private final boolean isFormat;
|
||||
private final String toString;
|
||||
private final static Map<Integer, Style> BY_ID = Maps.newHashMap();
|
||||
private final static Map<Character, Style> BY_CHAR = Maps.newHashMap();
|
||||
|
||||
Style(char code, int intCode) {
|
||||
this(code, intCode, false);
|
||||
}
|
||||
|
||||
Style(char code, int intCode, boolean isFormat) {
|
||||
this.code = code;
|
||||
this.intCode = intCode;
|
||||
this.isFormat = isFormat;
|
||||
this.toString = new String(new char[] {COLOR_CHAR, code});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the char value associated with this color
|
||||
*
|
||||
* @return A char value of this color code
|
||||
*/
|
||||
public char getChar() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this code is a format code as opposed to a color code.
|
||||
*
|
||||
* @return the if the code is a formatting code
|
||||
*/
|
||||
public boolean isFormat() {
|
||||
return isFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this code is a color code as opposed to a format code.
|
||||
*
|
||||
* @return the if the code is a color
|
||||
*/
|
||||
public boolean isColor() {
|
||||
return !isFormat && this != RESET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color represented by the specified color code
|
||||
*
|
||||
* @param code Code to check
|
||||
* @return Associative Style with the given code, or null if it doesn't exist
|
||||
*/
|
||||
public static Style getByChar(char code) {
|
||||
return BY_CHAR.get(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color represented by the specified color code
|
||||
*
|
||||
* @param code Code to check
|
||||
* @return Associative Style with the given code, or null if it doesn't exist
|
||||
*/
|
||||
public static Style getByChar(String code) {
|
||||
checkNotNull(code);
|
||||
checkArgument(!code.isEmpty(), "Code must have at least one character");
|
||||
|
||||
return BY_CHAR.get(code.charAt(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the given message of all color codes
|
||||
*
|
||||
* @param input String to strip of color
|
||||
* @return A copy of the input string, without any coloring
|
||||
*/
|
||||
public static String stripColor(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return STRIP_COLOR_PATTERN.matcher(input).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a string using an alternate color code character into a string that uses the internal
|
||||
* ChatColor.COLOR_CODE color code character. The alternate color code character will only be replaced
|
||||
* if it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r.
|
||||
*
|
||||
* @param altColorChar The alternate color code character to replace. Ex: &
|
||||
* @param textToTranslate Text containing the alternate color code character.
|
||||
* @return Text containing the ChatColor.COLOR_CODE color code character.
|
||||
*/
|
||||
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) {
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
for (int i = 0; i < b.length - 1; i++) {
|
||||
if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) {
|
||||
b[i] = Style.COLOR_CHAR;
|
||||
b[i+1] = Character.toLowerCase(b[i+1]);
|
||||
}
|
||||
}
|
||||
return new String(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ChatColors used at the end of the given input string.
|
||||
*
|
||||
* @param input Input string to retrieve the colors from.
|
||||
* @return Any remaining ChatColors to pass onto the next line.
|
||||
*/
|
||||
public static String getLastColors(String input) {
|
||||
String result = "";
|
||||
int length = input.length();
|
||||
|
||||
// Search backwards from the end as it is faster
|
||||
for (int index = length - 1; index > -1; index--) {
|
||||
char section = input.charAt(index);
|
||||
if (section == COLOR_CHAR && index < length - 1) {
|
||||
char c = input.charAt(index + 1);
|
||||
Style color = getByChar(c);
|
||||
|
||||
if (color != null) {
|
||||
result = color + result;
|
||||
|
||||
// Once we find a color or reset we can stop searching
|
||||
if (color.isColor() || color == RESET) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
for (Style color : values()) {
|
||||
BY_ID.put(color.intCode, color);
|
||||
BY_CHAR.put(color.code, color);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting;
|
||||
|
||||
/**
|
||||
* Represents set of styles, such as color, bold, etc.
|
||||
*/
|
||||
public class StyleSet {
|
||||
|
||||
private Boolean bold;
|
||||
private Boolean italic;
|
||||
private Boolean underline;
|
||||
private Boolean strikethrough;
|
||||
private Style color;
|
||||
|
||||
/**
|
||||
* Create a new style set with no properties set.
|
||||
*/
|
||||
public StyleSet() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new style set with the given styles.
|
||||
*
|
||||
* <p>{@link Style#RESET} will be ignored if provided.</p>
|
||||
*
|
||||
* @param styles a list of styles
|
||||
*/
|
||||
public StyleSet(Style... styles) {
|
||||
for (Style style : styles) {
|
||||
if (style.isColor()) {
|
||||
color = style;
|
||||
} else if (style == Style.BOLD) {
|
||||
bold = true;
|
||||
} else if (style == Style.ITALIC) {
|
||||
italic = true;
|
||||
} else if (style == Style.UNDERLINE) {
|
||||
underline = true;
|
||||
} else if (style == Style.STRIKETHROUGH) {
|
||||
strikethrough = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this style set is bold.
|
||||
*
|
||||
* @return true, false, or null if unset
|
||||
*/
|
||||
public Boolean getBold() {
|
||||
return bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the text is bold.
|
||||
*
|
||||
* @return true if bold
|
||||
*/
|
||||
public boolean isBold() {
|
||||
return getBold() != null && getBold();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the text is bold.
|
||||
*
|
||||
* @param bold true, false, or null to unset
|
||||
*/
|
||||
public void setBold(Boolean bold) {
|
||||
this.bold = bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this style set is italicized.
|
||||
*
|
||||
* @return true, false, or null if unset
|
||||
*/
|
||||
public Boolean getItalic() {
|
||||
return italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the text is italicized.
|
||||
*
|
||||
* @return true if italicized
|
||||
*/
|
||||
public boolean isItalic() {
|
||||
return getItalic() != null && getItalic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the text is italicized.
|
||||
*
|
||||
* @param italic false, or null to unset
|
||||
*/
|
||||
public void setItalic(Boolean italic) {
|
||||
this.italic = italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this style set is underlined.
|
||||
*
|
||||
* @return true, false, or null if unset
|
||||
*/
|
||||
public Boolean getUnderline() {
|
||||
return underline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the text is underlined.
|
||||
*
|
||||
* @return true if underlined
|
||||
*/
|
||||
public boolean isUnderline() {
|
||||
return getUnderline() != null && getUnderline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the text is underline.
|
||||
*
|
||||
* @param underline false, or null to unset
|
||||
*/
|
||||
public void setUnderline(Boolean underline) {
|
||||
this.underline = underline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this style set is stricken through.
|
||||
*
|
||||
* @return true, false, or null if unset
|
||||
*/
|
||||
public Boolean getStrikethrough() {
|
||||
return strikethrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the text is stricken through.
|
||||
*
|
||||
* @return true if there is strikethrough applied
|
||||
*/
|
||||
public boolean isStrikethrough() {
|
||||
return getStrikethrough() != null && getStrikethrough();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the text is stricken through.
|
||||
*
|
||||
* @param strikethrough false, or null to unset
|
||||
*/
|
||||
public void setStrikethrough(Boolean strikethrough) {
|
||||
this.strikethrough = strikethrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of the text.
|
||||
*
|
||||
* @return true, false, or null if unset
|
||||
*/
|
||||
public Style getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the text.
|
||||
*
|
||||
* @param color the color
|
||||
*/
|
||||
public void setColor(Style color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether text formatting (bold, italics, underline, strikethrough) is set.
|
||||
*
|
||||
* @return true if formatting is set
|
||||
*/
|
||||
public boolean hasFormatting() {
|
||||
return getBold() != null || getItalic() != null
|
||||
|| getUnderline() != null || getStrikethrough() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return where the text formatting of the given style set is different from
|
||||
* that assigned to this one.
|
||||
*
|
||||
* @param other the other style set
|
||||
* @return true if there is a difference
|
||||
*/
|
||||
public boolean hasEqualFormatting(StyleSet other) {
|
||||
return getBold() == other.getBold() && getItalic() == other.getItalic()
|
||||
&& getUnderline() == other.getUnderline() &&
|
||||
getStrikethrough() == other.getStrikethrough();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with styles inherited from this one but with new styles
|
||||
* from the given style set.
|
||||
*
|
||||
* @param style the style set
|
||||
* @return a new style set instance
|
||||
*/
|
||||
public StyleSet extend(StyleSet style) {
|
||||
StyleSet newStyle = clone();
|
||||
if (style.getBold() != null) {
|
||||
newStyle.setBold(style.getBold());
|
||||
}
|
||||
if (style.getItalic() != null) {
|
||||
newStyle.setItalic(style.getItalic());
|
||||
}
|
||||
if (style.getUnderline() != null) {
|
||||
newStyle.setUnderline(style.getUnderline());
|
||||
}
|
||||
if (style.getStrikethrough() != null) {
|
||||
newStyle.setStrikethrough(style.getStrikethrough());
|
||||
}
|
||||
if (style.getColor() != null) {
|
||||
newStyle.setColor(style.getColor());
|
||||
}
|
||||
return newStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyleSet clone() {
|
||||
StyleSet style = new StyleSet();
|
||||
style.setBold(getBold());
|
||||
style.setItalic(getItalic());
|
||||
style.setUnderline(getUnderline());
|
||||
style.setStrikethrough(getStrikethrough());
|
||||
style.setColor(getColor());
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A fragment of text that can be styled.
|
||||
*/
|
||||
public class StyledFragment extends Fragment {
|
||||
|
||||
private final List<Fragment> children = new ArrayList<>();
|
||||
private StyleSet style;
|
||||
private Fragment lastText;
|
||||
|
||||
public StyledFragment() {
|
||||
style = new StyleSet();
|
||||
}
|
||||
|
||||
public StyledFragment(StyleSet style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public StyledFragment(Style... styles) {
|
||||
this.style = new StyleSet(styles);
|
||||
}
|
||||
|
||||
public StyleSet getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public void setStyles(StyleSet style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public List<Fragment> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
protected Fragment lastText() {
|
||||
Fragment text;
|
||||
if (!children.isEmpty()) {
|
||||
text = children.get(children.size() - 1);
|
||||
if (text == lastText) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
text = new Fragment();
|
||||
this.lastText = text;
|
||||
children.add(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
public StyledFragment createFragment(Style... styles) {
|
||||
StyledFragment fragment = new StyledFragment(styles);
|
||||
append(fragment);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public StyledFragment append(StyledFragment fragment) {
|
||||
children.add(fragment);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(String str) {
|
||||
lastText().append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(Object obj) {
|
||||
append(String.valueOf(obj));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(StringBuffer sb) {
|
||||
append(String.valueOf(sb));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(CharSequence s) {
|
||||
append(String.valueOf(s));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(boolean b) {
|
||||
append(String.valueOf(b));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(char c) {
|
||||
append(String.valueOf(c));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(int i) {
|
||||
append(String.valueOf(i));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(long lng) {
|
||||
append(String.valueOf(lng));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(float f) {
|
||||
append(String.valueOf(f));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment append(double d) {
|
||||
append(String.valueOf(d));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledFragment newLine() {
|
||||
append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -17,21 +17,22 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.Style;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.google.auto.value.AutoAnnotation;
|
||||
import com.sk89q.worldedit.internal.annotation.Radii;
|
||||
|
||||
/**
|
||||
* Represents a fragment representing a label.
|
||||
* Holder for generated annotation classes.
|
||||
*/
|
||||
public class Label extends StyledFragment {
|
||||
class Annotations {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Label() {
|
||||
super(Style.YELLOW);
|
||||
@AutoAnnotation
|
||||
static Radii radii(int value) {
|
||||
return new AutoAnnotation_Annotations_radii(value);
|
||||
}
|
||||
|
||||
private Annotations() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockDistributionResult extends PaginationBox {
|
||||
|
||||
private final List<Countable<BlockState>> distribution;
|
||||
private final int totalBlocks;
|
||||
private final boolean separateStates;
|
||||
|
||||
public BlockDistributionResult(List<Countable<BlockState>> distribution, boolean separateStates) {
|
||||
super("Block Distribution", "//distr -p %page%" + (separateStates ? " -d" : ""));
|
||||
this.distribution = distribution;
|
||||
// note: doing things like region.getArea is inaccurate for non-cuboids.
|
||||
this.totalBlocks = distribution.stream().mapToInt(Countable::getAmount).sum();
|
||||
this.separateStates = separateStates;
|
||||
setComponentsPerPage(7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
Countable<BlockState> c = distribution.get(number);
|
||||
TextComponent.Builder line = TextComponent.builder();
|
||||
|
||||
final int count = c.getAmount();
|
||||
|
||||
final double perc = count / (double) totalBlocks * 100;
|
||||
final int maxDigits = (int) (Math.log10(totalBlocks) + 1);
|
||||
final int curDigits = (int) (Math.log10(count) + 1);
|
||||
line.append(String.format("%s%.3f%% ", perc < 10 ? " " : "", perc), TextColor.GOLD);
|
||||
final int space = maxDigits - curDigits;
|
||||
String pad = Strings.repeat(" ", space == 0 ? 2 : 2 * space + 1);
|
||||
line.append(String.format("%s%s", count, pad), TextColor.YELLOW);
|
||||
|
||||
final BlockState state = c.getID();
|
||||
final BlockType blockType = state.getBlockType();
|
||||
TextComponent blockName = TextComponent.of(blockType.getName(), TextColor.LIGHT_PURPLE);
|
||||
TextComponent toolTip;
|
||||
if (separateStates && state != blockType.getDefaultState()) {
|
||||
toolTip = TextComponent.of(state.getAsString(), TextColor.GRAY);
|
||||
blockName = blockName.append(TextComponent.of("*", TextColor.LIGHT_PURPLE));
|
||||
} else {
|
||||
toolTip = TextComponent.of(blockType.getId(), TextColor.GRAY);
|
||||
}
|
||||
blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip));
|
||||
line.append(blockName);
|
||||
|
||||
return line.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return distribution.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component create(int page) throws InvalidComponentException {
|
||||
super.getContents().append(TextComponent.of("Total Block Count: " + totalBlocks, TextColor.GRAY))
|
||||
.append(TextComponent.newline());
|
||||
return super.create(page);
|
||||
}
|
||||
}
|
@ -19,19 +19,30 @@
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.Style;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
/**
|
||||
* Represents a fragment representing a command that is to be typed.
|
||||
*/
|
||||
public class Code extends StyledFragment {
|
||||
public class CodeFormat extends TextComponentProducer {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Code() {
|
||||
super(Style.CYAN);
|
||||
private CodeFormat() {
|
||||
getBuilder().content("").color(TextColor.AQUA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CodeFormat with the given message.
|
||||
*
|
||||
* @param texts The text
|
||||
* @return The Component
|
||||
*/
|
||||
public static TextComponent wrap(String ... texts) {
|
||||
CodeFormat code = new CodeFormat();
|
||||
for (String text: texts) {
|
||||
code.append(text);
|
||||
}
|
||||
|
||||
return code.create();
|
||||
}
|
||||
}
|
@ -19,32 +19,86 @@
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
public class CommandListBox extends MessageBox {
|
||||
import java.util.List;
|
||||
|
||||
private boolean first = true;
|
||||
public class CommandListBox extends PaginationBox {
|
||||
|
||||
private List<CommandEntry> commands = Lists.newArrayList();
|
||||
private boolean hideHelp;
|
||||
|
||||
/**
|
||||
* Create a new box.
|
||||
*
|
||||
* @param title the title
|
||||
*/
|
||||
public CommandListBox(String title) {
|
||||
super(title);
|
||||
public CommandListBox(String title, String pageCommand) {
|
||||
super(title, pageCommand);
|
||||
}
|
||||
|
||||
public CommandListBox appendCommand(String alias, String description) {
|
||||
return appendCommand(alias, description, true);
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
return commands.get(number).createComponent(hideHelp);
|
||||
}
|
||||
|
||||
CommandListBox appendCommand(String alias, String description, boolean allowed) {
|
||||
if (!first) {
|
||||
getContents().newLine();
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return commands.size();
|
||||
}
|
||||
|
||||
public void appendCommand(String alias, Component description) {
|
||||
appendCommand(alias, description, null);
|
||||
}
|
||||
|
||||
public void appendCommand(String alias, String description, String insertion) {
|
||||
appendCommand(alias, TextComponent.of(description), insertion);
|
||||
}
|
||||
|
||||
public void appendCommand(String alias, Component description, String insertion) {
|
||||
commands.add(new CommandEntry(alias, description, insertion));
|
||||
}
|
||||
|
||||
public boolean isHidingHelp() {
|
||||
return hideHelp;
|
||||
}
|
||||
|
||||
public void setHidingHelp(boolean hideHelp) {
|
||||
this.hideHelp = hideHelp;
|
||||
}
|
||||
|
||||
private static class CommandEntry {
|
||||
private final String alias;
|
||||
private final Component description;
|
||||
private final String insertion;
|
||||
|
||||
CommandEntry(String alias, Component description, String insertion) {
|
||||
this.alias = alias;
|
||||
this.description = description;
|
||||
this.insertion = insertion;
|
||||
}
|
||||
getContents().append((allowed ? BBC.HELP_ITEM_ALLOWED : BBC.HELP_ITEM_DENIED).format(alias, description));
|
||||
first = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
Component createComponent(boolean hideHelp) {
|
||||
TextComponentProducer line = new TextComponentProducer();
|
||||
if (!hideHelp) {
|
||||
line.append(SubtleFormat.wrap("? ")
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "//help " + insertion))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Additional Help"))));
|
||||
}
|
||||
TextComponent command = TextComponent.of(alias, TextColor.GOLD);
|
||||
if (insertion == null) {
|
||||
line.append(command);
|
||||
} else {
|
||||
line.append(command
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, insertion))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to select"))));
|
||||
}
|
||||
return line.append(TextComponent.of(": ")).append(description).create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,90 +19,69 @@
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
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.Description;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
import org.enginehub.piston.ColorConfig;
|
||||
import org.enginehub.piston.Command;
|
||||
import org.enginehub.piston.CommandParameters;
|
||||
import org.enginehub.piston.util.HelpGenerator;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldedit.internal.command.CommandUtil.getSubCommands;
|
||||
|
||||
/**
|
||||
* A box to describe usage of a command.
|
||||
*/
|
||||
public class CommandUsageBox extends StyledFragment {
|
||||
public class CommandUsageBox extends TextComponentProducer {
|
||||
|
||||
/**
|
||||
* Create a new usage box.
|
||||
*
|
||||
* @param command the command to describe
|
||||
* @param commandString the command that was used, such as "/we" or "/brush sphere"
|
||||
* @param commands the commands to describe
|
||||
* @param commandString the commands that were used, such as "/we" or "/brush sphere"
|
||||
*/
|
||||
public CommandUsageBox(CommandCallable command, String commandString) {
|
||||
this(command, commandString, null);
|
||||
public CommandUsageBox(List<Command> commands, String commandString) throws InvalidComponentException {
|
||||
this(commands, commandString, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new usage box.
|
||||
*
|
||||
* @param command the command to describe
|
||||
* @param commandString the command that was used, such as "/we" or "/brush sphere"
|
||||
* @param locals list of locals to use
|
||||
* @param commands the commands to describe
|
||||
* @param commandString the commands that were used, such as "/we" or "/brush sphere"
|
||||
* @param parameters list of parameters to use
|
||||
*/
|
||||
public CommandUsageBox(CommandCallable command, String commandString, @Nullable CommandLocals locals) {
|
||||
checkNotNull(command);
|
||||
public CommandUsageBox(List<Command> commands, String commandString, @Nullable CommandParameters parameters) throws InvalidComponentException {
|
||||
checkNotNull(commands);
|
||||
checkNotNull(commandString);
|
||||
if (command instanceof Dispatcher) {
|
||||
attachDispatcherUsage((Dispatcher) command, commandString, locals);
|
||||
} else {
|
||||
attachCommandUsage(command.getDescription(), commandString);
|
||||
}
|
||||
attachCommandUsage(commands, commandString);
|
||||
}
|
||||
|
||||
private void attachDispatcherUsage(Dispatcher dispatcher, String commandString, @Nullable CommandLocals locals) {
|
||||
CommandListBox box = new CommandListBox(BBC.HELP_HEADER_SUBCOMMANDS.f());
|
||||
String prefix = !commandString.isEmpty() ? commandString + " " : "";
|
||||
|
||||
List<CommandMapping> list = new ArrayList<>(dispatcher.getCommands());
|
||||
list.sort(new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
|
||||
|
||||
for (CommandMapping mapping : list) {
|
||||
boolean perm = locals == null || mapping.getCallable().testPermission(locals);
|
||||
box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getDescription(), perm);
|
||||
private void attachCommandUsage(List<Command> commands, String commandString) {
|
||||
TextComponentProducer boxContent = new TextComponentProducer()
|
||||
.append(HelpGenerator.create(commands).getFullHelp());
|
||||
if (getSubCommands(Iterables.getLast(commands)).size() > 0) {
|
||||
boxContent.append(TextComponent.newline())
|
||||
.append(TextComponent.builder("> ")
|
||||
.color(ColorConfig.getHelpText())
|
||||
.append(TextComponent.builder("List Subcommands")
|
||||
.color(ColorConfig.getMainText())
|
||||
.decoration(TextDecoration.ITALIC, true)
|
||||
.clickEvent(ClickEvent.runCommand("//help -s " + commandString))
|
||||
.hoverEvent(HoverEvent.showText(TextComponent.of("List all subcommands of this command")))
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
MessageBox box = new MessageBox("Help for " + commandString,
|
||||
boxContent);
|
||||
|
||||
append(box);
|
||||
}
|
||||
|
||||
private void attachCommandUsage(Description description, String commandString) {
|
||||
MessageBox box = new MessageBox(BBC.HELP_HEADER_COMMAND.f(commandString));
|
||||
StyledFragment contents = box.getContents();
|
||||
|
||||
if (description.getUsage() != null) {
|
||||
contents.append(new Label().append(BBC.COMMAND_SYNTAX.f(description.getUsage())));
|
||||
} else {
|
||||
contents.append(new Subtle().append("Usage information is not available."));
|
||||
}
|
||||
|
||||
contents.newLine();
|
||||
|
||||
if (description.getHelp() != null) {
|
||||
contents.append(description.getHelp());
|
||||
} else if (description.getDescription() != null) {
|
||||
contents.append(description.getDescription());
|
||||
} else {
|
||||
contents.append(new Subtle().append("No further help is available."));
|
||||
}
|
||||
|
||||
append(box);
|
||||
append(box.create());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
/**
|
||||
* Represents a fragment representing an error.
|
||||
*/
|
||||
public class ErrorFormat extends TextComponentProducer {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
private ErrorFormat() {
|
||||
getBuilder().content("").color(TextColor.RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ErrorFormat with the given message.
|
||||
*
|
||||
* @param texts The text
|
||||
* @return The Component
|
||||
*/
|
||||
public static TextComponent wrap(String ... texts) {
|
||||
ErrorFormat error = new ErrorFormat();
|
||||
for (String component : texts) {
|
||||
error.append(component);
|
||||
}
|
||||
|
||||
return error.create();
|
||||
}
|
||||
}
|
@ -19,19 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.Style;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
/**
|
||||
* Represents a subtle part of the message.
|
||||
*/
|
||||
public class Subtle extends StyledFragment {
|
||||
public class InvalidComponentException extends WorldEditException {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Subtle() {
|
||||
super(Style.GRAY);
|
||||
public InvalidComponentException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
/**
|
||||
* Represents a fragment representing a label.
|
||||
*/
|
||||
public class LabelFormat extends TextComponentProducer {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
private LabelFormat() {
|
||||
getBuilder().content("").color(TextColor.YELLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LabelFormat with the given message.
|
||||
*
|
||||
* @param texts The text
|
||||
* @return The Component
|
||||
*/
|
||||
public static TextComponent wrap(String ... texts) {
|
||||
LabelFormat label = new LabelFormat();
|
||||
for (String component : texts) {
|
||||
label.append(component);
|
||||
}
|
||||
|
||||
return label.create();
|
||||
}
|
||||
}
|
@ -19,43 +19,76 @@
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
|
||||
|
||||
/**
|
||||
* Makes for a box with a border above and below.
|
||||
*/
|
||||
public class MessageBox extends StyledFragment {
|
||||
public class MessageBox extends TextComponentProducer {
|
||||
|
||||
private final StyledFragment contents = new StyledFragment();
|
||||
private static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47;
|
||||
|
||||
private TextComponentProducer contents;
|
||||
|
||||
/**
|
||||
* Create a new box.
|
||||
*/
|
||||
public MessageBox(String title) {
|
||||
public MessageBox(String title, TextComponentProducer contents) {
|
||||
checkNotNull(title);
|
||||
append(title);
|
||||
newLine();
|
||||
append(contents);
|
||||
|
||||
append(centerAndBorder(TextComponent.of(title))).newline();
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
private String createBorder(int count) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < count; i++) {
|
||||
builder.append("-");
|
||||
protected Component centerAndBorder(TextComponent text) {
|
||||
TextComponentProducer line = new TextComponentProducer();
|
||||
int leftOver = GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - getLength(text);
|
||||
int side = (int) Math.floor(leftOver / 2.0);
|
||||
if (side > 0) {
|
||||
if (side > 1) {
|
||||
line.append(createBorder(side - 1));
|
||||
}
|
||||
line.append(TextComponent.space());
|
||||
}
|
||||
return builder.toString();
|
||||
line.append(text);
|
||||
if (side > 0) {
|
||||
line.append(TextComponent.space());
|
||||
if (side > 1) {
|
||||
line.append(createBorder(side - 1));
|
||||
}
|
||||
}
|
||||
return line.create();
|
||||
}
|
||||
|
||||
private static int getLength(TextComponent text) {
|
||||
return text.content().length() + text.children().stream().filter(c -> c instanceof TextComponent)
|
||||
.mapToInt(c -> getLength((TextComponent) c)).sum();
|
||||
}
|
||||
|
||||
private TextComponent createBorder(int count) {
|
||||
return TextComponent.of(Strings.repeat("-", count),
|
||||
TextColor.YELLOW, Sets.newHashSet(TextDecoration.STRIKETHROUGH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal contents.
|
||||
* Gets the message box contents producer.
|
||||
*
|
||||
* @return the contents
|
||||
* @return The contents producer
|
||||
*/
|
||||
public StyledFragment getContents() {
|
||||
public TextComponentProducer getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextComponent create() {
|
||||
append(contents.create());
|
||||
return super.create();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PaginationBox extends MessageBox {
|
||||
|
||||
private static final int IDEAL_ROWS_FOR_PLAYER = 8;
|
||||
|
||||
private String pageCommand;
|
||||
private int componentsPerPage = IDEAL_ROWS_FOR_PLAYER;
|
||||
private int currentPage = -1;
|
||||
|
||||
/**
|
||||
* Creates a Paginated component
|
||||
*
|
||||
* @param title The title
|
||||
*/
|
||||
protected PaginationBox(String title) {
|
||||
this(title, null);
|
||||
}
|
||||
|
||||
public abstract Component getComponent(int number);
|
||||
|
||||
public abstract int getComponentsSize();
|
||||
|
||||
public void setComponentsPerPage(int componentsPerPage) {
|
||||
this.componentsPerPage = componentsPerPage;
|
||||
}
|
||||
|
||||
public void formatForConsole() {
|
||||
this.pageCommand = null;
|
||||
this.componentsPerPage = 20;
|
||||
}
|
||||
|
||||
protected final int getCurrentPage() {
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Paginated component
|
||||
*
|
||||
* @param title The title
|
||||
* @param pageCommand The command to run to switch page, with %page% representing page number
|
||||
*/
|
||||
protected PaginationBox(String title, @Nullable String pageCommand) {
|
||||
super(title, new TextComponentProducer());
|
||||
|
||||
if (pageCommand != null && !pageCommand.contains("%page%")) {
|
||||
throw new IllegalArgumentException("pageCommand must contain %page% if provided.");
|
||||
}
|
||||
this.pageCommand = pageCommand;
|
||||
}
|
||||
|
||||
public Component create(int page) throws InvalidComponentException {
|
||||
if (page == 1 && getComponentsSize() == 0) {
|
||||
return getContents().reset().append("No results found.").create();
|
||||
}
|
||||
int pageCount = (int) Math.ceil(getComponentsSize() / (double) componentsPerPage);
|
||||
if (page < 1 || page > pageCount) {
|
||||
throw new InvalidComponentException("Invalid page number.");
|
||||
}
|
||||
currentPage = page;
|
||||
final int lastComp = Math.min(page * componentsPerPage, getComponentsSize());
|
||||
for (int i = (page - 1) * componentsPerPage; i < lastComp; i++) {
|
||||
getContents().append(getComponent(i));
|
||||
if (i + 1 != lastComp) {
|
||||
getContents().newline();
|
||||
}
|
||||
}
|
||||
if (pageCount == 1) {
|
||||
return super.create();
|
||||
}
|
||||
getContents().newline();
|
||||
TextComponent pageNumberComponent = TextComponent.of("Page ", TextColor.YELLOW)
|
||||
.append(TextComponent.of(String.valueOf(page), TextColor.GOLD))
|
||||
.append(TextComponent.of(" of "))
|
||||
.append(TextComponent.of(String.valueOf(pageCount), TextColor.GOLD));
|
||||
if (pageCommand != null) {
|
||||
TextComponentProducer navProducer = new TextComponentProducer();
|
||||
if (page > 1) {
|
||||
TextComponent prevComponent = TextComponent.of("<<< ", TextColor.GOLD)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, pageCommand.replace("%page%", String.valueOf(page - 1))))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to navigate")));
|
||||
navProducer.append(prevComponent);
|
||||
}
|
||||
navProducer.append(pageNumberComponent);
|
||||
if (page < pageCount) {
|
||||
TextComponent nextComponent = TextComponent.of(" >>>", TextColor.GOLD)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, pageCommand.replace("%page%", String.valueOf(page + 1))))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to navigate")));
|
||||
navProducer.append(nextComponent);
|
||||
}
|
||||
getContents().append(centerAndBorder(navProducer.create()));
|
||||
} else {
|
||||
getContents().append(centerAndBorder(pageNumberComponent));
|
||||
}
|
||||
return super.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextComponent create() {
|
||||
throw new IllegalStateException("Pagination components must be created with a page");
|
||||
}
|
||||
|
||||
public static PaginationBox fromStrings(String header, @Nullable String pageCommand, List<String> lines) {
|
||||
return new ListPaginationBox(header, pageCommand, lines);
|
||||
}
|
||||
|
||||
private static class ListPaginationBox extends PaginationBox {
|
||||
private final List<String> lines;
|
||||
|
||||
ListPaginationBox(String header, String pageCommand, List<String> lines) {
|
||||
super(header, pageCommand);
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
return TextComponent.of(lines.get(number));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return lines.size();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.Files;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SchematicPaginationBox extends PaginationBox {
|
||||
private final String prefix;
|
||||
private final File[] files;
|
||||
|
||||
public SchematicPaginationBox(String rootDir, File[] files, String pageCommand) {
|
||||
super("Available schematics", pageCommand);
|
||||
this.prefix = rootDir == null ? "" : rootDir;
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
checkArgument(number < files.length && number >= 0);
|
||||
File file = files[number];
|
||||
Multimap<String, ClipboardFormat> exts = ClipboardFormats.getFileExtensionMap();
|
||||
String format = exts.get(Files.getFileExtension(file.getName()))
|
||||
.stream().findFirst().map(ClipboardFormat::getName).orElse("Unknown");
|
||||
boolean inRoot = file.getParentFile().getName().equals(prefix);
|
||||
|
||||
String path = inRoot ? file.getName() : file.getPath().split(Pattern.quote(prefix + File.separator))[1];
|
||||
|
||||
return TextComponent.builder()
|
||||
.content("")
|
||||
.append(TextComponent.of("[L]")
|
||||
.color(TextColor.GOLD)
|
||||
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/schem load " + path))
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to load"))))
|
||||
.append(TextComponent.space())
|
||||
.append(TextComponent.of(path)
|
||||
.color(TextColor.DARK_GREEN)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(format))))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return files.length;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
/**
|
||||
* Represents a subtle part of the message.
|
||||
*/
|
||||
public class SubtleFormat extends TextComponentProducer {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
private SubtleFormat() {
|
||||
getBuilder().content("").color(TextColor.GRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SubtleFormat with the given message.
|
||||
*
|
||||
* @param texts The text
|
||||
* @return The Component
|
||||
*/
|
||||
public static TextComponent wrap(String ... texts) {
|
||||
SubtleFormat subtle = new SubtleFormat();
|
||||
for (String component : texts) {
|
||||
subtle.append(component);
|
||||
}
|
||||
|
||||
return subtle.create();
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
|
||||
public class TextComponentProducer {
|
||||
|
||||
private TextComponent.Builder builder = TextComponent.builder().content("");
|
||||
|
||||
public TextComponent.Builder getBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a component as a child to this Producer.
|
||||
*
|
||||
* @param component The component
|
||||
* @return The producer, for chaining
|
||||
*/
|
||||
public TextComponentProducer append(Component component) {
|
||||
getBuilder().append(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a string as a child to this Producer.
|
||||
*
|
||||
* @param string The text
|
||||
* @return The producer, for chaining
|
||||
*/
|
||||
public TextComponentProducer append(String string) {
|
||||
getBuilder().append(TextComponent.of(string));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a newline as a child to this Producer.
|
||||
*
|
||||
* @return The producer, for chaining
|
||||
*/
|
||||
public TextComponentProducer newline() {
|
||||
getBuilder().append(TextComponent.newline());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TextComponent from this producer.
|
||||
*
|
||||
* @return The component
|
||||
*/
|
||||
public TextComponent create() {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the producer to a clean slate.
|
||||
*
|
||||
* @return The producer, for chaining
|
||||
*/
|
||||
public TextComponentProducer reset() {
|
||||
builder = TextComponent.builder().content("");
|
||||
return this;
|
||||
}
|
||||
}
|
@ -17,18 +17,27 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
package com.sk89q.worldedit.util.io;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Denotes a match of an exception.
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExceptionMatch {
|
||||
public class ResourceLoader {
|
||||
|
||||
private ResourceLoader() {
|
||||
}
|
||||
|
||||
public static URL getResource(Class clazz, String name) throws IOException {
|
||||
URL url = clazz.getResource(name);
|
||||
if (url == null) {
|
||||
try {
|
||||
return new URL("modjar://worldedit/" + clazz.getName().substring(0, clazz.getName().lastIndexOf('.')).replace(".", "/") + "/"
|
||||
+ name);
|
||||
} catch (Exception e) {
|
||||
// Not forge.
|
||||
}
|
||||
throw new IOException("Could not find " + name);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
@ -19,21 +19,16 @@
|
||||
|
||||
package com.sk89q.worldedit.util.paste;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.worldedit.command.util.AsyncCommandHelper;
|
||||
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
|
||||
import com.sk89q.worldedit.util.task.Supervisor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class ActorCallbackPaste {
|
||||
public final class ActorCallbackPaste {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ActorCallbackPaste.class);
|
||||
private static final Paster paster = new IncendoPaste("fastasyncworldedit");
|
||||
|
||||
private ActorCallbackPaste() {
|
||||
}
|
||||
@ -47,25 +42,15 @@ public class ActorCallbackPaste {
|
||||
* @param content The content
|
||||
* @param successMessage The message, formatted with {@link String#format(String, Object...)} on success
|
||||
*/
|
||||
public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage, final ExceptionConverter exceptionConverter) {
|
||||
ListenableFuture<URL> future = new IncendoPaste("fastasyncworldedit").paste(content);
|
||||
public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage) {
|
||||
Callable<URL> task = paster.paste(content);
|
||||
|
||||
AsyncCommandHelper.wrap(future, supervisor, sender, exceptionConverter)
|
||||
.registerWithSupervisor("Submitting content to a pastebin service...")
|
||||
.sendMessageAfterDelay("(Please wait... sending output to pastebin...)");
|
||||
|
||||
Futures.addCallback(future, new FutureCallback<URL>() {
|
||||
@Override
|
||||
public void onSuccess(URL url) {
|
||||
sender.print(String.format(successMessage, url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable throwable) {
|
||||
LOGGER.warn("Failed to submit pastebin", throwable);
|
||||
sender.printError("Failed to submit to a pastebin. Please see console for the error.");
|
||||
}
|
||||
});
|
||||
AsyncCommandBuilder.wrap(task, sender)
|
||||
.registerWithSupervisor(supervisor, "Submitting content to a pastebin service.")
|
||||
.sendMessageAfterDelay("(Please wait... sending output to pastebin...)")
|
||||
.onSuccess((String) null, url -> sender.print(String.format(successMessage, url)))
|
||||
.onFailure("Failed to submit paste", null)
|
||||
.buildAndExec(Pasters.getExecutor());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.paste;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.worldedit.util.net.HttpRequest;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
@ -35,8 +34,8 @@ public class EngineHubPaste implements Paster {
|
||||
private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$");
|
||||
|
||||
@Override
|
||||
public ListenableFuture<URL> paste(String content) {
|
||||
return Pasters.getExecutor().submit(new PasteTask(content));
|
||||
public Callable<URL> paste(String content) {
|
||||
return new PasteTask(content);
|
||||
}
|
||||
|
||||
private static final class PasteTask implements Callable<URL> {
|
||||
|
@ -2,7 +2,6 @@ package com.sk89q.worldedit.util.paste;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
@ -13,6 +12,7 @@ import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Single class paster for the Incendo paste service
|
||||
@ -53,19 +53,19 @@ public final class IncendoPaste implements Paster{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<URL> paste(String content) {
|
||||
return Pasters.getExecutor().submit(new PasteTask(content));
|
||||
public Callable<URL> paste(String content) {
|
||||
return new PasteTask(content);
|
||||
}
|
||||
|
||||
|
||||
private final class PasteTask implements Callable<URL>{
|
||||
|
||||
private PasteTask(String content) {}
|
||||
|
||||
|
||||
@Override
|
||||
public URL call() throws Exception {
|
||||
return new URL(debugPaste());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,14 +150,11 @@ public final class IncendoPaste implements Paster{
|
||||
throw new IllegalStateException(String.format("Server returned status: %d %s",
|
||||
httpURLConnection.getResponseCode(), httpURLConnection.getResponseMessage()));
|
||||
}
|
||||
final StringBuilder input = new StringBuilder();
|
||||
final String input;
|
||||
try (final BufferedReader inputStream = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = inputStream.readLine()) != null) {
|
||||
input.append(line).append("\n");
|
||||
}
|
||||
input = inputStream.lines().map(line -> line + "\n").collect(Collectors.joining());
|
||||
}
|
||||
return input.toString();
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,12 +262,9 @@ public final class IncendoPaste implements Paster{
|
||||
|
||||
private static String readFile(final File file) throws IOException {
|
||||
final StringBuilder content = new StringBuilder();
|
||||
final List<String> lines = new ArrayList<>();
|
||||
final List<String> lines;
|
||||
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
lines = reader.lines().collect(Collectors.toList());
|
||||
}
|
||||
for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) {
|
||||
content.append(lines.get(i)).append("\n");
|
||||
@ -278,4 +272,4 @@ public final class IncendoPaste implements Paster{
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.paste;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.worldedit.util.net.HttpRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -43,12 +42,12 @@ public class Pastebin implements Paster {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<URL> paste(String content) {
|
||||
public Callable<URL> paste(String content) {
|
||||
if (mungingLinks) {
|
||||
content = content.replaceAll("http://", "http_//");
|
||||
}
|
||||
|
||||
return Pasters.getExecutor().submit(new PasteTask(content));
|
||||
return new PasteTask(content);
|
||||
}
|
||||
|
||||
private final class PasteTask implements Callable<URL> {
|
||||
@ -89,5 +88,5 @@ public class Pastebin implements Paster {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -19,12 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.util.paste;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface Paster {
|
||||
|
||||
ListenableFuture<URL> paste(String content);
|
||||
Callable<URL> paste(String content);
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user