mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
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:
parent
8f236afae9
commit
5eb9b779d7
@ -14,6 +14,7 @@
|
||||
<allow pkg="gnu.trove"/>
|
||||
<allow pkg="com.google.gson"/>
|
||||
<allow pkg="net.royawesome.jlibnoise"/>
|
||||
<allow pkg="org.json.simple" />
|
||||
|
||||
<subpackage name="util.yaml">
|
||||
<allow pkg="org.yaml.snakeyaml"/>
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.bukkit;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.util.YAMLConfiguration;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -30,7 +31,7 @@ import java.io.File;
|
||||
public class BukkitConfiguration extends YAMLConfiguration {
|
||||
|
||||
public boolean noOpPermissions = false;
|
||||
private final WorldEditPlugin plugin;
|
||||
@Unreported private final WorldEditPlugin plugin;
|
||||
|
||||
public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
|
||||
super(config, plugin.getLogger());
|
||||
|
@ -11,6 +11,7 @@ dependencies {
|
||||
compile 'com.thoughtworks.paranamer:paranamer:2.6'
|
||||
compile 'com.google.code.gson:gson:2.8.0'
|
||||
compile 'com.sk89q.lib:jlibnoise:1.0.0'
|
||||
compile 'com.googlecode.json-simple:json-simple:1.1.1'
|
||||
//compile 'net.sf.trove4j:trove4j:3.0.3'
|
||||
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ import com.sk89q.worldedit.util.io.file.FilenameException;
|
||||
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
|
||||
import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
|
||||
import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler;
|
||||
import com.sk89q.worldedit.util.task.SimpleSupervisor;
|
||||
import com.sk89q.worldedit.util.task.Supervisor;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
@ -99,6 +101,7 @@ public class WorldEdit {
|
||||
private final PlatformManager platformManager = new PlatformManager(this);
|
||||
private final EditSessionFactory editSessionFactory = new EditSessionFactory.EditSessionFactoryImpl(eventBus);
|
||||
private final SessionManager sessions = new SessionManager(this);
|
||||
private final Supervisor supervisor = new SimpleSupervisor();
|
||||
|
||||
private final BlockFactory blockFactory = new BlockFactory(this);
|
||||
private final ItemFactory itemFactory = new ItemFactory(this);
|
||||
@ -148,6 +151,15 @@ public class WorldEdit {
|
||||
return eventBus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the supervisor.
|
||||
*
|
||||
* @return the supervisor
|
||||
*/
|
||||
public Supervisor getSupervisor() {
|
||||
return supervisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block factory from which new {@link BlockStateHolder}s can be
|
||||
* constructed.
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
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;
|
||||
@ -32,7 +33,14 @@ 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.Calendar;
|
||||
@ -86,6 +94,28 @@ public class WorldEditCommands {
|
||||
actor.print("Configuration reloaded!");
|
||||
}
|
||||
|
||||
@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 = "",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -1,280 +1,281 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
|
||||
package com.sk89q.worldedit.util;
|
||||
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Simple LocalConfiguration that loads settings using
|
||||
* {@code java.util.Properties}.
|
||||
*/
|
||||
public class PropertiesConfiguration extends LocalConfiguration {
|
||||
|
||||
private static final Logger log = Logger.getLogger(PropertiesConfiguration.class.getCanonicalName());
|
||||
|
||||
protected Properties properties;
|
||||
protected File path;
|
||||
|
||||
/**
|
||||
* Construct the object. The configuration isn't loaded yet.
|
||||
*
|
||||
* @param path the path tot he configuration
|
||||
*/
|
||||
public PropertiesConfiguration(File path) {
|
||||
this.path = path;
|
||||
|
||||
properties = new Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try (InputStream stream = new FileInputStream(path)) {
|
||||
properties.load(stream);
|
||||
} catch (FileNotFoundException ignored) {
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to read configuration", e);
|
||||
}
|
||||
|
||||
loadExtra();
|
||||
|
||||
profile = getBool("profile", profile);
|
||||
traceUnflushedSessions = getBool("trace-unflushed-sessions", traceUnflushedSessions);
|
||||
disallowedBlocks = getStringSet("disallowed-blocks", defaultDisallowedBlocks);
|
||||
defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
|
||||
maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
|
||||
defaultMaxPolygonalPoints = getInt("default-max-polygon-points", defaultMaxPolygonalPoints);
|
||||
maxPolygonalPoints = getInt("max-polygon-points", maxPolygonalPoints);
|
||||
defaultMaxPolyhedronPoints = getInt("default-max-polyhedron-points", defaultMaxPolyhedronPoints);
|
||||
maxPolyhedronPoints = getInt("max-polyhedron-points", maxPolyhedronPoints);
|
||||
shellSaveType = getString("shell-save-type", shellSaveType);
|
||||
maxRadius = getInt("max-radius", maxRadius);
|
||||
maxSuperPickaxeSize = getInt("max-super-pickaxe-size", maxSuperPickaxeSize);
|
||||
maxBrushRadius = getInt("max-brush-radius", maxBrushRadius);
|
||||
logCommands = getBool("log-commands", logCommands);
|
||||
logFile = getString("log-file", logFile);
|
||||
logFormat = getString("log-format", logFormat);
|
||||
registerHelp = getBool("register-help", registerHelp);
|
||||
wandItem = getString("wand-item", wandItem);
|
||||
try {
|
||||
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
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);
|
||||
navigationWand = getString("nav-wand-item", navigationWand);
|
||||
try {
|
||||
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
|
||||
scriptTimeout = getInt("scripting-timeout", scriptTimeout);
|
||||
calculationTimeout = getInt("calculation-timeout", calculationTimeout);
|
||||
saveDir = getString("schematic-save-dir", saveDir);
|
||||
scriptsDir = getString("craftscript-dir", scriptsDir);
|
||||
butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
|
||||
butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
|
||||
allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
|
||||
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
||||
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||
|
||||
String snapshotsDir = getString("snapshots-dir", "");
|
||||
if (!snapshotsDir.isEmpty()) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
}
|
||||
|
||||
path.getParentFile().mkdirs();
|
||||
try (OutputStream output = new FileOutputStream(path)) {
|
||||
properties.store(output, "Don't put comments; they get removed");
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to write configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to load extra configuration.
|
||||
*/
|
||||
protected void loadExtra() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected String getString(String key, String def) {
|
||||
if (def == null) {
|
||||
def = "";
|
||||
}
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, def);
|
||||
return def;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected boolean getBool(String key, boolean def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, def ? "true" : "false");
|
||||
return def;
|
||||
} else {
|
||||
return val.equalsIgnoreCase("true")
|
||||
|| val.equals("1");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected int getInt(String key, int def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return Integer.parseInt(val);
|
||||
} catch (NumberFormatException e) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a double value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected double getDouble(String key, double def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return Double.parseDouble(val);
|
||||
} catch (NumberFormatException e) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a double value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected Set<Integer> getIntSet(String key, int[] def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, StringUtil.joinString(def, ",", 0));
|
||||
Set<Integer> set = new HashSet<>();
|
||||
for (int i : def) {
|
||||
set.add(i);
|
||||
}
|
||||
return set;
|
||||
} else {
|
||||
Set<Integer> set = new HashSet<>();
|
||||
String[] parts = val.split(",");
|
||||
for (String part : parts) {
|
||||
try {
|
||||
int v = Integer.parseInt(part.trim());
|
||||
set.add(v);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a String set.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected Set<String> getStringSet(String key, String[] def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, StringUtil.joinString(def, ",", 0));
|
||||
return new HashSet<>(Arrays.asList(def));
|
||||
} else {
|
||||
Set<String> set = new HashSet<>();
|
||||
String[] parts = val.split(",");
|
||||
for (String part : parts) {
|
||||
try {
|
||||
String v = part.trim();
|
||||
set.add(v);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
|
||||
package com.sk89q.worldedit.util;
|
||||
|
||||
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.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Simple LocalConfiguration that loads settings using
|
||||
* {@code java.util.Properties}.
|
||||
*/
|
||||
public class PropertiesConfiguration extends LocalConfiguration {
|
||||
|
||||
@Unreported private static final Logger log = Logger.getLogger(PropertiesConfiguration.class.getCanonicalName());
|
||||
|
||||
@Unreported protected Properties properties;
|
||||
@Unreported protected File path;
|
||||
|
||||
/**
|
||||
* Construct the object. The configuration isn't loaded yet.
|
||||
*
|
||||
* @param path the path tot he configuration
|
||||
*/
|
||||
public PropertiesConfiguration(File path) {
|
||||
this.path = path;
|
||||
|
||||
properties = new Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try (InputStream stream = new FileInputStream(path)) {
|
||||
properties.load(stream);
|
||||
} catch (FileNotFoundException ignored) {
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to read configuration", e);
|
||||
}
|
||||
|
||||
loadExtra();
|
||||
|
||||
profile = getBool("profile", profile);
|
||||
traceUnflushedSessions = getBool("trace-unflushed-sessions", traceUnflushedSessions);
|
||||
disallowedBlocks = getStringSet("disallowed-blocks", defaultDisallowedBlocks);
|
||||
defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
|
||||
maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
|
||||
defaultMaxPolygonalPoints = getInt("default-max-polygon-points", defaultMaxPolygonalPoints);
|
||||
maxPolygonalPoints = getInt("max-polygon-points", maxPolygonalPoints);
|
||||
defaultMaxPolyhedronPoints = getInt("default-max-polyhedron-points", defaultMaxPolyhedronPoints);
|
||||
maxPolyhedronPoints = getInt("max-polyhedron-points", maxPolyhedronPoints);
|
||||
shellSaveType = getString("shell-save-type", shellSaveType);
|
||||
maxRadius = getInt("max-radius", maxRadius);
|
||||
maxSuperPickaxeSize = getInt("max-super-pickaxe-size", maxSuperPickaxeSize);
|
||||
maxBrushRadius = getInt("max-brush-radius", maxBrushRadius);
|
||||
logCommands = getBool("log-commands", logCommands);
|
||||
logFile = getString("log-file", logFile);
|
||||
logFormat = getString("log-format", logFormat);
|
||||
registerHelp = getBool("register-help", registerHelp);
|
||||
wandItem = getString("wand-item", wandItem);
|
||||
try {
|
||||
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
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);
|
||||
navigationWand = getString("nav-wand-item", navigationWand);
|
||||
try {
|
||||
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
|
||||
scriptTimeout = getInt("scripting-timeout", scriptTimeout);
|
||||
calculationTimeout = getInt("calculation-timeout", calculationTimeout);
|
||||
saveDir = getString("schematic-save-dir", saveDir);
|
||||
scriptsDir = getString("craftscript-dir", scriptsDir);
|
||||
butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
|
||||
butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
|
||||
allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
|
||||
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
||||
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||
|
||||
String snapshotsDir = getString("snapshots-dir", "");
|
||||
if (!snapshotsDir.isEmpty()) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
}
|
||||
|
||||
path.getParentFile().mkdirs();
|
||||
try (OutputStream output = new FileOutputStream(path)) {
|
||||
properties.store(output, "Don't put comments; they get removed");
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to write configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to load extra configuration.
|
||||
*/
|
||||
protected void loadExtra() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected String getString(String key, String def) {
|
||||
if (def == null) {
|
||||
def = "";
|
||||
}
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, def);
|
||||
return def;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected boolean getBool(String key, boolean def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, def ? "true" : "false");
|
||||
return def;
|
||||
} else {
|
||||
return val.equalsIgnoreCase("true")
|
||||
|| val.equals("1");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected int getInt(String key, int def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return Integer.parseInt(val);
|
||||
} catch (NumberFormatException e) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a double value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected double getDouble(String key, double def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return Double.parseDouble(val);
|
||||
} catch (NumberFormatException e) {
|
||||
properties.setProperty(key, String.valueOf(def));
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a double value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected Set<Integer> getIntSet(String key, int[] def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, StringUtil.joinString(def, ",", 0));
|
||||
Set<Integer> set = new HashSet<>();
|
||||
for (int i : def) {
|
||||
set.add(i);
|
||||
}
|
||||
return set;
|
||||
} else {
|
||||
Set<Integer> set = new HashSet<>();
|
||||
String[] parts = val.split(",");
|
||||
for (String part : parts) {
|
||||
try {
|
||||
int v = Integer.parseInt(part.trim());
|
||||
set.add(v);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a String set.
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
* @return the value
|
||||
*/
|
||||
protected Set<String> getStringSet(String key, String[] def) {
|
||||
String val = properties.getProperty(key);
|
||||
if (val == null) {
|
||||
properties.setProperty(key, StringUtil.joinString(def, ",", 0));
|
||||
return new HashSet<>(Arrays.asList(def));
|
||||
} else {
|
||||
Set<String> set = new HashSet<>();
|
||||
String[] parts = val.split(",");
|
||||
for (String part : parts) {
|
||||
try {
|
||||
String v = part.trim();
|
||||
set.add(v);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,133 +1,134 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A less simple implementation of {@link LocalConfiguration}
|
||||
* using YAML configuration files.
|
||||
*/
|
||||
public class YAMLConfiguration extends LocalConfiguration {
|
||||
|
||||
protected final YAMLProcessor config;
|
||||
protected final Logger logger;
|
||||
|
||||
public YAMLConfiguration(YAMLProcessor config, Logger logger) {
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try {
|
||||
config.load();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Error loading WorldEdit configuration", e);
|
||||
}
|
||||
|
||||
profile = config.getBoolean("debug", profile);
|
||||
traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions);
|
||||
wandItem = convertLegacyItem(config.getString("wand-item", wandItem));
|
||||
|
||||
defaultChangeLimit = Math.max(-1, config.getInt(
|
||||
"limits.max-blocks-changed.default", defaultChangeLimit));
|
||||
maxChangeLimit = Math.max(-1,
|
||||
config.getInt("limits.max-blocks-changed.maximum", maxChangeLimit));
|
||||
|
||||
defaultMaxPolygonalPoints = Math.max(-1,
|
||||
config.getInt("limits.max-polygonal-points.default", defaultMaxPolygonalPoints));
|
||||
maxPolygonalPoints = Math.max(-1,
|
||||
config.getInt("limits.max-polygonal-points.maximum", maxPolygonalPoints));
|
||||
|
||||
defaultMaxPolyhedronPoints = Math.max(-1, config.getInt("limits.max-polyhedron-points.default", defaultMaxPolyhedronPoints));
|
||||
maxPolyhedronPoints = Math.max(-1, config.getInt("limits.max-polyhedron-points.maximum", maxPolyhedronPoints));
|
||||
|
||||
maxRadius = Math.max(-1, config.getInt("limits.max-radius", maxRadius));
|
||||
maxBrushRadius = config.getInt("limits.max-brush-radius", maxBrushRadius);
|
||||
maxSuperPickaxeSize = Math.max(1, config.getInt(
|
||||
"limits.max-super-pickaxe-size", maxSuperPickaxeSize));
|
||||
|
||||
butcherDefaultRadius = Math.max(-1, config.getInt("limits.butcher-radius.default", butcherDefaultRadius));
|
||||
butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius));
|
||||
|
||||
disallowedBlocks = new HashSet<>(config.getStringList("limits.disallowed-blocks", Lists.newArrayList(defaultDisallowedBlocks)));
|
||||
allowedDataCycleBlocks = new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null));
|
||||
|
||||
registerHelp = config.getBoolean("register-help", true);
|
||||
logCommands = config.getBoolean("logging.log-commands", logCommands);
|
||||
logFile = config.getString("logging.file", logFile);
|
||||
logFormat = config.getString("logging.format", logFormat);
|
||||
|
||||
superPickaxeDrop = config.getBoolean("super-pickaxe.drop-items",
|
||||
superPickaxeDrop);
|
||||
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);
|
||||
useInventoryCreativeOverride = config.getBoolean("use-inventory.creative-mode-overrides",
|
||||
useInventoryCreativeOverride);
|
||||
|
||||
navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand));
|
||||
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);
|
||||
|
||||
scriptTimeout = config.getInt("scripting.timeout", scriptTimeout);
|
||||
scriptsDir = config.getString("scripting.dir", scriptsDir);
|
||||
|
||||
calculationTimeout = config.getInt("calculation.timeout", calculationTimeout);
|
||||
|
||||
saveDir = config.getString("saving.dir", saveDir);
|
||||
|
||||
allowSymlinks = config.getBoolean("files.allow-symbolic-links", false);
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(0, config.getInt("history.size", 15));
|
||||
SessionManager.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000;
|
||||
|
||||
showHelpInfo = config.getBoolean("show-help-on-first-use", true);
|
||||
serverSideCUI = config.getBoolean("server-side-cui", true);
|
||||
|
||||
String snapshotsDir = config.getString("snapshots.directory", "");
|
||||
if (!snapshotsDir.isEmpty()) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
}
|
||||
|
||||
String type = config.getString("shell-save-type", "").trim();
|
||||
shellSaveType = type.isEmpty() ? null : type;
|
||||
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A less simple implementation of {@link LocalConfiguration}
|
||||
* using YAML configuration files.
|
||||
*/
|
||||
public class YAMLConfiguration extends LocalConfiguration {
|
||||
|
||||
@Unreported protected final YAMLProcessor config;
|
||||
@Unreported protected final Logger logger;
|
||||
|
||||
public YAMLConfiguration(YAMLProcessor config, Logger logger) {
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try {
|
||||
config.load();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Error loading WorldEdit configuration", e);
|
||||
}
|
||||
|
||||
profile = config.getBoolean("debug", profile);
|
||||
traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions);
|
||||
wandItem = convertLegacyItem(config.getString("wand-item", wandItem));
|
||||
|
||||
defaultChangeLimit = Math.max(-1, config.getInt(
|
||||
"limits.max-blocks-changed.default", defaultChangeLimit));
|
||||
maxChangeLimit = Math.max(-1,
|
||||
config.getInt("limits.max-blocks-changed.maximum", maxChangeLimit));
|
||||
|
||||
defaultMaxPolygonalPoints = Math.max(-1,
|
||||
config.getInt("limits.max-polygonal-points.default", defaultMaxPolygonalPoints));
|
||||
maxPolygonalPoints = Math.max(-1,
|
||||
config.getInt("limits.max-polygonal-points.maximum", maxPolygonalPoints));
|
||||
|
||||
defaultMaxPolyhedronPoints = Math.max(-1, config.getInt("limits.max-polyhedron-points.default", defaultMaxPolyhedronPoints));
|
||||
maxPolyhedronPoints = Math.max(-1, config.getInt("limits.max-polyhedron-points.maximum", maxPolyhedronPoints));
|
||||
|
||||
maxRadius = Math.max(-1, config.getInt("limits.max-radius", maxRadius));
|
||||
maxBrushRadius = config.getInt("limits.max-brush-radius", maxBrushRadius);
|
||||
maxSuperPickaxeSize = Math.max(1, config.getInt(
|
||||
"limits.max-super-pickaxe-size", maxSuperPickaxeSize));
|
||||
|
||||
butcherDefaultRadius = Math.max(-1, config.getInt("limits.butcher-radius.default", butcherDefaultRadius));
|
||||
butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius));
|
||||
|
||||
disallowedBlocks = new HashSet<>(config.getStringList("limits.disallowed-blocks", Lists.newArrayList(defaultDisallowedBlocks)));
|
||||
allowedDataCycleBlocks = new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null));
|
||||
|
||||
registerHelp = config.getBoolean("register-help", true);
|
||||
logCommands = config.getBoolean("logging.log-commands", logCommands);
|
||||
logFile = config.getString("logging.file", logFile);
|
||||
logFormat = config.getString("logging.format", logFormat);
|
||||
|
||||
superPickaxeDrop = config.getBoolean("super-pickaxe.drop-items",
|
||||
superPickaxeDrop);
|
||||
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);
|
||||
useInventoryCreativeOverride = config.getBoolean("use-inventory.creative-mode-overrides",
|
||||
useInventoryCreativeOverride);
|
||||
|
||||
navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand));
|
||||
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);
|
||||
|
||||
scriptTimeout = config.getInt("scripting.timeout", scriptTimeout);
|
||||
scriptsDir = config.getString("scripting.dir", scriptsDir);
|
||||
|
||||
calculationTimeout = config.getInt("calculation.timeout", calculationTimeout);
|
||||
|
||||
saveDir = config.getString("saving.dir", saveDir);
|
||||
|
||||
allowSymlinks = config.getBoolean("files.allow-symbolic-links", false);
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(0, config.getInt("history.size", 15));
|
||||
SessionManager.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000;
|
||||
|
||||
showHelpInfo = config.getBoolean("show-help-on-first-use", true);
|
||||
serverSideCUI = config.getBoolean("server-side-cui", true);
|
||||
|
||||
String snapshotsDir = config.getString("snapshots.directory", "");
|
||||
if (!snapshotsDir.isEmpty()) {
|
||||
snapshotRepo = new SnapshotRepository(snapshotsDir);
|
||||
}
|
||||
|
||||
String type = config.getString("shell-save-type", "").trim();
|
||||
shellSaveType = type.isEmpty() ? null : type;
|
||||
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* 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.net;
|
||||
|
||||
import com.sk89q.worldedit.util.io.Closer;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpRequest implements Closeable {
|
||||
|
||||
private static final int CONNECT_TIMEOUT = 1000 * 5;
|
||||
private static final int READ_TIMEOUT = 1000 * 5;
|
||||
private static final int READ_BUFFER_SIZE = 1024 * 8;
|
||||
|
||||
private final Map<String, String> headers = new HashMap<>();
|
||||
private final String method;
|
||||
private final URL url;
|
||||
private String contentType;
|
||||
private byte[] body;
|
||||
private HttpURLConnection conn;
|
||||
private InputStream inputStream;
|
||||
|
||||
private long contentLength = -1;
|
||||
private long readBytes = 0;
|
||||
|
||||
/**
|
||||
* Create a new HTTP request.
|
||||
*
|
||||
* @param method the method
|
||||
* @param url the URL
|
||||
*/
|
||||
private HttpRequest(String method, URL url) {
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit data.
|
||||
*
|
||||
* @return this object
|
||||
*/
|
||||
public HttpRequest body(String data) {
|
||||
body = data.getBytes();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit form data.
|
||||
*
|
||||
* @param form the form
|
||||
* @return this object
|
||||
*/
|
||||
public HttpRequest bodyForm(Form form) {
|
||||
contentType = "application/x-www-form-urlencoded";
|
||||
body = form.toString().getBytes();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a header.
|
||||
*
|
||||
* @param key the header key
|
||||
* @param value the header value
|
||||
* @return this object
|
||||
*/
|
||||
public HttpRequest header(String key, String value) {
|
||||
if (key.equalsIgnoreCase("Content-Type")) {
|
||||
contentType = value;
|
||||
} else {
|
||||
headers.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request.
|
||||
* <p/>
|
||||
* After execution, {@link #close()} should be called.
|
||||
*
|
||||
* @return this object
|
||||
* @throws java.io.IOException on I/O error
|
||||
*/
|
||||
public HttpRequest execute() throws IOException {
|
||||
boolean successful = false;
|
||||
|
||||
try {
|
||||
if (conn != null) {
|
||||
throw new IllegalArgumentException("Connection already executed");
|
||||
}
|
||||
|
||||
conn = (HttpURLConnection) reformat(url).openConnection();
|
||||
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java)");
|
||||
|
||||
if (body != null) {
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(body.length));
|
||||
conn.setDoInput(true);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
conn.setRequestProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
conn.setRequestMethod(method);
|
||||
conn.setUseCaches(false);
|
||||
conn.setDoOutput(true);
|
||||
conn.setConnectTimeout(CONNECT_TIMEOUT);
|
||||
conn.setReadTimeout(READ_TIMEOUT);
|
||||
|
||||
conn.connect();
|
||||
|
||||
if (body != null) {
|
||||
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
|
||||
out.write(body);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK ?
|
||||
conn.getInputStream() : conn.getErrorStream();
|
||||
|
||||
successful = true;
|
||||
} finally {
|
||||
if (!successful) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require that the response code is one of the given response codes.
|
||||
*
|
||||
* @param codes a list of codes
|
||||
* @return this object
|
||||
* @throws java.io.IOException if there is an I/O error or the response code is not expected
|
||||
*/
|
||||
public HttpRequest expectResponseCode(int... codes) throws IOException {
|
||||
int responseCode = getResponseCode();
|
||||
|
||||
for (int code : codes) {
|
||||
if (code == responseCode) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
throw new IOException("Did not get expected response code, got " + responseCode + " for " + url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response code.
|
||||
*
|
||||
* @return the response code
|
||||
* @throws java.io.IOException on I/O error
|
||||
*/
|
||||
public int getResponseCode() throws IOException {
|
||||
if (conn == null) {
|
||||
throw new IllegalArgumentException("No connection has been made");
|
||||
}
|
||||
|
||||
return conn.getResponseCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input stream.
|
||||
*
|
||||
* @return the input stream
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffer the returned response.
|
||||
*
|
||||
* @return the buffered response
|
||||
* @throws java.io.IOException on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public BufferedResponse returnContent() throws IOException, InterruptedException {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("No input stream available");
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
int b = 0;
|
||||
while ((b = inputStream.read()) != -1) {
|
||||
bos.write(b);
|
||||
}
|
||||
return new BufferedResponse(bos.toByteArray());
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the result to a file.
|
||||
*
|
||||
* @param file the file
|
||||
* @return this object
|
||||
* @throws java.io.IOException on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public HttpRequest saveContent(File file) throws IOException, InterruptedException {
|
||||
Closer closer = Closer.create();
|
||||
|
||||
try {
|
||||
FileOutputStream fos = closer.register(new FileOutputStream(file));
|
||||
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
||||
|
||||
saveContent(bos);
|
||||
} finally {
|
||||
closer.close();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the result to an output stream.
|
||||
*
|
||||
* @param out the output stream
|
||||
* @return this object
|
||||
* @throws java.io.IOException on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public HttpRequest saveContent(OutputStream out) throws IOException, InterruptedException {
|
||||
BufferedInputStream bis;
|
||||
|
||||
try {
|
||||
String field = conn.getHeaderField("Content-Length");
|
||||
if (field != null) {
|
||||
long len = Long.parseLong(field);
|
||||
if (len >= 0) { // Let's just not deal with really big numbers
|
||||
contentLength = len;
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
|
||||
byte[] data = new byte[READ_BUFFER_SIZE];
|
||||
int len = 0;
|
||||
while ((len = bis.read(data, 0, READ_BUFFER_SIZE)) >= 0) {
|
||||
out.write(data, 0, len);
|
||||
readBytes += len;
|
||||
}
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (conn != null) conn.disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a GET request.
|
||||
*
|
||||
* @param url the URL
|
||||
* @return a new request object
|
||||
*/
|
||||
public static HttpRequest get(URL url) {
|
||||
return request("GET", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a POST request.
|
||||
*
|
||||
* @param url the URL
|
||||
* @return a new request object
|
||||
*/
|
||||
public static HttpRequest post(URL url) {
|
||||
return request("POST", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a request.
|
||||
*
|
||||
* @param method the method
|
||||
* @param url the URL
|
||||
* @return a new request object
|
||||
*/
|
||||
public static HttpRequest request(String method, URL url) {
|
||||
return new HttpRequest(method, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link java.net.URL} and throw a {@link RuntimeException} if the URL
|
||||
* is not valid.
|
||||
*
|
||||
* @param url the url
|
||||
* @return a URL object
|
||||
* @throws RuntimeException if the URL is invalid
|
||||
*/
|
||||
public static URL url(String url) {
|
||||
try {
|
||||
return new URL(url);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL may contain spaces and other nasties that will cause a failure.
|
||||
*
|
||||
* @param existing the existing URL to transform
|
||||
* @return the new URL, or old one if there was a failure
|
||||
*/
|
||||
private static URL reformat(URL existing) {
|
||||
try {
|
||||
URL url = new URL(existing.toString());
|
||||
URI uri = new URI(
|
||||
url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(),
|
||||
url.getPath(), url.getQuery(), url.getRef());
|
||||
url = uri.toURL();
|
||||
return url;
|
||||
} catch (MalformedURLException e) {
|
||||
return existing;
|
||||
} catch (URISyntaxException e) {
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used with {@link #bodyForm(Form)}.
|
||||
*/
|
||||
public final static class Form {
|
||||
public final List<String> elements = new ArrayList<>();
|
||||
|
||||
private Form() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a key/value to the form.
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return this object
|
||||
*/
|
||||
public Form add(String key, String value) {
|
||||
try {
|
||||
elements.add(URLEncoder.encode(key, "UTF-8") +
|
||||
"=" + URLEncoder.encode(value, "UTF-8"));
|
||||
return this;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String element : elements) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
builder.append("&");
|
||||
}
|
||||
builder.append(element);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new form.
|
||||
*
|
||||
* @return a new form
|
||||
*/
|
||||
public static Form create() {
|
||||
return new Form();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to buffer the response in memory.
|
||||
*/
|
||||
public class BufferedResponse {
|
||||
private final byte[] data;
|
||||
|
||||
private BufferedResponse(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result as bytes.
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
public byte[] asBytes() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result as a string.
|
||||
*
|
||||
* @param encoding the encoding
|
||||
* @return the string
|
||||
* @throws java.io.IOException on I/O error
|
||||
*/
|
||||
public String asString(String encoding) throws IOException {
|
||||
return new String(data, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the result to a file.
|
||||
*
|
||||
* @param file the file
|
||||
* @return this object
|
||||
* @throws java.io.IOException on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public BufferedResponse saveContent(File file) throws IOException, InterruptedException {
|
||||
Closer closer = Closer.create();
|
||||
file.getParentFile().mkdirs();
|
||||
|
||||
try {
|
||||
FileOutputStream fos = closer.register(new FileOutputStream(file));
|
||||
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
||||
|
||||
saveContent(bos);
|
||||
} finally {
|
||||
closer.close();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the result to an output stream.
|
||||
*
|
||||
* @param out the output stream
|
||||
* @return this object
|
||||
* @throws java.io.IOException on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public BufferedResponse saveContent(OutputStream out) throws IOException, InterruptedException {
|
||||
out.write(data);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.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.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.task.Supervisor;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ActorCallbackPaste {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ActorCallbackPaste.class.getSimpleName());
|
||||
|
||||
private ActorCallbackPaste() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit data to a pastebin service and inform the sender of
|
||||
* success or failure.
|
||||
*
|
||||
* @param supervisor The supervisor instance
|
||||
* @param sender The sender
|
||||
* @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) {
|
||||
ListenableFuture<URL> future = new EngineHubPaste().paste(content);
|
||||
|
||||
AsyncCommandHelper.wrap(future, supervisor, sender)
|
||||
.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.log(Level.WARNING, "Failed to submit pastebin", throwable);
|
||||
sender.printError("Failed to submit to a pastebin. Please see console for the error.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 org.json.simple.JSONValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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("content", content);
|
||||
form.add("from", "worldguard");
|
||||
|
||||
URL url = HttpRequest.url("http://paste.enginehub.org/paste");
|
||||
String result = HttpRequest.post(url)
|
||||
.bodyForm(form)
|
||||
.execute()
|
||||
.expectResponseCode(200)
|
||||
.returnContent()
|
||||
.asString("UTF-8").trim();
|
||||
|
||||
Object object = JSONValue.parse(result);
|
||||
if (object instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
String urlString = String.valueOf(((Map<Object, Object>) object).get("url"));
|
||||
Matcher m = URL_PATTERN.matcher(urlString);
|
||||
|
||||
if (m.matches()) {
|
||||
return new URL(urlString);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IOException("Failed to save paste; instead, got: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 java.net.URL;
|
||||
|
||||
public interface Paster {
|
||||
|
||||
ListenableFuture<URL> paste(String content);
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
final class Pasters {
|
||||
|
||||
private static final ListeningExecutorService executor =
|
||||
MoreExecutors.listeningDecorator(
|
||||
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
|
||||
2L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<>()));
|
||||
|
||||
private Pasters() {
|
||||
}
|
||||
|
||||
static ListeningExecutorService getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.report;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
|
||||
public class ConfigReport extends DataReport {
|
||||
|
||||
public ConfigReport() {
|
||||
super("WorldEdit Configuration");
|
||||
|
||||
append("Configuration", new HierarchyObjectReport("Configuration", WorldEdit.getInstance().getConfiguration()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.report;
|
||||
|
||||
public class HierarchyObjectReport extends ShallowObjectReport {
|
||||
|
||||
public HierarchyObjectReport(String title, Object object) {
|
||||
super(title, object);
|
||||
|
||||
Class<?> type = object.getClass();
|
||||
while ((type = type.getSuperclass()) != null) {
|
||||
scanClass(object, type);
|
||||
}
|
||||
}
|
||||
}
|
@ -34,8 +34,10 @@ public class ShallowObjectReport extends DataReport {
|
||||
super(title);
|
||||
checkNotNull(object, "object");
|
||||
|
||||
Class<?> type = object.getClass();
|
||||
scanClass(object, object.getClass());
|
||||
}
|
||||
|
||||
void scanClass(Object object, Class<?> type) {
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
@ -54,5 +56,4 @@ public class ShallowObjectReport extends DataReport {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.task;
|
||||
|
||||
import com.google.common.util.concurrent.AbstractFuture;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An abstract task that stores a name and owner.
|
||||
*
|
||||
* @param <V> the type returned
|
||||
*/
|
||||
public abstract class AbstractTask<V> extends AbstractFuture<V> implements Task<V> {
|
||||
|
||||
private final UUID uniqueId = UUID.randomUUID();
|
||||
private final String name;
|
||||
private final Object owner;
|
||||
private final Date creationDate = new Date();
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param name the name
|
||||
* @param owner the owner
|
||||
*/
|
||||
protected AbstractTask(String name, @Nullable Object owner) {
|
||||
checkNotNull(name);
|
||||
this.name = name;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.worldedit.util.task.progress.Progress;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A task that wraps a {@code ListenableFuture}.
|
||||
*
|
||||
* <p>{@link Task.State#SCHEDULED} is never returned because it is not possible
|
||||
* to test whether the future has "started," so {@link Task.State#RUNNING} is
|
||||
* returned in its place.</p>
|
||||
*
|
||||
* <p>Use {@link #create(ListenableFuture, String, Object)} to create a new
|
||||
* instance.</p>
|
||||
*
|
||||
* @param <V> the type returned
|
||||
*/
|
||||
public class FutureForwardingTask<V> extends AbstractTask<V> {
|
||||
|
||||
private final ListenableFuture<V> future;
|
||||
|
||||
private FutureForwardingTask(ListenableFuture<V> future, String name, @Nullable Object owner) {
|
||||
super(name, owner);
|
||||
checkNotNull(future);
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Runnable listener, Executor executor) {
|
||||
future.addListener(listener, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return future.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return future.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return future.isDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get() throws InterruptedException, ExecutionException {
|
||||
return future.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return future.get(timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
if (isCancelled()) {
|
||||
return State.CANCELLED;
|
||||
} else if (isDone()) {
|
||||
try {
|
||||
get();
|
||||
return State.SUCCEEDED;
|
||||
} catch (InterruptedException e) {
|
||||
return State.CANCELLED;
|
||||
} catch (ExecutionException e) {
|
||||
return State.FAILED;
|
||||
}
|
||||
} else {
|
||||
return State.RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Progress getProgress() {
|
||||
return Progress.indeterminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param future the future
|
||||
* @param name the name of the task
|
||||
* @param owner the owner of the task, or {@code null}
|
||||
* @param <V> the type returned by the future
|
||||
* @return a new instance
|
||||
*/
|
||||
public static <V> FutureForwardingTask<V> create(ListenableFuture<V> future, String name, @Nullable Object owner) {
|
||||
return new FutureForwardingTask<>(future, name, owner);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An implementation of a {@code Supervisor}.
|
||||
*/
|
||||
public class SimpleSupervisor implements Supervisor {
|
||||
|
||||
private final List<Task<?>> monitored = new ArrayList<>();
|
||||
private final Object lock = new Object();
|
||||
|
||||
@Override
|
||||
public List<Task<?>> getTasks() {
|
||||
synchronized (lock) {
|
||||
return new ArrayList<>(monitored);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void monitor(final Task<?> task) {
|
||||
checkNotNull(task);
|
||||
|
||||
synchronized (lock) {
|
||||
monitored.add(task);
|
||||
}
|
||||
|
||||
task.addListener(() -> {
|
||||
synchronized (lock) {
|
||||
monitored.remove(task);
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages running tasks and informs users of their progress, but does not
|
||||
* execute the task.
|
||||
*/
|
||||
public interface Supervisor {
|
||||
|
||||
/**
|
||||
* Get a list of running or queued tasks.
|
||||
*
|
||||
* @return a list of tasks
|
||||
*/
|
||||
List<Task<?>> getTasks();
|
||||
|
||||
/**
|
||||
* Monitor the given task.
|
||||
*
|
||||
* @param task the task
|
||||
*/
|
||||
void monitor(Task<?> task);
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.sk89q.worldedit.util.task.progress.ProgressObservable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A task is a job that can be scheduled, run, or cancelled. Tasks can report
|
||||
* on their own status. Tasks have owners.
|
||||
*/
|
||||
public interface Task<V> extends ListenableFuture<V>, ProgressObservable {
|
||||
|
||||
/**
|
||||
* Get the unique ID of this task.
|
||||
*
|
||||
* @return this task's unique ID
|
||||
*/
|
||||
UUID getUniqueId();
|
||||
|
||||
/**
|
||||
* Get the name of the task so it can be printed to the user.
|
||||
*
|
||||
* @return the name of the task
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Get the owner of the task.
|
||||
*
|
||||
* @return an owner object, if one is known or valid, otherwise {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
Object getOwner();
|
||||
|
||||
/**
|
||||
* Get the state of the task.
|
||||
*
|
||||
* @return the state of the task
|
||||
*/
|
||||
State getState();
|
||||
|
||||
/**
|
||||
* Get the time at which the task was created.
|
||||
*
|
||||
* @return a date
|
||||
*/
|
||||
Date getCreationDate();
|
||||
|
||||
/**
|
||||
* Represents the state of a task.
|
||||
*/
|
||||
enum State {
|
||||
/**
|
||||
* The task has been scheduled to run but is not running yet.
|
||||
*/
|
||||
SCHEDULED,
|
||||
/**
|
||||
* The task has been cancelled and may be stopped or will stop.
|
||||
*/
|
||||
CANCELLED,
|
||||
/**
|
||||
* The task is currently running.
|
||||
*/
|
||||
RUNNING,
|
||||
/**
|
||||
* The task has failed.
|
||||
*/
|
||||
FAILED,
|
||||
/**
|
||||
* The task has succeeded.
|
||||
*/
|
||||
SUCCEEDED
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Compares task states according to the order of the {@link Task.State}
|
||||
* enumeration.
|
||||
*/
|
||||
public class TaskStateComparator implements Comparator<Task<?>> {
|
||||
|
||||
@Override
|
||||
public int compare(com.sk89q.worldedit.util.task.Task<?> o1, Task<?> o2) {
|
||||
int ordinal1 = o1.getState().ordinal();
|
||||
int ordinal2 = o2.getState().ordinal();
|
||||
if (ordinal1 < ordinal2) {
|
||||
return -1;
|
||||
} else if (ordinal1 > ordinal2) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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.task.progress;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A progress object describes the progress of an operation, specifying
|
||||
* either a percentage of completion or a status of indeterminacy.
|
||||
*
|
||||
* <p>Progress objects are immutable.</p>
|
||||
*
|
||||
* <p>To create a new instance, use one of the static constructors
|
||||
* on this class.</p>
|
||||
*/
|
||||
public abstract class Progress {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
private Progress() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the current progress is indeterminate.
|
||||
*
|
||||
* @return true if indeterminate
|
||||
*/
|
||||
public abstract boolean isIndeterminate();
|
||||
|
||||
/**
|
||||
* Get the progress percentage.
|
||||
*
|
||||
* <p>If {@link #isIndeterminate()} returns {@code true}, the behavior
|
||||
* of this method is undefined.</p>
|
||||
*
|
||||
* @return a number in the range [0, 1]
|
||||
*/
|
||||
public abstract double getProgress();
|
||||
|
||||
/**
|
||||
* Get a static progress object that is indeterminate.
|
||||
*
|
||||
* @return a progress object
|
||||
*/
|
||||
public static Progress indeterminate() {
|
||||
return INDETERMINATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a static progress object that is complete.
|
||||
*
|
||||
* @return a progress object
|
||||
*/
|
||||
public static Progress completed() {
|
||||
return COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new progress object with the given percentage.
|
||||
*
|
||||
* @param value the percentage, which will be clamped to [0, 1]
|
||||
* @return a progress object
|
||||
*/
|
||||
public static Progress of(double value) {
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
} else if (value > 1) {
|
||||
value = 1;
|
||||
}
|
||||
|
||||
final double finalValue = value;
|
||||
return new Progress() {
|
||||
@Override
|
||||
public boolean isIndeterminate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getProgress() {
|
||||
return finalValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new progress object with progress split equally between the
|
||||
* given progress objects.
|
||||
*
|
||||
* @param objects an array of progress objects
|
||||
* @return a new progress value
|
||||
*/
|
||||
public static Progress split(Progress... objects) {
|
||||
return split(Arrays.asList(objects));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new progress object with progress split equally between the
|
||||
* given progress objects.
|
||||
*
|
||||
* @param progress a collection of progress objects
|
||||
* @return a new progress value
|
||||
*/
|
||||
public static Progress split(Collection<Progress> progress) {
|
||||
int count = 0;
|
||||
double total = 0;
|
||||
|
||||
for (Progress p : progress) {
|
||||
if (p.isIndeterminate()) {
|
||||
return indeterminate();
|
||||
}
|
||||
total += p.getProgress();
|
||||
}
|
||||
|
||||
return of(total / count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new progress object with progress split equally between the
|
||||
* given {@link ProgressObservable}s.
|
||||
*
|
||||
* @param observables an array of observables
|
||||
* @return a new progress value
|
||||
*/
|
||||
public static Progress splitObservables(ProgressObservable... observables) {
|
||||
return splitObservables(Arrays.asList(observables));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new progress object with progress split equally between the
|
||||
* given {@link ProgressObservable}s.
|
||||
*
|
||||
* @param observables a collection of observables
|
||||
* @return a new progress value
|
||||
*/
|
||||
public static Progress splitObservables(Collection<? extends ProgressObservable> observables) {
|
||||
int count = 0;
|
||||
double total = 0;
|
||||
|
||||
for (ProgressObservable observable : observables) {
|
||||
Progress p = observable.getProgress();
|
||||
if (p.isIndeterminate()) {
|
||||
return indeterminate();
|
||||
}
|
||||
total += p.getProgress();
|
||||
}
|
||||
|
||||
return of(total / count);
|
||||
}
|
||||
|
||||
private static final Progress COMPLETED = of(1);
|
||||
|
||||
private static final Progress INDETERMINATE = new Progress() {
|
||||
@Override
|
||||
public boolean isIndeterminate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getProgress() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.task.progress;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An iterator that keeps track of how many entries have been visited and
|
||||
* calculates a "percent completed" using a provided total count.
|
||||
*
|
||||
* <p>The returned progress percentage will always be between 0 or 1
|
||||
* (inclusive). If the iterator returns more entries than the total count,
|
||||
* then 100% will be returned for the progress.</p>
|
||||
*
|
||||
* @param <V> the type
|
||||
*/
|
||||
public class ProgressIterator<V> implements Iterator<V>, ProgressObservable {
|
||||
|
||||
private final Iterator<V> iterator;
|
||||
private final int count;
|
||||
private int visited = 0;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param iterator the iterator
|
||||
* @param count the count
|
||||
*/
|
||||
private ProgressIterator(Iterator<V> iterator, int count) {
|
||||
checkNotNull(iterator);
|
||||
this.iterator = iterator;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V next() {
|
||||
V value = iterator.next();
|
||||
visited++;
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Progress getProgress() {
|
||||
return Progress.of(count > 0 ? Math.min(1, Math.max(0, (visited / (double) count))) : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param iterator the iterator
|
||||
* @param count the number of objects
|
||||
* @param <V> the type
|
||||
* @return an instance
|
||||
*/
|
||||
public static <V> ProgressIterator<V> create(Iterator<V> iterator, int count) {
|
||||
return new ProgressIterator<V>(iterator, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a list.
|
||||
*
|
||||
* @param list a list
|
||||
* @param <V> the type
|
||||
* @return an instance
|
||||
*/
|
||||
public static <V> ProgressIterator<V> create(List<V> list) {
|
||||
return create(list.iterator(), list.size());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.task.progress;
|
||||
|
||||
/**
|
||||
* An object that is able to report on its progress.
|
||||
*/
|
||||
public interface ProgressObservable {
|
||||
|
||||
/**
|
||||
* Get the current percentage of completion.
|
||||
*
|
||||
* @return a progress object
|
||||
*/
|
||||
Progress getProgress();
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ import com.google.common.reflect.TypeToken;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
import ninja.leaping.configurate.ConfigurationOptions;
|
||||
@ -36,10 +37,10 @@ import java.util.HashSet;
|
||||
|
||||
public class ConfigurateConfiguration extends LocalConfiguration {
|
||||
|
||||
protected final ConfigurationLoader<CommentedConfigurationNode> config;
|
||||
protected final Logger logger;
|
||||
@Unreported protected final ConfigurationLoader<CommentedConfigurationNode> config;
|
||||
@Unreported protected final Logger logger;
|
||||
|
||||
protected CommentedConfigurationNode node;
|
||||
@Unreported protected CommentedConfigurationNode node;
|
||||
|
||||
public ConfigurateConfiguration(ConfigurationLoader<CommentedConfigurationNode> config, Logger logger) {
|
||||
this.config = config;
|
||||
|
Loading…
Reference in New Issue
Block a user