mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
Run schematic-file I/O in a task.
This commit is contained in:
parent
fab21c3eea
commit
7b170d8193
@ -21,6 +21,8 @@ package com.sk89q.worldedit;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
|
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
|
||||||
@ -44,6 +46,7 @@ import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
|
|||||||
import com.sk89q.worldedit.session.SessionManager;
|
import com.sk89q.worldedit.session.SessionManager;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.util.concurrency.EvenMoreExecutors;
|
||||||
import com.sk89q.worldedit.util.eventbus.EventBus;
|
import com.sk89q.worldedit.util.eventbus.EventBus;
|
||||||
import com.sk89q.worldedit.util.io.file.FileSelectionAbortedException;
|
import com.sk89q.worldedit.util.io.file.FileSelectionAbortedException;
|
||||||
import com.sk89q.worldedit.util.io.file.FilenameException;
|
import com.sk89q.worldedit.util.io.file.FilenameException;
|
||||||
@ -102,6 +105,7 @@ public final class WorldEdit {
|
|||||||
private final PlatformManager platformManager = new PlatformManager(this);
|
private final PlatformManager platformManager = new PlatformManager(this);
|
||||||
private final EditSessionFactory editSessionFactory = new EditSessionFactory.EditSessionFactoryImpl(eventBus);
|
private final EditSessionFactory editSessionFactory = new EditSessionFactory.EditSessionFactoryImpl(eventBus);
|
||||||
private final SessionManager sessions = new SessionManager(this);
|
private final SessionManager sessions = new SessionManager(this);
|
||||||
|
private final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));;
|
||||||
private final Supervisor supervisor = new SimpleSupervisor();
|
private final Supervisor supervisor = new SimpleSupervisor();
|
||||||
|
|
||||||
private final BlockFactory blockFactory = new BlockFactory(this);
|
private final BlockFactory blockFactory = new BlockFactory(this);
|
||||||
@ -152,7 +156,7 @@ public final class WorldEdit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the supervisor.
|
* Get the supervisor. Internal, not for API use.
|
||||||
*
|
*
|
||||||
* @return the supervisor
|
* @return the supervisor
|
||||||
*/
|
*/
|
||||||
@ -160,6 +164,15 @@ public final class WorldEdit {
|
|||||||
return supervisor;
|
return supervisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the executor service. Internal, not for API use.
|
||||||
|
*
|
||||||
|
* @return the executor service
|
||||||
|
*/
|
||||||
|
public ListeningExecutorService getExecutorService() {
|
||||||
|
return executorService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the block factory from which new {@link BlockStateHolder}s can be
|
* Get the block factory from which new {@link BlockStateHolder}s can be
|
||||||
* constructed.
|
* constructed.
|
||||||
|
@ -23,6 +23,7 @@ import com.sk89q.worldedit.LocalConfiguration;
|
|||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
|
||||||
import com.sk89q.worldedit.command.util.CommandPermissions;
|
import com.sk89q.worldedit.command.util.CommandPermissions;
|
||||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
@ -60,6 +61,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -113,20 +115,13 @@ public class SchematicCommands {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Closer closer = Closer.create()) {
|
SchematicLoadTask task = new SchematicLoadTask(player, f, format);
|
||||||
FileInputStream fis = closer.register(new FileInputStream(f));
|
AsyncCommandBuilder.wrap(task, player)
|
||||||
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
|
.registerWithSupervisor(worldEdit.getSupervisor(), "Loading schematic " + filename)
|
||||||
ClipboardReader reader = closer.register(format.getReader(bis));
|
.sendMessageAfterDelay("(Please wait... loading schematic.)")
|
||||||
|
.onSuccess(filename + " loaded. Paste it with //paste", session::setClipboard)
|
||||||
Clipboard clipboard = reader.read();
|
.onFailure("Failed to load schematic", worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter())
|
||||||
session.setClipboard(new ClipboardHolder(clipboard));
|
.buildAndExec(worldEdit.getExecutorService());
|
||||||
|
|
||||||
log.info(player.getName() + " loaded " + f.getCanonicalPath());
|
|
||||||
player.print(filename + " loaded. Paste it with //paste");
|
|
||||||
} catch (IOException e) {
|
|
||||||
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
|
|
||||||
log.warn("Failed to load schematic: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -165,42 +160,24 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipboardHolder holder = session.getClipboard();
|
|
||||||
Clipboard clipboard = holder.getClipboard();
|
|
||||||
Transform transform = holder.getTransform();
|
|
||||||
Clipboard target;
|
|
||||||
|
|
||||||
// If we have a transform, bake it into the copy
|
|
||||||
if (!transform.isIdentity()) {
|
|
||||||
FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform);
|
|
||||||
target = new BlockArrayClipboard(result.getTransformedRegion());
|
|
||||||
target.setOrigin(clipboard.getOrigin());
|
|
||||||
Operations.completeLegacy(result.copyTo(target));
|
|
||||||
} else {
|
|
||||||
target = clipboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create parent directories
|
// Create parent directories
|
||||||
File parent = f.getParentFile();
|
File parent = f.getParentFile();
|
||||||
if (parent != null && !parent.exists()) {
|
if (parent != null && !parent.exists()) {
|
||||||
if (!parent.mkdirs()) {
|
if (!parent.mkdirs()) {
|
||||||
throw new StopExecutionException(TextComponent.of(
|
throw new StopExecutionException(TextComponent.of(
|
||||||
"Could not create folder for schematics!"));
|
"Could not create folder for schematics!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Closer closer = Closer.create()) {
|
ClipboardHolder holder = session.getClipboard();
|
||||||
FileOutputStream fos = closer.register(new FileOutputStream(f));
|
|
||||||
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
|
||||||
ClipboardWriter writer = closer.register(format.getWriter(bos));
|
|
||||||
writer.write(target);
|
|
||||||
|
|
||||||
log.info(player.getName() + " saved " + f.getCanonicalPath() + (overwrite ? " (overwriting previous file)" : ""));
|
SchematicSaveTask task = new SchematicSaveTask(player, f, format, holder, overwrite);
|
||||||
player.print(filename + " saved" + (overwrite ? " (overwriting previous file)." : "."));
|
AsyncCommandBuilder.wrap(task, player)
|
||||||
} catch (IOException e) {
|
.registerWithSupervisor(worldEdit.getSupervisor(), "Saving schematic " + filename)
|
||||||
player.printError("Schematic could not written: " + e.getMessage());
|
.sendMessageAfterDelay("(Please wait... saving schematic.)")
|
||||||
log.warn("Failed to write a saved clipboard", e);
|
.onSuccess(filename + " saved" + (overwrite ? " (overwriting previous file)." : "."), null)
|
||||||
}
|
.onFailure("Failed to load schematic", worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter())
|
||||||
|
.buildAndExec(worldEdit.getExecutorService());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -329,4 +306,71 @@ public class SchematicCommands {
|
|||||||
return fileList;
|
return fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SchematicLoadTask implements Callable<ClipboardHolder> {
|
||||||
|
private final Player player;
|
||||||
|
private final File file;
|
||||||
|
private final ClipboardFormat format;
|
||||||
|
|
||||||
|
SchematicLoadTask(Player player, File file, ClipboardFormat format) {
|
||||||
|
this.player = player;
|
||||||
|
this.file = file;
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardHolder call() throws Exception {
|
||||||
|
try (Closer closer = Closer.create()) {
|
||||||
|
FileInputStream fis = closer.register(new FileInputStream(file));
|
||||||
|
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
|
||||||
|
ClipboardReader reader = closer.register(format.getReader(bis));
|
||||||
|
|
||||||
|
Clipboard clipboard = reader.read();
|
||||||
|
log.info(player.getName() + " loaded " + file.getCanonicalPath());
|
||||||
|
return new ClipboardHolder(clipboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SchematicSaveTask implements Callable<Void> {
|
||||||
|
private final Player player;
|
||||||
|
private final File file;
|
||||||
|
private final ClipboardFormat format;
|
||||||
|
private final ClipboardHolder holder;
|
||||||
|
private final boolean overwrite;
|
||||||
|
|
||||||
|
SchematicSaveTask(Player player, File file, ClipboardFormat format, ClipboardHolder holder, boolean overwrite) {
|
||||||
|
this.player = player;
|
||||||
|
this.file = file;
|
||||||
|
this.format = format;
|
||||||
|
this.holder = holder;
|
||||||
|
this.overwrite = overwrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
Clipboard clipboard = holder.getClipboard();
|
||||||
|
Transform transform = holder.getTransform();
|
||||||
|
Clipboard target;
|
||||||
|
|
||||||
|
// If we have a transform, bake it into the copy
|
||||||
|
if (transform.isIdentity()) {
|
||||||
|
target = clipboard;
|
||||||
|
} else {
|
||||||
|
FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform);
|
||||||
|
target = new BlockArrayClipboard(result.getTransformedRegion());
|
||||||
|
target.setOrigin(clipboard.getOrigin());
|
||||||
|
Operations.completeLegacy(result.copyTo(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Closer closer = Closer.create()) {
|
||||||
|
FileOutputStream fos = closer.register(new FileOutputStream(file));
|
||||||
|
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
||||||
|
ClipboardWriter writer = closer.register(format.getWriter(bos));
|
||||||
|
writer.write(target);
|
||||||
|
|
||||||
|
log.info(player.getName() + " saved " + file.getCanonicalPath() + (overwrite ? " (overwriting previous file)" : ""));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ public class WorldEditCommands {
|
|||||||
String result = report.toString();
|
String result = report.toString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File dest = new File(we.getWorkingDirectoryFile(we.getConfiguration().saveDir), "report.txt");
|
File dest = new File(we.getConfiguration().getWorkingDirectory(), "report.txt");
|
||||||
Files.write(result, dest, Charset.forName("UTF-8"));
|
Files.write(result, dest, Charset.forName("UTF-8"));
|
||||||
actor.print("WorldEdit report written to " + dest.getAbsolutePath());
|
actor.print("WorldEdit report written to " + dest.getAbsolutePath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* WorldEdit, a Minecraft world manipulation toolkit
|
|
||||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
|
||||||
* Copyright (C) WorldEdit team and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sk89q.worldedit.command.util;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
|
||||||
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
|
|
||||||
import org.enginehub.piston.exception.CommandException;
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user