Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-03 01:50:07 +01:00
Add AsyncCommandBuilder as replacement for AsyncCommandHelper.
See full explanation at https://github.com/EngineHub/WorldGuard/pull/408
Dieser Commit ist enthalten in:
Ursprung
aed25fce7c
Commit
fab21c3eea
@ -67,7 +67,7 @@ public class WorldEditCommands {
|
|||||||
aliases = { "ver" },
|
aliases = { "ver" },
|
||||||
desc = "Get WorldEdit version"
|
desc = "Get WorldEdit version"
|
||||||
)
|
)
|
||||||
public void version(Actor actor) throws WorldEditException {
|
public void version(Actor actor) {
|
||||||
actor.print("WorldEdit version " + WorldEdit.getVersion());
|
actor.print("WorldEdit version " + WorldEdit.getVersion());
|
||||||
actor.print("https://github.com/EngineHub/worldedit/");
|
actor.print("https://github.com/EngineHub/worldedit/");
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ public class WorldEditCommands {
|
|||||||
desc = "Reload configuration"
|
desc = "Reload configuration"
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.reload")
|
@CommandPermissions("worldedit.reload")
|
||||||
public void reload(Actor actor) throws WorldEditException {
|
public void reload(Actor actor) {
|
||||||
we.getPlatformManager().queryCapability(Capability.CONFIGURATION).reload();
|
we.getPlatformManager().queryCapability(Capability.CONFIGURATION).reload();
|
||||||
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
|
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
|
||||||
actor.print("Configuration reloaded!");
|
actor.print("Configuration reloaded!");
|
||||||
@ -100,7 +100,7 @@ public class WorldEditCommands {
|
|||||||
name = "report",
|
name = "report",
|
||||||
desc = "Writes a report on WorldEdit"
|
desc = "Writes a report on WorldEdit"
|
||||||
)
|
)
|
||||||
@CommandPermissions({"worldedit.report"})
|
@CommandPermissions("worldedit.report")
|
||||||
public void report(Actor actor,
|
public void report(Actor actor,
|
||||||
@Switch(name = 'p', desc = "Pastebins the report")
|
@Switch(name = 'p', desc = "Pastebins the report")
|
||||||
boolean pastebin) throws WorldEditException {
|
boolean pastebin) throws WorldEditException {
|
||||||
@ -119,10 +119,7 @@ public class WorldEditCommands {
|
|||||||
|
|
||||||
if (pastebin) {
|
if (pastebin) {
|
||||||
actor.checkPermission("worldedit.report.pastebin");
|
actor.checkPermission("worldedit.report.pastebin");
|
||||||
ActorCallbackPaste.pastebin(
|
ActorCallbackPaste.pastebin(we.getSupervisor(), actor, result, "WorldEdit report: %s.report");
|
||||||
we.getSupervisor(), actor, result, "WorldEdit report: %s.report",
|
|
||||||
WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getExceptionConverter()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +127,7 @@ public class WorldEditCommands {
|
|||||||
name = "cui",
|
name = "cui",
|
||||||
desc = "Complete CUI handshake (internal usage)"
|
desc = "Complete CUI handshake (internal usage)"
|
||||||
)
|
)
|
||||||
public void cui(Player player, LocalSession session) throws WorldEditException {
|
public void cui(Player player, LocalSession session) {
|
||||||
session.setCUISupport(true);
|
session.setCUISupport(true);
|
||||||
session.dispatchCUISetup(player);
|
session.dispatchCUISetup(player);
|
||||||
}
|
}
|
||||||
@ -141,7 +138,7 @@ public class WorldEditCommands {
|
|||||||
)
|
)
|
||||||
public void tz(Player player, LocalSession session,
|
public void tz(Player player, LocalSession session,
|
||||||
@Arg(desc = "The timezone to set")
|
@Arg(desc = "The timezone to set")
|
||||||
String timezone) throws WorldEditException {
|
String timezone) {
|
||||||
try {
|
try {
|
||||||
ZoneId tz = ZoneId.of(timezone);
|
ZoneId tz = ZoneId.of(timezone);
|
||||||
session.setTimezone(tz);
|
session.setTimezone(tz);
|
||||||
|
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* 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.command.util;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
|
||||||
|
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||||
|
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.task.FutureForwardingTask;
|
||||||
|
import com.sk89q.worldedit.util.task.Supervisor;
|
||||||
|
import org.enginehub.piston.exception.CommandException;
|
||||||
|
import org.enginehub.piston.exception.CommandExecutionException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public final class AsyncCommandBuilder<T> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(AsyncCommandBuilder.class);
|
||||||
|
|
||||||
|
private final Callable<T> callable;
|
||||||
|
private final Actor sender;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Supervisor supervisor;
|
||||||
|
@Nullable
|
||||||
|
private String description;
|
||||||
|
@Nullable
|
||||||
|
private String delayMessage;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Component successMessage;
|
||||||
|
@Nullable
|
||||||
|
private Consumer<T> consumer;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Component failureMessage;
|
||||||
|
@Nullable
|
||||||
|
private ExceptionConverter exceptionConverter;
|
||||||
|
|
||||||
|
private AsyncCommandBuilder(Callable<T> callable, Actor sender) {
|
||||||
|
checkNotNull(callable);
|
||||||
|
checkNotNull(sender);
|
||||||
|
this.callable = callable;
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> AsyncCommandBuilder<T> wrap(Callable<T> callable, Actor sender) {
|
||||||
|
return new AsyncCommandBuilder<>(callable, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> registerWithSupervisor(Supervisor supervisor, String description) {
|
||||||
|
this.supervisor = checkNotNull(supervisor);
|
||||||
|
this.description = checkNotNull(description);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> sendMessageAfterDelay(String message) {
|
||||||
|
this.delayMessage = checkNotNull(message);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> onSuccess(@Nullable Component message, @Nullable Consumer<T> consumer) {
|
||||||
|
checkArgument(message != null || consumer != null, "Can't have null message AND consumer");
|
||||||
|
this.successMessage = message;
|
||||||
|
this.consumer = consumer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> onSuccess(@Nullable String message, @Nullable Consumer<T> consumer) {
|
||||||
|
checkArgument(message != null || consumer != null, "Can't have null message AND consumer");
|
||||||
|
this.successMessage = message == null ? null : TextComponent.of(message, TextColor.LIGHT_PURPLE);
|
||||||
|
this.consumer = consumer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> onFailure(@Nullable Component message, @Nullable ExceptionConverter exceptionConverter) {
|
||||||
|
checkArgument(message != null || exceptionConverter != null, "Can't have null message AND exceptionConverter");
|
||||||
|
this.failureMessage = message;
|
||||||
|
this.exceptionConverter = exceptionConverter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCommandBuilder<T> onFailure(@Nullable String message, @Nullable ExceptionConverter exceptionConverter) {
|
||||||
|
checkArgument(message != null || exceptionConverter != null, "Can't have null message AND exceptionConverter");
|
||||||
|
this.failureMessage = message == null ? null : ErrorFormat.wrap(message);
|
||||||
|
this.exceptionConverter = exceptionConverter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<T> buildAndExec(ListeningExecutorService executor) {
|
||||||
|
final ListenableFuture<T> future = checkNotNull(executor).submit(this::runTask);
|
||||||
|
if (delayMessage != null) {
|
||||||
|
FutureProgressListener.addProgressListener(future, sender, delayMessage);
|
||||||
|
}
|
||||||
|
if (supervisor != null && description != null) {
|
||||||
|
supervisor.monitor(FutureForwardingTask.create(future, description, sender));
|
||||||
|
}
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
private T runTask() {
|
||||||
|
T result = null;
|
||||||
|
try {
|
||||||
|
result = callable.call();
|
||||||
|
if (consumer != null) {
|
||||||
|
consumer.accept(result);
|
||||||
|
}
|
||||||
|
if (successMessage != null) {
|
||||||
|
sender.print(successMessage);
|
||||||
|
}
|
||||||
|
} catch (Exception orig) {
|
||||||
|
Component failure = failureMessage != null ? failureMessage : TextComponent.of("An error occurred");
|
||||||
|
try {
|
||||||
|
if (exceptionConverter != null) {
|
||||||
|
try {
|
||||||
|
exceptionConverter.convert(orig);
|
||||||
|
} catch (CommandException converted) {
|
||||||
|
Component message;
|
||||||
|
|
||||||
|
// TODO remove this once WG migrates to piston and can use piston exceptions everywhere
|
||||||
|
message = tryExtractOldCommandException(converted);
|
||||||
|
|
||||||
|
if (message == null) {
|
||||||
|
if (Strings.isNullOrEmpty(converted.getMessage())) {
|
||||||
|
message = TextComponent.of("Unknown error.");
|
||||||
|
} else {
|
||||||
|
message = converted.getRichMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender.print(failure.append(TextComponent.of(": ")).append(message));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw orig;
|
||||||
|
}
|
||||||
|
} catch (Throwable unknown) {
|
||||||
|
sender.print(failure.append(TextComponent.of(": Unknown error. Please see console.")));
|
||||||
|
logger.error("Uncaught exception occurred in task: " + description, orig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is needed right now since worldguard is still on the 2011 command framework which throws and converts
|
||||||
|
// com.sk89q.minecraft.util.commands.CommandException. the ExceptionConverter currently expects converted
|
||||||
|
// exceptions to be org.enginehub.piston.CommandException, throw it wraps the resulting InvocationTargetException in
|
||||||
|
// a CommandExecutionException. here, we unwrap those layers to retrieve the original WG error message
|
||||||
|
private Component tryExtractOldCommandException(CommandException converted) {
|
||||||
|
Component message = null;
|
||||||
|
if (converted instanceof CommandExecutionException) {
|
||||||
|
Throwable parentCause = converted;
|
||||||
|
while ((parentCause = parentCause.getCause()) != null) {
|
||||||
|
if (parentCause instanceof com.sk89q.minecraft.util.commands.CommandException) {
|
||||||
|
final String msg = parentCause.getMessage();
|
||||||
|
if (!Strings.isNullOrEmpty(msg)) {
|
||||||
|
message = TextComponent.of(msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
@ -1,144 +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.command.util;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
|
||||||
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
|
|
||||||
import com.sk89q.worldedit.util.task.FutureForwardingTask;
|
|
||||||
import com.sk89q.worldedit.util.task.Supervisor;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
|
|
||||||
public class AsyncCommandHelper {
|
|
||||||
|
|
||||||
private final ListenableFuture<?> future;
|
|
||||||
private final Supervisor supervisor;
|
|
||||||
private final Actor sender;
|
|
||||||
private final ExceptionConverter exceptionConverter;
|
|
||||||
@Nullable
|
|
||||||
private Object[] formatArgs;
|
|
||||||
|
|
||||||
private AsyncCommandHelper(ListenableFuture<?> future, Supervisor supervisor, Actor sender, ExceptionConverter exceptionConverter) {
|
|
||||||
checkNotNull(future);
|
|
||||||
checkNotNull(supervisor);
|
|
||||||
checkNotNull(sender);
|
|
||||||
checkNotNull(exceptionConverter);
|
|
||||||
|
|
||||||
this.future = future;
|
|
||||||
this.supervisor = supervisor;
|
|
||||||
this.sender = sender;
|
|
||||||
this.exceptionConverter = exceptionConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper formatUsing(Object... args) {
|
|
||||||
this.formatArgs = args;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String format(String message) {
|
|
||||||
if (formatArgs != null) {
|
|
||||||
return String.format(message, formatArgs);
|
|
||||||
} else {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper registerWithSupervisor(String description) {
|
|
||||||
supervisor.monitor(
|
|
||||||
FutureForwardingTask.create(
|
|
||||||
future, format(description), sender));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper sendMessageAfterDelay(String message) {
|
|
||||||
FutureProgressListener.addProgressListener(future, sender, format(message));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper thenRespondWith(String success, String failure) {
|
|
||||||
// Send a response message
|
|
||||||
Futures.addCallback(
|
|
||||||
future,
|
|
||||||
new MessageFutureCallback.Builder(sender)
|
|
||||||
.exceptionConverter(exceptionConverter)
|
|
||||||
.onSuccess(format(success))
|
|
||||||
.onFailure(format(failure))
|
|
||||||
.build(),
|
|
||||||
ForkJoinPool.commonPool());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper thenTellErrorsOnly(String failure) {
|
|
||||||
// Send a response message
|
|
||||||
Futures.addCallback(
|
|
||||||
future,
|
|
||||||
new MessageFutureCallback.Builder(sender)
|
|
||||||
.exceptionConverter(exceptionConverter)
|
|
||||||
.onFailure(format(failure))
|
|
||||||
.build(),
|
|
||||||
ForkJoinPool.commonPool());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper forRegionDataLoad(World world, boolean silent) {
|
|
||||||
checkNotNull(world);
|
|
||||||
|
|
||||||
formatUsing(world.getName());
|
|
||||||
registerWithSupervisor("Loading region data for '%s'");
|
|
||||||
if (silent) {
|
|
||||||
thenTellErrorsOnly("Failed to load regions '%s'");
|
|
||||||
} else {
|
|
||||||
sendMessageAfterDelay("(Please wait... loading the region data for '%s')");
|
|
||||||
thenRespondWith(
|
|
||||||
"Loaded region data for '%s'",
|
|
||||||
"Failed to load regions '%s'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncCommandHelper forRegionDataSave(World world, boolean silent) {
|
|
||||||
checkNotNull(world);
|
|
||||||
|
|
||||||
formatUsing(world.getName());
|
|
||||||
registerWithSupervisor("Saving region data for '%s'");
|
|
||||||
if (silent) {
|
|
||||||
thenTellErrorsOnly("Failed to save regions '%s'");
|
|
||||||
} else {
|
|
||||||
sendMessageAfterDelay("(Please wait... saving the region data for '%s')");
|
|
||||||
thenRespondWith(
|
|
||||||
"Saved region data for '%s'",
|
|
||||||
"Failed to load regions '%s'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AsyncCommandHelper wrap(ListenableFuture<?> future, Supervisor supervisor, Actor sender, ExceptionConverter exceptionConverter) {
|
|
||||||
return new AsyncCommandHelper(future, supervisor, sender, exceptionConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -19,22 +19,16 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.paste;
|
package com.sk89q.worldedit.util.paste;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||||
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.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
|
|
||||||
import com.sk89q.worldedit.util.task.Supervisor;
|
import com.sk89q.worldedit.util.task.Supervisor;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
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 EngineHubPaste();
|
||||||
|
|
||||||
private ActorCallbackPaste() {
|
private ActorCallbackPaste() {
|
||||||
}
|
}
|
||||||
@ -48,25 +42,15 @@ public class ActorCallbackPaste {
|
|||||||
* @param content The content
|
* @param content The content
|
||||||
* @param successMessage The message, formatted with {@link String#format(String, Object...)} on success
|
* @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) {
|
public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage) {
|
||||||
ListenableFuture<URL> future = new EngineHubPaste().paste(content);
|
Callable<URL> task = paster.paste(content);
|
||||||
|
|
||||||
AsyncCommandHelper.wrap(future, supervisor, sender, exceptionConverter)
|
AsyncCommandBuilder.wrap(task, sender)
|
||||||
.registerWithSupervisor("Submitting content to a pastebin service...")
|
.registerWithSupervisor(supervisor, "Submitting content to a pastebin service.")
|
||||||
.sendMessageAfterDelay("(Please wait... sending output to pastebin...)");
|
.sendMessageAfterDelay("(Please wait... sending output to pastebin...)")
|
||||||
|
.onSuccess((String) null, url -> sender.print(String.format(successMessage, url)))
|
||||||
Futures.addCallback(future, new FutureCallback<URL>() {
|
.onFailure("Failed to submit paste", null)
|
||||||
@Override
|
.buildAndExec(Pasters.getExecutor());
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}, ForkJoinPool.commonPool());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.paste;
|
package com.sk89q.worldedit.util.paste;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.sk89q.worldedit.util.net.HttpRequest;
|
import com.sk89q.worldedit.util.net.HttpRequest;
|
||||||
import org.json.simple.JSONValue;
|
import org.json.simple.JSONValue;
|
||||||
|
|
||||||
@ -35,11 +34,11 @@ public class EngineHubPaste implements Paster {
|
|||||||
private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$");
|
private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<URL> paste(String content) {
|
public Callable<URL> paste(String content) {
|
||||||
return Pasters.getExecutor().submit(new PasteTask(content));
|
return new PasteTask(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class PasteTask implements Callable<URL> {
|
private static final class PasteTask implements Callable<URL> {
|
||||||
private final String content;
|
private final String content;
|
||||||
|
|
||||||
private PasteTask(String content) {
|
private PasteTask(String content) {
|
||||||
@ -50,7 +49,7 @@ public class EngineHubPaste implements Paster {
|
|||||||
public URL call() throws IOException, InterruptedException {
|
public URL call() throws IOException, InterruptedException {
|
||||||
HttpRequest.Form form = HttpRequest.Form.create();
|
HttpRequest.Form form = HttpRequest.Form.create();
|
||||||
form.add("content", content);
|
form.add("content", content);
|
||||||
form.add("from", "worldguard");
|
form.add("from", "enginehub");
|
||||||
|
|
||||||
URL url = HttpRequest.url("http://paste.enginehub.org/paste");
|
URL url = HttpRequest.url("http://paste.enginehub.org/paste");
|
||||||
String result = HttpRequest.post(url)
|
String result = HttpRequest.post(url)
|
||||||
|
@ -1,93 +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.paste;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.sk89q.worldedit.util.net.HttpRequest;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class Pastebin implements Paster {
|
|
||||||
|
|
||||||
private static final Pattern URL_PATTERN = Pattern.compile("https?://pastebin.com/([^/]+)$");
|
|
||||||
|
|
||||||
private boolean mungingLinks = true;
|
|
||||||
|
|
||||||
public boolean isMungingLinks() {
|
|
||||||
return mungingLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMungingLinks(boolean mungingLinks) {
|
|
||||||
this.mungingLinks = mungingLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ListenableFuture<URL> paste(String content) {
|
|
||||||
if (mungingLinks) {
|
|
||||||
content = content.replaceAll("http://", "http_//");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pasters.getExecutor().submit(new PasteTask(content));
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class PasteTask implements Callable<URL> {
|
|
||||||
private final String content;
|
|
||||||
|
|
||||||
private PasteTask(String content) {
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public URL call() throws IOException, InterruptedException {
|
|
||||||
HttpRequest.Form form = HttpRequest.Form.create();
|
|
||||||
form.add("api_option", "paste");
|
|
||||||
form.add("api_dev_key", "4867eae74c6990dbdef07c543cf8f805");
|
|
||||||
form.add("api_paste_code", content);
|
|
||||||
form.add("api_paste_private", "0");
|
|
||||||
form.add("api_paste_name", "");
|
|
||||||
form.add("api_paste_expire_date", "1W");
|
|
||||||
form.add("api_paste_format", "text");
|
|
||||||
form.add("api_user_key", "");
|
|
||||||
|
|
||||||
URL url = HttpRequest.url("http://pastebin.com/api/api_post.php");
|
|
||||||
String result = HttpRequest.post(url)
|
|
||||||
.bodyForm(form)
|
|
||||||
.execute()
|
|
||||||
.expectResponseCode(200)
|
|
||||||
.returnContent()
|
|
||||||
.asString("UTF-8").trim();
|
|
||||||
|
|
||||||
Matcher m = URL_PATTERN.matcher(result);
|
|
||||||
|
|
||||||
if (m.matches()) {
|
|
||||||
return new URL("http://pastebin.com/raw.php?i=" + m.group(1));
|
|
||||||
} else if (result.matches("^https?://.+")) {
|
|
||||||
return new URL(result);
|
|
||||||
} else {
|
|
||||||
throw new IOException("Failed to save paste; instead, got: " + result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -19,12 +19,11 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.paste;
|
package com.sk89q.worldedit.util.paste;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public interface Paster {
|
public interface Paster {
|
||||||
|
|
||||||
ListenableFuture<URL> paste(String content);
|
Callable<URL> paste(String content);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren