Move the pasting system over to WorldEdit, and add a /we report command. Currently only reports system status and the config. Need to add a platform reporter system.

This commit is contained in:
Matthew Miller
2018-12-18 19:28:55 +10:00
committed by IronApollo
parent 54142c8669
commit 45f1de6009
35 changed files with 2395 additions and 17 deletions

View File

@ -28,6 +28,7 @@ import com.boydti.fawe.util.HastebinUtility;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.Updater;
import com.google.common.io.Files;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
@ -40,6 +41,18 @@ import com.sk89q.worldedit.extension.platform.*;
import java.io.IOException;
import java.net.URL;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.util.paste.ActorCallbackPaste;
import com.sk89q.worldedit.util.report.ConfigReport;
import com.sk89q.worldedit.util.report.ReportList;
import com.sk89q.worldedit.util.report.SystemInfoReport;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
@ -189,7 +202,8 @@ public class WorldEditCommands {
)
@CommandPermissions("worldedit.debugpaste")
public void debugpaste(Actor actor) throws WorldEditException, IOException {
BBC.DOWNLOAD_LINK.send(actor, HastebinUtility.debugPaste());
// BBC.DOWNLOAD_LINK.send(actor, HastebinUtility.debugPaste());
ActorCallbackPaste.pastebin(we.getSupervisor(), actor, null, "FastAsyncWorldEdit report: " + BBC.DOWNLOAD_LINK);
}
@Command(
@ -213,6 +227,28 @@ public class WorldEditCommands {
}
}
// @Command(aliases = {"report"}, desc = "Writes a report on WorldEdit", flags = "p", max = 0)
// @CommandPermissions({"worldedit.report"})
// public void report(Actor actor, CommandContext args) throws WorldEditException {
// ReportList report = new ReportList("Report");
// report.add(new SystemInfoReport());
// report.add(new ConfigReport());
// String result = report.toString();
//
// try {
// File dest = new File(we.getWorkingDirectoryFile(we.getConfiguration().saveDir), "report.txt");
// Files.write(result, dest, Charset.forName("UTF-8"));
// actor.print("WorldEdit report written to " + dest.getAbsolutePath());
// } catch (IOException e) {
// actor.printError("Failed to write report: " + e.getMessage());
// }
//
// if (args.hasFlag('p')) {
// actor.checkPermission("worldedit.report.pastebin");
// ActorCallbackPaste.pastebin(we.getSupervisor(), actor, result, "WorldEdit report: %s.report");
// }
// }
@Command(
aliases = {"cui"},
usage = "",

View File

@ -35,7 +35,7 @@ import com.sk89q.worldedit.world.World;
public class ItemUseParser extends SimpleCommand<Contextual<RegionFunction>> {
private final ItemParser itemParser = addParameter(new ItemParser("item", "minecraft:dye:15"));
private final ItemParser itemParser = addParameter(new ItemParser("item", "minecraft:bone_meal"));
@Override
public Contextual<RegionFunction> call(CommandArgs args, CommandLocals locals) throws CommandException {

View File

@ -62,7 +62,7 @@ public class NumberParser implements CommandExecutor<Number> {
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.emptyList();
}
@Override

View File

@ -57,7 +57,7 @@ public class StringParser implements CommandExecutor<String> {
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.emptyList();
}
@Override

View File

@ -0,0 +1,135 @@
/*
* 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.util.task.FutureForwardingTask;
import com.sk89q.worldedit.util.task.Supervisor;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
public class AsyncCommandHelper {
private final ListenableFuture<?> future;
private final Supervisor supervisor;
private final Actor sender;
@Nullable
private Object[] formatArgs;
private AsyncCommandHelper(ListenableFuture<?> future, Supervisor supervisor, Actor sender) {
checkNotNull(future);
checkNotNull(supervisor);
checkNotNull(sender);
this.future = future;
this.supervisor = supervisor;
this.sender = sender;
}
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)
.onSuccess(format(success))
.onFailure(format(failure))
.build());
return this;
}
public AsyncCommandHelper thenTellErrorsOnly(String failure) {
// Send a response message
Futures.addCallback(
future,
new MessageFutureCallback.Builder(sender)
.onFailure(format(failure))
.build());
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) {
return new AsyncCommandHelper(future, supervisor, sender);
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.worldedit.extension.platform.Actor;
import java.util.Timer;
public class FutureProgressListener implements Runnable {
private static final Timer timer = new Timer();
private static final int MESSAGE_DELAY = 1000;
private final MessageTimerTask task;
public FutureProgressListener(Actor sender, String message) {
checkNotNull(sender);
checkNotNull(message);
task = new MessageTimerTask(sender, message);
timer.schedule(task, MESSAGE_DELAY);
}
@Override
public void run() {
task.cancel();
}
public static void addProgressListener(ListenableFuture<?> future, Actor sender, String message) {
future.addListener(new FutureProgressListener(sender, message), MoreExecutors.directExecutor());
}
}

View File

@ -0,0 +1,114 @@
/*
* 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.FutureCallback;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
import javax.annotation.Nullable;
public class MessageFutureCallback<V> implements FutureCallback<V> {
private final ExceptionConverter exceptionConverter;
private final Actor sender;
@Nullable
private final String success;
@Nullable
private final String failure;
private MessageFutureCallback(ExceptionConverter exceptionConverter, Actor sender, @Nullable String success, @Nullable String failure) {
this.exceptionConverter = exceptionConverter;
this.sender = sender;
this.success = success;
this.failure = failure;
}
@Override
public void onSuccess(@Nullable V v) {
if (success != null) {
sender.print(success);
}
}
@Override
public void onFailure(@Nullable Throwable throwable) {
try {
exceptionConverter.convert(throwable);
} catch (CommandException e) {
String failure = this.failure != null ? this.failure : "An error occurred";
String message = e.getMessage() != null ? e.getMessage() : "An unknown error occurred. Please see the console!";
sender.printError(failure + ": " + message);
}
}
public static class Builder {
private final Actor sender;
@Nullable
private String success;
@Nullable
private String failure;
private ExceptionConverter exceptionConverter;
public Builder(Actor sender) {
checkNotNull(sender);
this.sender = sender;
}
public Builder exceptionConverter(ExceptionConverter exceptionConverter) {
this.exceptionConverter = exceptionConverter;
return this;
}
public Builder onSuccess(@Nullable String message) {
this.success = message;
return this;
}
public Builder onFailure(@Nullable String message) {
this.failure = message;
return this;
}
public <V> MessageFutureCallback<V> build() {
checkNotNull(exceptionConverter);
return new MessageFutureCallback<>(exceptionConverter, sender, success, failure);
}
}
public static <V> MessageFutureCallback<V> createRegionLoadCallback(ExceptionConverter exceptionConverter, Actor sender) {
return new Builder(sender)
.exceptionConverter(exceptionConverter)
.onSuccess("Successfully load the region data.")
.build();
}
public static <V> MessageFutureCallback<V> createRegionSaveCallback(ExceptionConverter exceptionConverter, Actor sender) {
return new Builder(sender)
.exceptionConverter(exceptionConverter)
.onSuccess("Successfully saved the region data.")
.build();
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.sk89q.worldedit.extension.platform.Actor;
import java.util.TimerTask;
public class MessageTimerTask extends TimerTask {
private final Actor sender;
private final String message;
MessageTimerTask(Actor sender, String message) {
checkNotNull(sender);
checkNotNull(message);
this.sender = sender;
this.message = message;
}
@Override
public void run() {
sender.printDebug(message);
}
}