mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-29 14:06:30 +01:00
Merge pull request #3008 from Multiverse/ben/mv5/results
Revamp results to support value returns
This commit is contained in:
commit
d02cd63244
@ -51,34 +51,35 @@ public class CloneCommand extends MultiverseCommand {
|
||||
@CommandCompletion("@mvworlds:scope=both @empty")
|
||||
@Syntax("<world> <new world name>")
|
||||
@Description("{@@mv-core.clone.description}")
|
||||
public void onCloneCommand(MVCommandIssuer issuer,
|
||||
void onCloneCommand(
|
||||
MVCommandIssuer issuer,
|
||||
|
||||
@Syntax("<world>")
|
||||
@Description("{@@mv-core.clone.world.description}")
|
||||
LoadedMultiverseWorld world,
|
||||
@Syntax("<world>")
|
||||
@Description("{@@mv-core.clone.world.description}")
|
||||
LoadedMultiverseWorld world,
|
||||
|
||||
@Syntax("<new world name>")
|
||||
@Description("{@@mv-core.clone.newWorld.description}")
|
||||
String newWorldName,
|
||||
@Syntax("<new world name>")
|
||||
@Description("{@@mv-core.clone.newWorld.description}")
|
||||
String newWorldName,
|
||||
|
||||
@Optional
|
||||
@Syntax("") // TODO
|
||||
@Description("{@@mv-core.regen.other.description}")
|
||||
String[] flags
|
||||
) {
|
||||
@Optional
|
||||
@Syntax(/* TODO */ "")
|
||||
@Description("{@@mv-core.regen.other.description}")
|
||||
String[] flags) {
|
||||
ParsedCommandFlags parsedFlags = parseFlags(flags);
|
||||
|
||||
issuer.sendInfo(MVCorei18n.CLONE_CLONING, "{world}", world.getName(), "{newworld}", newWorldName);
|
||||
worldManager.cloneWorld(CloneWorldOptions.fromTo(world, newWorldName)
|
||||
CloneWorldOptions cloneWorldOptions = CloneWorldOptions.fromTo(world, newWorldName)
|
||||
.keepWorldConfig(!parsedFlags.hasFlag("--reset-world-config"))
|
||||
.keepGameRule(!parsedFlags.hasFlag("--reset-gamerules"))
|
||||
.keepWorldBorder(!parsedFlags.hasFlag("--reset-world-border"))
|
||||
).onSuccess((success) -> {
|
||||
Logging.fine("World remove success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
Logging.fine("World remove failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
});
|
||||
.keepWorldBorder(!parsedFlags.hasFlag("--reset-world-border"));
|
||||
worldManager.cloneWorld(cloneWorldOptions)
|
||||
.onSuccess(newWorld -> {
|
||||
Logging.fine("World clone success: " + newWorld);
|
||||
issuer.sendInfo(MVCorei18n.CLONE_SUCCESS, "{world}", newWorld.getName());
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World clone failure: " + failure);
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package com.onarandombox.MultiverseCore.commands;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import co.aikar.commands.annotation.Subcommand;
|
||||
@ -83,8 +82,7 @@ public class CreateCommand extends MultiverseCommand {
|
||||
@Optional
|
||||
@Syntax("--seed [seed] --generator [generator[:id]] --world-type [worldtype] --adjust-spawn --no-structures")
|
||||
@Description("{@@mv-core.create.flags.description}")
|
||||
String[] flags
|
||||
) {
|
||||
String[] flags) {
|
||||
ParsedCommandFlags parsedFlags = parseFlags(flags);
|
||||
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES, "{worldName}", worldName);
|
||||
@ -103,13 +101,13 @@ public class CreateCommand extends MultiverseCommand {
|
||||
.worldType(parsedFlags.flagValue("--world-type", WorldType.NORMAL, WorldType.class))
|
||||
.useSpawnAdjust(!parsedFlags.hasFlag("--no-adjust-spawn"))
|
||||
.generator(parsedFlags.flagValue("--generator", "", String.class))
|
||||
.generateStructures(!parsedFlags.hasFlag("--no-structures"))
|
||||
).onSuccess((success) -> {
|
||||
Logging.fine("World create success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
Logging.fine("World create failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
});
|
||||
.generateStructures(!parsedFlags.hasFlag("--no-structures")))
|
||||
.onSuccess(newWorld -> {
|
||||
Logging.fine("World create success: " + newWorld);
|
||||
issuer.sendInfo(MVCorei18n.CREATE_SUCCESS, "{world}", newWorld.getName());
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World create failure: " + failure);
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ public class DeleteCommand extends MultiverseCommand {
|
||||
() -> {
|
||||
issuer.sendInfo(MVCorei18n.DELETE_DELETING, "{world}", worldName);
|
||||
worldManager.deleteWorld(worldName)
|
||||
.onSuccess((success) -> {
|
||||
Logging.fine("World delete success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
.onSuccess(deletedWorldName -> {
|
||||
Logging.fine("World delete success: " + deletedWorldName);
|
||||
issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, "{world}", deletedWorldName);
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World delete failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
},
|
||||
this.commandManager.formatMessage(
|
||||
|
@ -78,13 +78,14 @@ public class ImportCommand extends MultiverseCommand {
|
||||
worldManager.importWorld(ImportWorldOptions.worldName(worldName)
|
||||
.environment(environment)
|
||||
.generator(parsedFlags.flagValue("--generator", String.class))
|
||||
.useSpawnAdjust(parsedFlags.hasFlag("--adjust-spawn"))
|
||||
).onSuccess((success) -> {
|
||||
Logging.fine("World create success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
Logging.fine("World create failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
});
|
||||
.useSpawnAdjust(parsedFlags.hasFlag("--adjust-spawn")))
|
||||
.onSuccess(newWorld -> {
|
||||
Logging.fine("World import success: " + newWorld);
|
||||
issuer.sendInfo(MVCorei18n.IMPORT_SUCCESS, "{world}", newWorld.getName());
|
||||
})
|
||||
.onFailure(failure -> {
|
||||
Logging.fine("World import failure: " + failure);
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -45,12 +45,12 @@ public class LoadCommand extends MultiverseCommand {
|
||||
) {
|
||||
issuer.sendInfo(MVCorei18n.LOAD_LOADING, "{world}", worldName);
|
||||
worldManager.loadWorld(worldName)
|
||||
.onSuccess((success) -> {
|
||||
Logging.fine("World load success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
.onSuccess(newWorld -> {
|
||||
Logging.fine("World load success: " + newWorld);
|
||||
issuer.sendInfo(MVCorei18n.LOAD_SUCCESS, "{world}", newWorld.getName());
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World load failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -85,12 +85,12 @@ public class RegenCommand extends MultiverseCommand {
|
||||
.keepWorldConfig(!parsedFlags.hasFlag("--reset-world-config"))
|
||||
.keepGameRule(!parsedFlags.hasFlag("--reset-gamerules"))
|
||||
.keepWorldBorder(!parsedFlags.hasFlag("--reset-world-border"))
|
||||
).onSuccess((success) -> {
|
||||
Logging.fine("World create success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
Logging.fine("World create failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
).onSuccess(newWorld -> {
|
||||
Logging.fine("World regen success: " + newWorld);
|
||||
issuer.sendInfo(MVCorei18n.REGEN_SUCCESS, "{world}", newWorld.getName());
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World regen failure: " + failure);
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
},
|
||||
this.commandManager.formatMessage(
|
||||
|
@ -12,6 +12,7 @@ import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandIssuer;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.worldnew.WorldManager;
|
||||
import jakarta.inject.Inject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -43,12 +44,12 @@ public class RemoveCommand extends MultiverseCommand {
|
||||
String worldName
|
||||
) {
|
||||
worldManager.removeWorld(worldName)
|
||||
.onSuccess((success) -> {
|
||||
Logging.fine("World remove success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
.onSuccess(removedWorldName -> {
|
||||
Logging.fine("World remove success: " + removedWorldName);
|
||||
issuer.sendInfo(MVCorei18n.REMOVEWORLD_REMOVED, "{world}", removedWorldName);
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World remove failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ public class UnloadCommand extends MultiverseCommand {
|
||||
) {
|
||||
issuer.sendInfo(MVCorei18n.UNLOAD_UNLOADING, "{world}", world.getAlias());
|
||||
worldManager.unloadWorld(world)
|
||||
.onSuccess((success) -> {
|
||||
Logging.fine("World unload success: " + success);
|
||||
issuer.sendInfo(success.getReasonMessage());
|
||||
}).onFailure((failure) -> {
|
||||
.onSuccess(loadedWorld -> {
|
||||
Logging.fine("World unload success: " + loadedWorld);
|
||||
issuer.sendInfo(MVCorei18n.UNLOAD_SUCCESS, "{world}", loadedWorld.getName());
|
||||
}).onFailure(failure -> {
|
||||
Logging.fine("World unload failure: " + failure);
|
||||
issuer.sendError(failure.getReasonMessage());
|
||||
issuer.sendError(failure.getFailureMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class MVWorldListener implements InjectableListener {
|
||||
return;
|
||||
}
|
||||
worldManager.unloadWorld(event.getWorld()).onFailure(failure -> {
|
||||
if (failure.getFailureReason() != UnloadWorldResult.Failure.WORLD_ALREADY_UNLOADING) {
|
||||
if (failure.getFailureReason() != UnloadWorldResult.WORLD_ALREADY_UNLOADING) {
|
||||
Logging.severe("Failed to unload world: " + failure);
|
||||
}
|
||||
});
|
||||
@ -60,7 +60,7 @@ public class MVWorldListener implements InjectableListener {
|
||||
.peek(world -> {
|
||||
Logging.fine("Loading world: " + world.getName());
|
||||
worldManager.loadWorld(world).onFailure(failure -> {
|
||||
if (failure.getFailureReason() != LoadWorldResult.Failure.WORLD_ALREADY_LOADING) {
|
||||
if (failure.getFailureReason() != LoadWorldResult.WORLD_ALREADY_LOADING) {
|
||||
Logging.severe("Failed to load world: " + failure);
|
||||
}
|
||||
});
|
||||
|
@ -7,6 +7,8 @@ import com.onarandombox.MultiverseCore.utils.message.MessageReplacement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum MVCorei18n implements MessageKeyProvider {
|
||||
// BEGIN CHECKSTYLE-SUPPRESSION: Javadoc
|
||||
|
||||
// config status
|
||||
CONFIG_SAVE_FAILED,
|
||||
CONFIG_NODE_NOTFOUND,
|
||||
@ -16,6 +18,7 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
|
||||
// clone command
|
||||
CLONE_CLONING,
|
||||
CLONE_SUCCESS,
|
||||
|
||||
// Coordinates command
|
||||
COORDINATES_INFO_TITLE,
|
||||
@ -34,6 +37,7 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
CREATE_PROPERTIES_GENERATOR,
|
||||
CREATE_PROPERTIES_STRUCTURES,
|
||||
CREATE_LOADING,
|
||||
CREATE_SUCCESS,
|
||||
|
||||
// delete command
|
||||
DELETE_DELETING,
|
||||
@ -56,13 +60,16 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
|
||||
// import command
|
||||
IMPORT_IMPORTING,
|
||||
IMPORT_SUCCESS,
|
||||
|
||||
// load command
|
||||
LOAD_LOADING,
|
||||
LOAD_SUCCESS,
|
||||
|
||||
// regen command
|
||||
REGEN_REGENERATING,
|
||||
REGEN_PROMPT,
|
||||
REGEN_SUCCESS,
|
||||
|
||||
// reload command
|
||||
RELOAD_RELOADING,
|
||||
@ -77,6 +84,7 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
|
||||
// unload command
|
||||
UNLOAD_UNLOADING,
|
||||
UNLOAD_SUCCESS,
|
||||
|
||||
// debug command
|
||||
DEBUG_INFO_OFF,
|
||||
@ -94,46 +102,39 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
ENTRYCHECK_NOWORLDACCESS,
|
||||
|
||||
// world manager result
|
||||
CLONEWORLD_CLONED,
|
||||
CLONEWORLD_INVALIDWORLDNAME,
|
||||
CLONEWORLD_WORLDEXISTFOLDER,
|
||||
CLONEWORLD_WORLDEXISTUNLOADED,
|
||||
CLONEWORLD_WORLDEXISTLOADED,
|
||||
CLONEWORLD_COPYFAILED,
|
||||
|
||||
CREATEWORLD_CREATED,
|
||||
CREATEWORLD_INVALIDWORLDNAME,
|
||||
CREATEWORLD_WORLDEXISTFOLDER,
|
||||
CREATEWORLD_WORLDEXISTUNLOADED,
|
||||
CREATEWORLD_WORLDEXISTLOADED,
|
||||
CREATEWORLD_BUKKITCREATIONFAILED,
|
||||
|
||||
DELETEWORLD_DELETED,
|
||||
DELETE_SUCCESS,
|
||||
DELETEWORLD_WORLDNONEXISTENT,
|
||||
DELETEWORLD_LOADFAILED,
|
||||
DELETEWORLD_WORLDFOLDERNOTFOUND,
|
||||
DELETEWORLD_FAILEDTODELETEFOLDER,
|
||||
|
||||
IMPORTWORLD_IMPORTED,
|
||||
IMPORTWORLD_INVALIDWORLDNAME,
|
||||
IMPORTWORLD_WORLDFOLDERINVALID,
|
||||
IMPORTWORLD_WORLDEXISTUNLOADED,
|
||||
IMPORTWORLD_WORLDEXISTLOADED,
|
||||
IMPORTWORLD_BUKKITCREATIONFAILED,
|
||||
|
||||
LOADWORLD_LOADED,
|
||||
LOADWORLD_WORLDALREADYLOADING,
|
||||
LOADWORLD_WORLDNONEXISTENT,
|
||||
LOADWORLD_WORLDEXISTFOLDER,
|
||||
LOADWORLD_WORLDEXISTLOADED,
|
||||
LOADWORLD_BUKKITCREATIONFAILED,
|
||||
|
||||
REGENWORLD_REGENERATED,
|
||||
|
||||
REMOVEWORLD_REMOVED,
|
||||
REMOVEWORLD_WORLDNONEXISTENT,
|
||||
|
||||
UNLOADWORLD_UNLOADED,
|
||||
UNLOADWORLD_WORLDALREADYUNLOADING,
|
||||
UNLOADWORLD_WORLDNONEXISTENT,
|
||||
UNLOADWORLD_WORLDUNLOADED,
|
||||
@ -141,9 +142,9 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
|
||||
// generic
|
||||
GENERIC_SUCCESS,
|
||||
GENERIC_FAILURE
|
||||
GENERIC_FAILURE;
|
||||
|
||||
;
|
||||
// END CHECKSTYLE-SUPPRESSION: Javadoc
|
||||
|
||||
private final MessageKey key = MessageKey.of("mv-core." + this.name().replace('_', '.').toLowerCase());
|
||||
|
||||
|
@ -0,0 +1,338 @@
|
||||
package com.onarandombox.MultiverseCore.utils.result;
|
||||
|
||||
import com.onarandombox.MultiverseCore.utils.message.Message;
|
||||
import com.onarandombox.MultiverseCore.utils.message.MessageReplacement;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Represents an attempt to process a value that can fail with a reason that has a localized message.
|
||||
*
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
*/
|
||||
public sealed interface Attempt<T, F extends FailureReason> permits Attempt.Success, Attempt.Failure {
|
||||
|
||||
/**
|
||||
* Creates a new success attempt.
|
||||
*
|
||||
* @param value The value.
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
* @return The new success attempt.
|
||||
*/
|
||||
static <T, F extends FailureReason> Attempt<T, F> success(T value) {
|
||||
return new Success<>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new failure attempt.
|
||||
*
|
||||
* @param failureReason The reason for failure.
|
||||
* @param messageReplacements The replacements for the failure message.
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
* @return The new failure attempt.
|
||||
*/
|
||||
static <T, F extends FailureReason> Attempt<T, F> failure(
|
||||
F failureReason, MessageReplacement... messageReplacements) {
|
||||
return new Failure<>(failureReason, Message.of(failureReason, "Failed!", messageReplacements));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new failure attempt with a custom message.
|
||||
*
|
||||
* @param failureReason The reason for failure.
|
||||
* @param message The custom message for failure. This will override the default message.
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
* @return The new failure attempt.
|
||||
*/
|
||||
static <T, F extends FailureReason> Attempt<T, F> failure(F failureReason, Message message) {
|
||||
return new Failure<>(failureReason, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this attempt. Exceptions will be thrown if this is a failure attempt.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
T get();
|
||||
|
||||
/**
|
||||
* Gets the reason for failure. Exceptions will be thrown if this is a success attempt.
|
||||
*
|
||||
* @return The reason for failure.
|
||||
*/
|
||||
F getFailureReason();
|
||||
|
||||
/**
|
||||
* Gets the message for failure. Exceptions will be thrown if this is a success attempt.
|
||||
*
|
||||
* @return The message for failure.
|
||||
*/
|
||||
Message getFailureMessage();
|
||||
|
||||
/**
|
||||
* Returns whether this attempt is a success.
|
||||
*
|
||||
* @return Whether this attempt is a success.
|
||||
*/
|
||||
default boolean isSuccess() {
|
||||
return this instanceof Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this attempt is a failure.
|
||||
*
|
||||
* @return Whether this attempt is a failure.
|
||||
*/
|
||||
default boolean isFailure() {
|
||||
return this instanceof Failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the value if this is a success attempt.
|
||||
*
|
||||
* @param consumer The consumer with the value.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> peek(Consumer<T> consumer) {
|
||||
if (this instanceof Success) {
|
||||
consumer.accept(get());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the value to another value if this is a success attempt.
|
||||
*
|
||||
* @param mapper The mapper.
|
||||
* @param <U> The type of the new value.
|
||||
* @return The new attempt.
|
||||
*/
|
||||
default <U> Attempt<U, F> map(Function<? super T, ? extends U> mapper) {
|
||||
if (this instanceof Success) {
|
||||
return new Success<>(mapper.apply(get()));
|
||||
} else {
|
||||
return new Failure<>(getFailureReason(), getFailureMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the value to another attempt if this is a success attempt.
|
||||
*
|
||||
* @param mapper The mapper.
|
||||
* @param <U> The type of the new value.
|
||||
* @return The new attempt.
|
||||
*/
|
||||
default <U> Attempt<U, F> map(Supplier<? extends U> mapper) {
|
||||
if (this instanceof Success) {
|
||||
return new Success<>(mapper.get());
|
||||
} else {
|
||||
return new Failure<>(getFailureReason(), getFailureMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the value to another attempt with the same fail reason if this is a success attempt.
|
||||
*
|
||||
* @param mapper The mapper.
|
||||
* @param <U> The type of the new value.
|
||||
* @return The new attempt.
|
||||
*/
|
||||
default <U> Attempt<U, F> mapAttempt(Function<? super T, Attempt<U, F>> mapper) {
|
||||
if (this instanceof Success) {
|
||||
return mapper.apply(get());
|
||||
} else {
|
||||
return new Failure<>(getFailureReason(), getFailureMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the value to another attempt with the same fail reason if this is a success attempt.
|
||||
*
|
||||
* @param mapper The mapper.
|
||||
* @param <U> The type of the new value.
|
||||
* @return The new attempt.
|
||||
*/
|
||||
default <U> Attempt<U, F> mapAttempt(Supplier<Attempt<U, F>> mapper) {
|
||||
if (this instanceof Success) {
|
||||
return mapper.get();
|
||||
} else {
|
||||
return new Failure<>(getFailureReason(), getFailureMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps to another attempt with a different fail reason.
|
||||
*
|
||||
* @param failureReason The new fail reason.
|
||||
* @param <UF> The type of the new fail reason.
|
||||
* @return The new attempt.
|
||||
*/
|
||||
default <UF extends FailureReason> Attempt<T, UF> transform(UF failureReason) {
|
||||
if (this instanceof Success) {
|
||||
return new Success<>(get());
|
||||
} else {
|
||||
return new Failure<>(failureReason, getFailureMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls either the failure or success function depending on the result type.
|
||||
*
|
||||
* @param failureMapper The failure function.
|
||||
* @param successMapper The success function.
|
||||
* @param <N> The type of the new value.
|
||||
* @return The result of the function.
|
||||
*/
|
||||
default <N> N fold(Function<Failure<T, F>, N> failureMapper, Function<T, N> successMapper) {
|
||||
if (this instanceof Success) {
|
||||
return successMapper.apply(get());
|
||||
} else {
|
||||
return failureMapper.apply((Failure<T, F>) this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given runnable if this is a success attempt.
|
||||
*
|
||||
* @param runnable The runnable.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> onSuccess(Runnable runnable) {
|
||||
if (this instanceof Success) {
|
||||
runnable.run();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given consumer if this is a success attempt.
|
||||
*
|
||||
* @param consumer The consumer with the value.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> onSuccess(Consumer<T> consumer) {
|
||||
if (this instanceof Success) {
|
||||
consumer.accept(get());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given consumer if this is a failure attempt.
|
||||
*
|
||||
* @param runnable The runnable.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> onFailure(Runnable runnable) {
|
||||
if (this instanceof Failure) {
|
||||
runnable.run();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given consumer if this is a failure attempt.
|
||||
*
|
||||
* @param consumer The consumer with the failure instance.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> onFailure(Consumer<Failure<T, F>> consumer) {
|
||||
if (this instanceof Failure) {
|
||||
consumer.accept((Failure<T, F>) this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given runnable if this is a failure attempt.
|
||||
*
|
||||
* @param consumer The consumer with the failure reason.
|
||||
* @return This attempt.
|
||||
*/
|
||||
default Attempt<T, F> onFailureReason(Consumer<F> consumer) {
|
||||
if (this instanceof Failure) {
|
||||
consumer.accept(getFailureReason());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a successful attempt with a value.
|
||||
*
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
*/
|
||||
final class Success<T, F extends FailureReason> implements Attempt<T, F> {
|
||||
private final T value;
|
||||
|
||||
Success(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public F getFailureReason() {
|
||||
throw new UnsupportedOperationException("No failure reason as attempt is a success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message getFailureMessage() {
|
||||
throw new UnsupportedOperationException("No failure message as attempt is a success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Success{"
|
||||
+ "value=" + value
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a failed attempt with a reason.
|
||||
*
|
||||
* @param <T> The type of the value.
|
||||
* @param <F> The type of failure reason.
|
||||
*/
|
||||
final class Failure<T, F extends FailureReason> implements Attempt<T, F> {
|
||||
private final F failureReason;
|
||||
private final Message message;
|
||||
|
||||
Failure(F failureReason, Message message) {
|
||||
this.failureReason = failureReason;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
throw new UnsupportedOperationException("No value as attempt is a failure");
|
||||
}
|
||||
|
||||
@Override
|
||||
public F getFailureReason() {
|
||||
return failureReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message getFailureMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Failure{"
|
||||
+ "reason=" + failureReason
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
@ -5,51 +5,126 @@ import com.onarandombox.MultiverseCore.utils.message.MessageReplacement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public sealed interface Result<S extends SuccessReason, F extends FailureReason> permits Result.Success, Result.Failure {
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> success() {
|
||||
return new Success<>(null, Message.of("Success!"));
|
||||
}
|
||||
/**
|
||||
* Represents result of an operation with a reason for success or failure that has localized messages.
|
||||
*
|
||||
* @param <S> The type of success reason.
|
||||
* @param <F> The type of failure reason.
|
||||
*/
|
||||
public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
permits Result.Success, Result.Failure {
|
||||
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> success(S successReason, MessageReplacement...replacements) {
|
||||
/**
|
||||
* Creates a new success result.
|
||||
*
|
||||
* @param successReason The reason for success.
|
||||
* @param replacements The replacements for the success message.
|
||||
* @param <F> The type of failure reason.
|
||||
* @param <S> The type of success reason.
|
||||
* @return The new success result.
|
||||
*/
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> success(
|
||||
S successReason, MessageReplacement... replacements) {
|
||||
return new Success<>(successReason, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new success result.
|
||||
*
|
||||
* @param successReason The reason for success.
|
||||
* @param message The custom message for success. This will override the default message.
|
||||
* @param <F> The type of failure reason.
|
||||
* @param <S> The type of success reason.
|
||||
* @return The new success result.
|
||||
*/
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> success(S successReason, Message message) {
|
||||
return new Success<>(successReason, message);
|
||||
}
|
||||
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> failure() {
|
||||
return new Failure<>(null, Message.of("Failed!"));
|
||||
}
|
||||
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> failure(F failureReason, MessageReplacement...replacements) {
|
||||
/**
|
||||
* Creates a new failure result.
|
||||
*
|
||||
* @param failureReason The reason for failure.
|
||||
* @param replacements The replacements for the failure message.
|
||||
* @param <F> The type of failure reason.
|
||||
* @param <S> The type of success reason.
|
||||
* @return The new failure result.
|
||||
*/
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> failure(
|
||||
F failureReason, MessageReplacement... replacements) {
|
||||
return new Failure<>(failureReason, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new failure result.
|
||||
*
|
||||
* @param failureReason The reason for failure.
|
||||
* @param message The custom message for failure. This will override the default message.
|
||||
* @param <F> The type of failure reason.
|
||||
* @param <S> The type of success reason.
|
||||
* @return The new failure result.
|
||||
*/
|
||||
static <F extends FailureReason, S extends SuccessReason> Result<S, F> failure(F failureReason, Message message) {
|
||||
return new Failure<>(failureReason, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this result is a success.
|
||||
*
|
||||
* @return Whether this result is a success.
|
||||
*/
|
||||
boolean isSuccess();
|
||||
|
||||
/**
|
||||
* Returns whether this result is a failure.
|
||||
*
|
||||
* @return Whether this result is a failure.
|
||||
*/
|
||||
boolean isFailure();
|
||||
|
||||
/**
|
||||
* Returns the reason for success.
|
||||
*
|
||||
* @return The reason for success.
|
||||
*/
|
||||
S getSuccessReason();
|
||||
|
||||
/**
|
||||
* Returns the reason for failure.
|
||||
*
|
||||
* @return The reason for failure.
|
||||
*/
|
||||
F getFailureReason();
|
||||
|
||||
/**
|
||||
* Returns the message for the reason of this result.
|
||||
*
|
||||
* @return The message for the reason.
|
||||
*/
|
||||
@NotNull Message getReasonMessage();
|
||||
|
||||
default Result<S, F> onSuccess(Consumer<Success<F, S>> consumer) {
|
||||
/**
|
||||
* Executes the given consumer if this result is a success.
|
||||
*
|
||||
* @param consumer The consumer with success object.
|
||||
* @return This result.
|
||||
*/
|
||||
default Result<S, F> onSuccess(Consumer<Success<S, F>> consumer) {
|
||||
if (this instanceof Success) {
|
||||
consumer.accept((Success<F, S>) this);
|
||||
consumer.accept((Success<S, F>) this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given consumer if this result is a failure.
|
||||
*
|
||||
* @param consumer The consumer with failure object.
|
||||
* @return This result.
|
||||
*/
|
||||
default Result<S, F> onFailure(Consumer<Failure<S, F>> consumer) {
|
||||
if (this instanceof Failure) {
|
||||
consumer.accept((Failure<S, F>) this);
|
||||
@ -57,6 +132,13 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given consumer if this result is a success and the success reason matches the given reason.
|
||||
*
|
||||
* @param successReason The success reason to match.
|
||||
* @param consumer The consumer with success reason.
|
||||
* @return This result.
|
||||
*/
|
||||
default Result<S, F> onSuccessReason(S successReason, Consumer<S> consumer) {
|
||||
if (this.isSuccess() && this.getSuccessReason() == successReason) {
|
||||
consumer.accept(this.getSuccessReason());
|
||||
@ -64,6 +146,13 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given consumer if this result is a failure and the failure reason matches the given reason.
|
||||
*
|
||||
* @param failureReason The failure reason to match.
|
||||
* @param consumer The consumer with failure reason.
|
||||
* @return This result.
|
||||
*/
|
||||
default Result<S, F> onFailureReason(F failureReason, Consumer<F> consumer) {
|
||||
if (this.isFailure() && this.getFailureReason() == failureReason) {
|
||||
consumer.accept(this.getFailureReason());
|
||||
@ -71,13 +160,25 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
return this;
|
||||
}
|
||||
|
||||
default Result<S, F> onSuccessThen(Function<Success<F, S>, Result<S, F>> function) {
|
||||
/**
|
||||
* Executes the given function if this result is a success and returns the result of the function.
|
||||
*
|
||||
* @param function The function with success object.
|
||||
* @return The result of the function.
|
||||
*/
|
||||
default Result<S, F> onSuccessThen(Function<Success<S, F>, Result<S, F>> function) {
|
||||
if (this instanceof Success) {
|
||||
return function.apply((Success<F, S>) this);
|
||||
return function.apply((Success<S, F>) this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given function if this result is a failure and returns the result of the function.
|
||||
*
|
||||
* @param function The function with failure object.
|
||||
* @return The result of the function.
|
||||
*/
|
||||
default Result<S, F> onFailureThen(Function<Failure<S, F>, Result<S, F>> function) {
|
||||
if (this instanceof Failure) {
|
||||
return function.apply((Failure<S, F>) this);
|
||||
@ -85,25 +186,39 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
return this;
|
||||
}
|
||||
|
||||
default <R> R fold(Function<Failure<S, F>, R> failureFunc, Function<Success<F, S>, R> successFunc) {
|
||||
/**
|
||||
* Executes either the failure or success function depending on the result type.
|
||||
*
|
||||
* @param failureFunc The function with success reason.
|
||||
* @param successFunc The function with success reason.
|
||||
* @param <R> The type of the result.
|
||||
* @return The result of the function.
|
||||
*/
|
||||
default <R> R fold(Function<Failure<S, F>, R> failureFunc, Function<Success<S, F>, R> successFunc) {
|
||||
if (this instanceof Failure) {
|
||||
return failureFunc.apply((Failure<S, F>) this);
|
||||
} else if (this instanceof Success) {
|
||||
return successFunc.apply((Success<F, S>) this);
|
||||
return successFunc.apply((Success<S, F>) this);
|
||||
}
|
||||
throw new IllegalStateException("Unknown result type: " + this.getClass().getName());
|
||||
}
|
||||
|
||||
final class Success<F extends FailureReason, S extends SuccessReason> implements Result<S, F> {
|
||||
/**
|
||||
* The class for a successful result.
|
||||
*
|
||||
* @param <F> The type of failure reason.
|
||||
* @param <S> The type of success reason.
|
||||
*/
|
||||
final class Success<S extends SuccessReason, F extends FailureReason> implements Result<S, F> {
|
||||
private final S successReason;
|
||||
private final Message message;
|
||||
|
||||
public Success(S successReason, Message message) {
|
||||
Success(S successReason, Message message) {
|
||||
this.successReason = successReason;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Success(S successReason, MessageReplacement[] replacements) {
|
||||
Success(S successReason, MessageReplacement[] replacements) {
|
||||
this.successReason = successReason;
|
||||
this.message = Message.of(successReason, "Success!", replacements);
|
||||
}
|
||||
@ -125,7 +240,7 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
|
||||
@Override
|
||||
public F getFailureReason() {
|
||||
throw new NoSuchElementException("No reason for failure");
|
||||
throw new UnsupportedOperationException("No reason for success");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -135,24 +250,30 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Success{" +
|
||||
"reason=" + successReason +
|
||||
'}';
|
||||
return "Success{"
|
||||
+ "reason=" + successReason
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class for a failed result.
|
||||
*
|
||||
* @param <S> The type of success reason.
|
||||
* @param <F> The type of failure reason.
|
||||
*/
|
||||
final class Failure<S extends SuccessReason, F extends FailureReason> implements Result<S, F> {
|
||||
private final F failureReason;
|
||||
private final Message message;
|
||||
|
||||
public Failure(F failureReason, Message message) {
|
||||
Failure(F failureReason, Message message) {
|
||||
this.failureReason = failureReason;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Failure(F failureReason, MessageReplacement[] replacements) {
|
||||
Failure(F failureReason, MessageReplacement[] replacements) {
|
||||
this.failureReason = failureReason;
|
||||
this.message = Message.of(failureReason, "Success!", replacements);
|
||||
this.message = Message.of(failureReason, "Failed!", replacements);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -167,7 +288,7 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
|
||||
@Override
|
||||
public S getSuccessReason() {
|
||||
throw new NoSuchElementException("No reason for failure");
|
||||
throw new UnsupportedOperationException("No reason for failure");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -182,9 +303,9 @@ public sealed interface Result<S extends SuccessReason, F extends FailureReason>
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Failure{" +
|
||||
"reason=" + failureReason +
|
||||
'}';
|
||||
return "Failure{"
|
||||
+ "reason=" + failureReason
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
package com.onarandombox.MultiverseCore.utils.result;
|
@ -6,9 +6,8 @@ import com.onarandombox.MultiverseCore.api.BlockSafety;
|
||||
import com.onarandombox.MultiverseCore.api.LocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.message.MessageReplacement;
|
||||
import com.onarandombox.MultiverseCore.utils.result.Attempt;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.Result;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigManager;
|
||||
import com.onarandombox.MultiverseCore.worldnew.generators.GeneratorProvider;
|
||||
@ -47,6 +46,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.onarandombox.MultiverseCore.utils.message.MessageReplacement.replace;
|
||||
import static com.onarandombox.MultiverseCore.worldnew.helpers.DataStore.WorldBorderStore;
|
||||
@ -169,25 +169,22 @@ public class WorldManager {
|
||||
* @param options The options for customizing the creation of a new world.
|
||||
* @return The result of the creation.
|
||||
*/
|
||||
public Result<CreateWorldResult.Success, CreateWorldResult.Failure> createWorld(CreateWorldOptions options) {
|
||||
return invalidateCreateWorldOptions(options).getOrElse(() -> createValidatedWorld(options));
|
||||
public Attempt<LoadedMultiverseWorld, CreateWorldResult> createWorld(CreateWorldOptions options) {
|
||||
return validateCreateWorldOptions(options).mapAttempt(this::createValidatedWorld);
|
||||
}
|
||||
|
||||
private Option<Result<CreateWorldResult.Success, CreateWorldResult.Failure>> invalidateCreateWorldOptions(
|
||||
private Attempt<CreateWorldOptions, CreateWorldResult> validateCreateWorldOptions(
|
||||
CreateWorldOptions options) {
|
||||
Result<CreateWorldResult.Success, CreateWorldResult.Failure> result = null;
|
||||
|
||||
if (!worldNameChecker.isValidWorldName(options.worldName())) {
|
||||
result = worldActionResult(CreateWorldResult.Failure.INVALID_WORLDNAME, options.worldName());
|
||||
return worldActionResult(CreateWorldResult.INVALID_WORLDNAME, options.worldName());
|
||||
} else if (getLoadedWorld(options.worldName()).isDefined()) {
|
||||
result = worldActionResult(CreateWorldResult.Failure.WORLD_EXIST_LOADED, options.worldName());
|
||||
return worldActionResult(CreateWorldResult.WORLD_EXIST_LOADED, options.worldName());
|
||||
} else if (getWorld(options.worldName()).isDefined()) {
|
||||
result = worldActionResult(CreateWorldResult.Failure.WORLD_EXIST_UNLOADED, options.worldName());
|
||||
return worldActionResult(CreateWorldResult.WORLD_EXIST_UNLOADED, options.worldName());
|
||||
} else if (hasWorldFolder(options.worldName())) {
|
||||
result = worldActionResult(CreateWorldResult.Failure.WORLD_EXIST_FOLDER, options.worldName());
|
||||
return worldActionResult(CreateWorldResult.WORLD_EXIST_FOLDER, options.worldName());
|
||||
}
|
||||
|
||||
return Option.of(result);
|
||||
return worldActionResult(options);
|
||||
}
|
||||
|
||||
private boolean hasWorldFolder(String worldName) {
|
||||
@ -195,21 +192,25 @@ public class WorldManager {
|
||||
return worldFolder.exists();
|
||||
}
|
||||
|
||||
private Result<CreateWorldResult.Success, CreateWorldResult.Failure> createValidatedWorld(
|
||||
private Attempt<LoadedMultiverseWorld, CreateWorldResult> createValidatedWorld(
|
||||
CreateWorldOptions options) {
|
||||
String parsedGenerator = parseGenerator(options.worldName(), options.generator());
|
||||
return createBukkitWorld(WorldCreator.name(options.worldName())
|
||||
WorldCreator worldCreator = WorldCreator.name(options.worldName())
|
||||
.environment(options.environment())
|
||||
.generateStructures(options.generateStructures())
|
||||
.generator(parsedGenerator)
|
||||
.seed(options.seed())
|
||||
.type(options.worldType())).fold(
|
||||
exception -> worldActionResult(CreateWorldResult.Failure.BUKKIT_CREATION_FAILED,
|
||||
options.worldName(), exception.getMessage()),
|
||||
world -> {
|
||||
newLoadedMultiverseWorld(world, parsedGenerator, options.useSpawnAdjust());
|
||||
return worldActionResult(CreateWorldResult.Success.CREATED, world.getName());
|
||||
});
|
||||
.type(options.worldType());
|
||||
return createBukkitWorld(worldCreator).fold(
|
||||
exception -> worldActionResult(CreateWorldResult.BUKKIT_CREATION_FAILED,
|
||||
options.worldName(), exception),
|
||||
world -> {
|
||||
LoadedMultiverseWorld loadedWorld = newLoadedMultiverseWorld(
|
||||
world,
|
||||
parsedGenerator,
|
||||
options.useSpawnAdjust());
|
||||
return worldActionResult(loadedWorld);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,39 +219,41 @@ public class WorldManager {
|
||||
* @param options The options for customizing the import of an existing world folder.
|
||||
* @return The result of the import.
|
||||
*/
|
||||
public Result<ImportWorldResult.Success, ImportWorldResult.Failure> importWorld(ImportWorldOptions options) {
|
||||
return invalidateImportWorldOptions(options).getOrElse(() -> importValidatedWorld(options));
|
||||
}
|
||||
|
||||
private Option<Result<ImportWorldResult.Success, ImportWorldResult.Failure>> invalidateImportWorldOptions(
|
||||
public Attempt<LoadedMultiverseWorld, ImportWorldResult> importWorld(
|
||||
ImportWorldOptions options) {
|
||||
Result<ImportWorldResult.Success, ImportWorldResult.Failure> result = null;
|
||||
|
||||
if (!worldNameChecker.isValidWorldName(options.worldName())) {
|
||||
result = worldActionResult(ImportWorldResult.Failure.INVALID_WORLDNAME, options.worldName());
|
||||
} else if (!worldNameChecker.isValidWorldFolder(options.worldName())) {
|
||||
result = worldActionResult(ImportWorldResult.Failure.WORLD_FOLDER_INVALID, options.worldName());
|
||||
} else if (isLoadedWorld(options.worldName())) {
|
||||
result = worldActionResult(ImportWorldResult.Failure.WORLD_EXIST_LOADED, options.worldName());
|
||||
} else if (isWorld(options.worldName())) {
|
||||
result = worldActionResult(ImportWorldResult.Failure.WORLD_EXIST_UNLOADED, options.worldName());
|
||||
}
|
||||
|
||||
return Option.of(result);
|
||||
return validateImportWorldOptions(options).mapAttempt(this::doImportWorld);
|
||||
}
|
||||
|
||||
private Result<ImportWorldResult.Success, ImportWorldResult.Failure> importValidatedWorld(
|
||||
private Attempt<ImportWorldOptions, ImportWorldResult> validateImportWorldOptions(
|
||||
ImportWorldOptions options) {
|
||||
String worldName = options.worldName();
|
||||
if (!worldNameChecker.isValidWorldName(worldName)) {
|
||||
return worldActionResult(ImportWorldResult.INVALID_WORLDNAME, worldName);
|
||||
} else if (!worldNameChecker.isValidWorldFolder(worldName)) {
|
||||
return worldActionResult(ImportWorldResult.WORLD_FOLDER_INVALID, worldName);
|
||||
} else if (isLoadedWorld(worldName)) {
|
||||
return worldActionResult(ImportWorldResult.WORLD_EXIST_LOADED, worldName);
|
||||
} else if (isWorld(worldName)) {
|
||||
return worldActionResult(ImportWorldResult.WORLD_EXIST_UNLOADED, worldName);
|
||||
}
|
||||
return worldActionResult(options);
|
||||
}
|
||||
|
||||
private Attempt<LoadedMultiverseWorld, ImportWorldResult> doImportWorld(
|
||||
ImportWorldOptions options) {
|
||||
String parsedGenerator = parseGenerator(options.worldName(), options.generator());
|
||||
return createBukkitWorld(WorldCreator.name(options.worldName())
|
||||
WorldCreator worldCreator = WorldCreator.name(options.worldName())
|
||||
.environment(options.environment())
|
||||
.generator(parsedGenerator)).fold(
|
||||
exception -> worldActionResult(ImportWorldResult.Failure.BUKKIT_CREATION_FAILED,
|
||||
options.worldName(), exception.getMessage()),
|
||||
world -> {
|
||||
newLoadedMultiverseWorld(world, parsedGenerator, options.useSpawnAdjust());
|
||||
return worldActionResult(ImportWorldResult.Success.IMPORTED, options.worldName());
|
||||
});
|
||||
.generator(parsedGenerator);
|
||||
return createBukkitWorld(worldCreator).fold(
|
||||
exception -> worldActionResult(ImportWorldResult.BUKKIT_CREATION_FAILED,
|
||||
options.worldName(), exception),
|
||||
world -> {
|
||||
LoadedMultiverseWorld loadedWorld = newLoadedMultiverseWorld(world,
|
||||
parsedGenerator,
|
||||
options.useSpawnAdjust());
|
||||
return worldActionResult(loadedWorld);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,7 +276,8 @@ public class WorldManager {
|
||||
* @param generator The generator string.
|
||||
* @param adjustSpawn Whether to adjust spawn.
|
||||
*/
|
||||
private void newLoadedMultiverseWorld(@NotNull World world, @Nullable String generator, boolean adjustSpawn) {
|
||||
private LoadedMultiverseWorld newLoadedMultiverseWorld(
|
||||
@NotNull World world, @Nullable String generator, boolean adjustSpawn) {
|
||||
WorldConfig worldConfig = worldsConfigManager.addWorldConfig(world.getName());
|
||||
worldConfig.setAdjustSpawn(adjustSpawn);
|
||||
worldConfig.setGenerator(generator == null ? "" : generator);
|
||||
@ -289,6 +293,7 @@ public class WorldManager {
|
||||
locationManipulation);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
return loadedWorld;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,48 +302,44 @@ public class WorldManager {
|
||||
* @param worldName The name of the world to load.
|
||||
* @return The result of the load.
|
||||
*/
|
||||
public Result<LoadWorldResult.Success, LoadWorldResult.Failure> loadWorld(@NotNull String worldName) {
|
||||
public Attempt<LoadedMultiverseWorld, LoadWorldResult> loadWorld(@NotNull String worldName) {
|
||||
return getWorld(worldName)
|
||||
.map(this::loadWorld)
|
||||
.getOrElse(() -> worldNameChecker.isValidWorldFolder(worldName)
|
||||
? worldActionResult(LoadWorldResult.Failure.WORLD_EXIST_FOLDER, worldName)
|
||||
: worldActionResult(LoadWorldResult.Failure.WORLD_NON_EXISTENT, worldName));
|
||||
? worldActionResult(LoadWorldResult.WORLD_EXIST_FOLDER, worldName)
|
||||
: worldActionResult(LoadWorldResult.WORLD_NON_EXISTENT, worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an existing world in config.
|
||||
*
|
||||
* @param mvWorld The world to load.
|
||||
* @param world The world to load.
|
||||
* @return The result of the load.
|
||||
*/
|
||||
public Result<LoadWorldResult.Success, LoadWorldResult.Failure> loadWorld(@NotNull MultiverseWorld mvWorld) {
|
||||
return invalidateWorldToLoad(mvWorld).getOrElse(() -> loadValidatedWorld(mvWorld));
|
||||
public Attempt<LoadedMultiverseWorld, LoadWorldResult> loadWorld(@NotNull MultiverseWorld world) {
|
||||
return validateWorldToLoad(world).mapAttempt(this::doLoadWorld);
|
||||
}
|
||||
|
||||
private Option<Result<LoadWorldResult.Success, LoadWorldResult.Failure>> invalidateWorldToLoad(
|
||||
private Attempt<MultiverseWorld, LoadWorldResult> validateWorldToLoad(
|
||||
@NotNull MultiverseWorld mvWorld) {
|
||||
Result<LoadWorldResult.Success, LoadWorldResult.Failure> result = null;
|
||||
|
||||
if (loadTracker.contains(mvWorld.getName())) {
|
||||
// This is to prevent recursive calls by WorldLoadEvent
|
||||
Logging.fine("World already loading: " + mvWorld.getName());
|
||||
result = worldActionResult(LoadWorldResult.Failure.WORLD_ALREADY_LOADING, mvWorld.getName());
|
||||
return worldActionResult(LoadWorldResult.WORLD_ALREADY_LOADING, mvWorld.getName());
|
||||
} else if (isLoadedWorld(mvWorld)) {
|
||||
Logging.severe("World already loaded: " + mvWorld.getName());
|
||||
result = worldActionResult(LoadWorldResult.Failure.WORLD_EXIST_LOADED, mvWorld.getName());
|
||||
return worldActionResult(LoadWorldResult.WORLD_EXIST_LOADED, mvWorld.getName());
|
||||
}
|
||||
|
||||
return Option.of(result);
|
||||
return worldActionResult(mvWorld);
|
||||
}
|
||||
|
||||
private Result<LoadWorldResult.Success, LoadWorldResult.Failure> loadValidatedWorld(
|
||||
@NotNull MultiverseWorld mvWorld) {
|
||||
private Attempt<LoadedMultiverseWorld, LoadWorldResult> doLoadWorld(@NotNull MultiverseWorld mvWorld) {
|
||||
return createBukkitWorld(WorldCreator.name(mvWorld.getName())
|
||||
.environment(mvWorld.getEnvironment())
|
||||
.generator(Strings.isNullOrEmpty(mvWorld.getGenerator()) ? null : mvWorld.getGenerator())
|
||||
.seed(mvWorld.getSeed())).fold(
|
||||
exception -> worldActionResult(LoadWorldResult.Failure.BUKKIT_CREATION_FAILED,
|
||||
mvWorld.getName(), exception.getMessage()),
|
||||
exception -> worldActionResult(LoadWorldResult.BUKKIT_CREATION_FAILED,
|
||||
mvWorld.getName(), exception),
|
||||
world -> {
|
||||
// TODO: Check worldConfig null
|
||||
WorldConfig worldConfig = worldsConfigManager.getWorldConfig(mvWorld.getName());
|
||||
@ -350,7 +351,7 @@ public class WorldManager {
|
||||
locationManipulation);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
return worldActionResult(LoadWorldResult.Success.LOADED, loadedWorld.getName());
|
||||
return worldActionResult(loadedWorld);
|
||||
});
|
||||
}
|
||||
|
||||
@ -360,7 +361,7 @@ public class WorldManager {
|
||||
* @param world The bukkit world to unload.
|
||||
* @return The result of the unload action.
|
||||
*/
|
||||
public Result<UnloadWorldResult.Success, UnloadWorldResult.Failure> unloadWorld(@NotNull World world) {
|
||||
public Attempt<MultiverseWorld, UnloadWorldResult> unloadWorld(@NotNull World world) {
|
||||
return unloadWorld(world.getName());
|
||||
}
|
||||
|
||||
@ -370,12 +371,12 @@ public class WorldManager {
|
||||
* @param worldName The name of the world to unload.
|
||||
* @return The result of the unload action.
|
||||
*/
|
||||
public Result<UnloadWorldResult.Success, UnloadWorldResult.Failure> unloadWorld(@NotNull String worldName) {
|
||||
public Attempt<MultiverseWorld, UnloadWorldResult> unloadWorld(@NotNull String worldName) {
|
||||
return getLoadedWorld(worldName)
|
||||
.map(this::unloadWorld)
|
||||
.getOrElse(() -> isUnloadedWorld(worldName)
|
||||
? worldActionResult(UnloadWorldResult.Failure.WORLD_UNLOADED, worldName)
|
||||
: worldActionResult(UnloadWorldResult.Failure.WORLD_NON_EXISTENT, worldName));
|
||||
? worldActionResult(UnloadWorldResult.WORLD_UNLOADED, worldName)
|
||||
: worldActionResult(UnloadWorldResult.WORLD_NON_EXISTENT, worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -384,28 +385,28 @@ public class WorldManager {
|
||||
* @param world The multiverse world to unload.
|
||||
* @return The result of the unload action.
|
||||
*/
|
||||
public Result<UnloadWorldResult.Success, UnloadWorldResult.Failure> unloadWorld(
|
||||
public Attempt<MultiverseWorld, UnloadWorldResult> unloadWorld(
|
||||
@NotNull LoadedMultiverseWorld world) {
|
||||
if (unloadTracker.contains(world.getName())) {
|
||||
// This is to prevent recursive calls by WorldUnloadEvent
|
||||
Logging.fine("World already unloading: " + world.getName());
|
||||
return worldActionResult(UnloadWorldResult.Failure.WORLD_ALREADY_UNLOADING, world.getName());
|
||||
return worldActionResult(UnloadWorldResult.WORLD_ALREADY_UNLOADING, world.getName());
|
||||
}
|
||||
|
||||
// TODO: removePlayersFromWorld?
|
||||
|
||||
return unloadBukkitWorld(world.getBukkitWorld().getOrNull()).fold(
|
||||
exception -> worldActionResult(UnloadWorldResult.Failure.BUKKIT_UNLOAD_FAILED,
|
||||
world.getName(), exception.getMessage()),
|
||||
exception -> worldActionResult(UnloadWorldResult.BUKKIT_UNLOAD_FAILED,
|
||||
world.getName(), exception),
|
||||
success -> Option.of(loadedWorldsMap.remove(world.getName())).fold(
|
||||
() -> {
|
||||
Logging.severe("Failed to remove world from map: " + world.getName());
|
||||
return worldActionResult(UnloadWorldResult.Failure.WORLD_NON_EXISTENT, world.getName());
|
||||
return worldActionResult(UnloadWorldResult.WORLD_NON_EXISTENT, world.getName());
|
||||
},
|
||||
mvWorld -> {
|
||||
Logging.fine("Removed MultiverseWorld from map: " + world.getName());
|
||||
mvWorld.getWorldConfig().deferenceMVWorld();
|
||||
return worldActionResult(UnloadWorldResult.Success.UNLOADED, world.getName());
|
||||
return worldActionResult(getWorld(mvWorld.getName()).get());
|
||||
}));
|
||||
}
|
||||
|
||||
@ -416,11 +417,11 @@ public class WorldManager {
|
||||
* @param worldName The name of the world to remove.
|
||||
* @return The result of the remove.
|
||||
*/
|
||||
public Result<RemoveWorldResult.Success, RemoveWorldResult.Failure> removeWorld(
|
||||
public Attempt<String, RemoveWorldResult> removeWorld(
|
||||
@NotNull String worldName) {
|
||||
return getWorld(worldName)
|
||||
.map(this::removeWorld)
|
||||
.getOrElse(() -> worldActionResult(RemoveWorldResult.Failure.WORLD_NON_EXISTENT, worldName));
|
||||
.getOrElse(() -> worldActionResult(RemoveWorldResult.WORLD_NON_EXISTENT, worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -430,7 +431,7 @@ public class WorldManager {
|
||||
* @param world The multiverse world to remove.
|
||||
* @return The result of the remove.
|
||||
*/
|
||||
public Result<RemoveWorldResult.Success, RemoveWorldResult.Failure> removeWorld(@NotNull MultiverseWorld world) {
|
||||
public Attempt<String, RemoveWorldResult> removeWorld(@NotNull MultiverseWorld world) {
|
||||
return getLoadedWorld(world).fold(
|
||||
() -> removeWorldFromConfig(world),
|
||||
this::removeWorld);
|
||||
@ -443,13 +444,10 @@ public class WorldManager {
|
||||
* @param loadedWorld The multiverse world to remove.
|
||||
* @return The result of the remove.
|
||||
*/
|
||||
public Result<RemoveWorldResult.Success, RemoveWorldResult.Failure> removeWorld(
|
||||
@NotNull LoadedMultiverseWorld loadedWorld) {
|
||||
var result = unloadWorld(loadedWorld);
|
||||
if (result.isFailure()) {
|
||||
return Result.failure(RemoveWorldResult.Failure.UNLOAD_FAILED, result.getReasonMessage());
|
||||
}
|
||||
return removeWorldFromConfig(loadedWorld);
|
||||
public Attempt<String, RemoveWorldResult> removeWorld(@NotNull LoadedMultiverseWorld loadedWorld) {
|
||||
return unloadWorld(loadedWorld)
|
||||
.transform(RemoveWorldResult.UNLOAD_FAILED)
|
||||
.mapAttempt(this::removeWorldFromConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,14 +456,13 @@ public class WorldManager {
|
||||
* @param world The multiverse world to remove.
|
||||
* @return The result of the remove.
|
||||
*/
|
||||
private Result<RemoveWorldResult.Success, RemoveWorldResult.Failure>
|
||||
removeWorldFromConfig(@NotNull MultiverseWorld world) {
|
||||
private Attempt<String, RemoveWorldResult> removeWorldFromConfig(@NotNull MultiverseWorld world) {
|
||||
// Remove world from config
|
||||
worldsMap.remove(world.getName());
|
||||
worldsConfigManager.deleteWorldConfig(world.getName());
|
||||
saveWorldsConfig();
|
||||
|
||||
return Result.success(RemoveWorldResult.Success.REMOVED);
|
||||
return worldActionResult(world.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -475,10 +472,10 @@ public class WorldManager {
|
||||
* @param worldName The name of the world to delete.
|
||||
* @return The result of the delete action.
|
||||
*/
|
||||
public Result<DeleteWorldResult.Success, DeleteWorldResult.Failure> deleteWorld(@NotNull String worldName) {
|
||||
public Attempt<String, DeleteWorldResult> deleteWorld(@NotNull String worldName) {
|
||||
return getWorld(worldName)
|
||||
.map(this::deleteWorld)
|
||||
.getOrElse(() -> worldActionResult(DeleteWorldResult.Failure.WORLD_NON_EXISTENT, worldName));
|
||||
.getOrElse(() -> worldActionResult(DeleteWorldResult.WORLD_NON_EXISTENT, worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -488,15 +485,11 @@ public class WorldManager {
|
||||
* @param world The world to delete.
|
||||
* @return The result of the delete action.
|
||||
*/
|
||||
public Result<DeleteWorldResult.Success, DeleteWorldResult.Failure> deleteWorld(@NotNull MultiverseWorld world) {
|
||||
public Attempt<String, DeleteWorldResult> deleteWorld(@NotNull MultiverseWorld world) {
|
||||
return getLoadedWorld(world).fold(
|
||||
() -> {
|
||||
var result = loadWorld(world);
|
||||
if (result.isFailure()) {
|
||||
return worldActionResult(DeleteWorldResult.Failure.LOAD_FAILED, world.getName());
|
||||
}
|
||||
return deleteWorld(world);
|
||||
},
|
||||
() -> loadWorld(world)
|
||||
.transform(DeleteWorldResult.LOAD_FAILED)
|
||||
.mapAttempt(this::deleteWorld),
|
||||
this::deleteWorld);
|
||||
}
|
||||
|
||||
@ -506,25 +499,26 @@ public class WorldManager {
|
||||
* @param world The multiverse world to delete.
|
||||
* @return The result of the delete action.
|
||||
*/
|
||||
public Result<DeleteWorldResult.Success, DeleteWorldResult.Failure>
|
||||
deleteWorld(@NotNull LoadedMultiverseWorld world) {
|
||||
public Attempt<String, DeleteWorldResult> deleteWorld(@NotNull LoadedMultiverseWorld world) {
|
||||
// TODO: Possible config options to keep certain files
|
||||
AtomicReference<File> worldFolder = new AtomicReference<>();
|
||||
return validateWorldToDelete(world)
|
||||
.peek(worldFolder::set)
|
||||
.mapAttempt(() -> removeWorld(world).transform(DeleteWorldResult.REMOVE_FAILED))
|
||||
.mapAttempt(() -> filesManipulator.deleteFolder(worldFolder.get()).fold(
|
||||
exception -> worldActionResult(DeleteWorldResult.FAILED_TO_DELETE_FOLDER,
|
||||
world.getName(), exception),
|
||||
success -> worldActionResult(world.getName())));
|
||||
}
|
||||
|
||||
private Attempt<File, DeleteWorldResult> validateWorldToDelete(
|
||||
@NotNull LoadedMultiverseWorld world) {
|
||||
File worldFolder = world.getBukkitWorld().map(World::getWorldFolder).getOrNull();
|
||||
if (worldFolder == null || !worldNameChecker.isValidWorldFolder(worldFolder)) {
|
||||
Logging.severe("Failed to get world folder for world: " + world.getName());
|
||||
return worldActionResult(DeleteWorldResult.Failure.WORLD_FOLDER_NOT_FOUND, world.getName());
|
||||
return worldActionResult(DeleteWorldResult.WORLD_FOLDER_NOT_FOUND, world.getName());
|
||||
}
|
||||
|
||||
var result = removeWorld(world);
|
||||
if (result.isFailure()) {
|
||||
return Result.failure(DeleteWorldResult.Failure.REMOVE_FAILED, result.getReasonMessage());
|
||||
}
|
||||
|
||||
// Erase world files from disk
|
||||
// TODO: Possible config options to keep certain files
|
||||
return filesManipulator.deleteFolder(worldFolder).fold(
|
||||
exception -> worldActionResult(DeleteWorldResult.Failure.FAILED_TO_DELETE_FOLDER,
|
||||
world.getName(), exception.getMessage()),
|
||||
success -> worldActionResult(DeleteWorldResult.Success.DELETED, world.getName()));
|
||||
return worldActionResult(worldFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -533,58 +527,52 @@ public class WorldManager {
|
||||
* @param options The options for customizing the cloning of a world.
|
||||
* @return The result of the clone.
|
||||
*/
|
||||
public Result<CloneWorldResult.Success, CloneWorldResult.Failure> cloneWorld(@NotNull CloneWorldOptions options) {
|
||||
public Attempt<LoadedMultiverseWorld, CloneWorldResult> cloneWorld(@NotNull CloneWorldOptions options) {
|
||||
return cloneWorldValidateWorld(options)
|
||||
.onSuccessThen(s -> cloneWorldCopyFolder(options))
|
||||
.onSuccessThen(s -> importWorld(
|
||||
ImportWorldOptions.worldName(options.newWorldName())
|
||||
.environment(options.world().getEnvironment())
|
||||
.generator(options.world().getGenerator()))
|
||||
.fold(
|
||||
failure -> Result.failure(CloneWorldResult.Failure.IMPORT_FAILED,
|
||||
failure.getReasonMessage()),
|
||||
success -> Result.success()))
|
||||
.onSuccessThen(s -> getLoadedWorld(options.newWorldName()).fold(
|
||||
() -> worldActionResult(CloneWorldResult.Failure.MV_WORLD_FAILED, options.newWorldName()),
|
||||
mvWorld -> {
|
||||
cloneWorldTransferData(options, mvWorld);
|
||||
saveWorldsConfig();
|
||||
return Result.success(CloneWorldResult.Success.CLONED,
|
||||
replaceWorldName(options.world().getName()),
|
||||
replace("{newworld}").with(mvWorld.getName()));
|
||||
}));
|
||||
.mapAttempt(this::cloneWorldCopyFolder)
|
||||
.mapAttempt(validatedOptions -> {
|
||||
ImportWorldOptions importWorldOptions = ImportWorldOptions
|
||||
.worldName(validatedOptions.newWorldName())
|
||||
.environment(validatedOptions.world().getEnvironment())
|
||||
.generator(validatedOptions.world().getGenerator());
|
||||
return importWorld(importWorldOptions).transform(CloneWorldResult.IMPORT_FAILED);
|
||||
})
|
||||
.onSuccess(newWorld -> {
|
||||
cloneWorldTransferData(options, newWorld);
|
||||
saveWorldsConfig();
|
||||
});
|
||||
}
|
||||
|
||||
private Result<CloneWorldResult.Success, CloneWorldResult.Failure> cloneWorldValidateWorld(
|
||||
private Attempt<CloneWorldOptions, CloneWorldResult> cloneWorldValidateWorld(
|
||||
@NotNull CloneWorldOptions options) {
|
||||
String newWorldName = options.newWorldName();
|
||||
if (!worldNameChecker.isValidWorldName(newWorldName)) {
|
||||
Logging.severe("Invalid world name: " + newWorldName);
|
||||
return worldActionResult(CloneWorldResult.Failure.INVALID_WORLDNAME, newWorldName);
|
||||
return worldActionResult(CloneWorldResult.INVALID_WORLDNAME, newWorldName);
|
||||
}
|
||||
if (worldNameChecker.isValidWorldFolder(newWorldName)) {
|
||||
return worldActionResult(CloneWorldResult.Failure.WORLD_EXIST_FOLDER, newWorldName);
|
||||
return worldActionResult(CloneWorldResult.WORLD_EXIST_FOLDER, newWorldName);
|
||||
}
|
||||
if (isLoadedWorld(newWorldName)) {
|
||||
Logging.severe("World already loaded when attempting to clone: " + newWorldName);
|
||||
return worldActionResult(CloneWorldResult.Failure.WORLD_EXIST_LOADED, newWorldName);
|
||||
return worldActionResult(CloneWorldResult.WORLD_EXIST_LOADED, newWorldName);
|
||||
}
|
||||
if (isWorld(newWorldName)) {
|
||||
Logging.severe("World already exist unloaded: " + newWorldName);
|
||||
return worldActionResult(CloneWorldResult.Failure.WORLD_EXIST_UNLOADED, newWorldName);
|
||||
return worldActionResult(CloneWorldResult.WORLD_EXIST_UNLOADED, newWorldName);
|
||||
}
|
||||
return Result.success();
|
||||
return worldActionResult(options);
|
||||
}
|
||||
|
||||
private Result<CloneWorldResult.Success, CloneWorldResult.Failure> cloneWorldCopyFolder(
|
||||
private Attempt<CloneWorldOptions, CloneWorldResult> cloneWorldCopyFolder(
|
||||
@NotNull CloneWorldOptions options) {
|
||||
// TODO: Check null?
|
||||
File worldFolder = options.world().getBukkitWorld().map(World::getWorldFolder).getOrNull();
|
||||
File newWorldFolder = new File(Bukkit.getWorldContainer(), options.newWorldName());
|
||||
return filesManipulator.copyFolder(worldFolder, newWorldFolder, CLONE_IGNORE_FILES).fold(
|
||||
exception -> worldActionResult(CloneWorldResult.Failure.COPY_FAILED, options.world().getName(),
|
||||
exception.getMessage()),
|
||||
success -> Result.success());
|
||||
exception -> worldActionResult(CloneWorldResult.COPY_FAILED,
|
||||
options.world().getName(), exception),
|
||||
success -> worldActionResult(options));
|
||||
}
|
||||
|
||||
private void cloneWorldTransferData(@NotNull CloneWorldOptions options, @NotNull LoadedMultiverseWorld newWorld) {
|
||||
@ -615,12 +603,11 @@ public class WorldManager {
|
||||
* @param options The options for customizing the regeneration of a world.
|
||||
* @return The result of the regeneration.
|
||||
*/
|
||||
public Result<RegenWorldResult.Success, RegenWorldResult.Failure> regenWorld(@NotNull RegenWorldOptions options) {
|
||||
public Attempt<LoadedMultiverseWorld, RegenWorldResult> regenWorld(@NotNull RegenWorldOptions options) {
|
||||
// TODO: Teleport players out of world, and back in after regen
|
||||
|
||||
LoadedMultiverseWorld world = options.world();
|
||||
|
||||
DataTransfer<LoadedMultiverseWorld> dataTransfer = transferData(options, world);
|
||||
|
||||
CreateWorldOptions createWorldOptions = CreateWorldOptions.worldName(world.getName())
|
||||
.environment(world.getEnvironment())
|
||||
.generateStructures(world.canGenerateStructures().getOrElse(true))
|
||||
@ -628,36 +615,28 @@ public class WorldManager {
|
||||
.seed(options.seed())
|
||||
.worldType(world.getWorldType().getOrElse(WorldType.NORMAL));
|
||||
|
||||
var deleteResult = deleteWorld(world);
|
||||
if (deleteResult.isFailure()) {
|
||||
return Result.failure(RegenWorldResult.Failure.DELETE_FAILED, deleteResult.getReasonMessage());
|
||||
}
|
||||
|
||||
var createResult = createWorld(createWorldOptions);
|
||||
if (createResult.isFailure()) {
|
||||
return Result.failure(RegenWorldResult.Failure.CREATE_FAILED, createResult.getReasonMessage());
|
||||
}
|
||||
|
||||
getLoadedWorld(createWorldOptions.worldName()).peek(newWorld -> {
|
||||
dataTransfer.pasteAllTo(newWorld);
|
||||
saveWorldsConfig();
|
||||
});
|
||||
return worldActionResult(RegenWorldResult.Success.REGENERATED, world.getName());
|
||||
return deleteWorld(world)
|
||||
.transform(RegenWorldResult.DELETE_FAILED)
|
||||
.mapAttempt(() -> createWorld(createWorldOptions).transform(RegenWorldResult.CREATE_FAILED))
|
||||
.onSuccess(newWorld -> {
|
||||
dataTransfer.pasteAllTo(newWorld);
|
||||
saveWorldsConfig();
|
||||
});
|
||||
}
|
||||
|
||||
private <F extends FailureReason, S extends SuccessReason> Result<S, F> worldActionResult(
|
||||
@NotNull S messageKeyProvider, @NotNull String worldName) {
|
||||
return Result.success(messageKeyProvider, replaceWorldName(worldName));
|
||||
private <T, F extends FailureReason> Attempt<T, F> worldActionResult(@NotNull T value) {
|
||||
return Attempt.success(value);
|
||||
}
|
||||
|
||||
private <F extends FailureReason, S extends SuccessReason> Result<S, F> worldActionResult(
|
||||
@NotNull F messageKeyProvider, @NotNull String worldName) {
|
||||
return Result.failure(messageKeyProvider, replaceWorldName(worldName));
|
||||
private <T, F extends FailureReason> Attempt<T, F> worldActionResult(
|
||||
@NotNull F failureReason, @NotNull String worldName) {
|
||||
return Attempt.failure(failureReason, replaceWorldName(worldName));
|
||||
}
|
||||
|
||||
private <F extends FailureReason, S extends SuccessReason> Result<S, F> worldActionResult(
|
||||
@NotNull F messageKeyProvider, @NotNull String worldName, @NotNull String errorMessage) {
|
||||
return Result.failure(messageKeyProvider, replaceWorldName(worldName), replaceError(errorMessage));
|
||||
private <T, F extends FailureReason> Attempt<T, F> worldActionResult(
|
||||
@NotNull F failureReason, @NotNull String worldName, @NotNull Throwable error) {
|
||||
// TODO: Localize error message if its a MultiverseException
|
||||
return Attempt.failure(failureReason, replaceWorldName(worldName), replaceError(error.getMessage()));
|
||||
}
|
||||
|
||||
private MessageReplacement replaceWorldName(@NotNull String worldName) {
|
||||
|
@ -9,41 +9,24 @@ import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
/**
|
||||
* Result of a world clone operation.
|
||||
*/
|
||||
public class CloneWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
CLONED(MVCorei18n.CLONEWORLD_CLONED);
|
||||
public enum CloneWorldResult implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.CLONEWORLD_INVALIDWORLDNAME),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.CLONEWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.CLONEWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.CLONEWORLD_WORLDEXISTLOADED),
|
||||
COPY_FAILED(MVCorei18n.CLONEWORLD_COPYFAILED),
|
||||
IMPORT_FAILED(null),
|
||||
MV_WORLD_FAILED(null), // TODO
|
||||
;
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
CloneWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.CLONEWORLD_INVALIDWORLDNAME),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.CLONEWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.CLONEWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.CLONEWORLD_WORLDEXISTLOADED),
|
||||
COPY_FAILED(MVCorei18n.CLONEWORLD_COPYFAILED),
|
||||
IMPORT_FAILED(null),
|
||||
MV_WORLD_FAILED(null), // TODO
|
||||
;
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -9,38 +9,21 @@ import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
/**
|
||||
* Result of a world creation operation.
|
||||
*/
|
||||
public class CreateWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
CREATED(MVCorei18n.CREATEWORLD_CREATED);
|
||||
public enum CreateWorldResult implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.CREATEWORLD_INVALIDWORLDNAME),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.CREATEWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.CREATEWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.CREATEWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.CREATEWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
CreateWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.CREATEWORLD_INVALIDWORLDNAME),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.CREATEWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.CREATEWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.CREATEWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.CREATEWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -9,38 +9,21 @@ import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
/**
|
||||
* Result of a world deletion operation.
|
||||
*/
|
||||
public class DeleteWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
DELETED(MVCorei18n.DELETEWORLD_DELETED);
|
||||
public enum DeleteWorldResult implements FailureReason {
|
||||
WORLD_NON_EXISTENT(MVCorei18n.DELETEWORLD_WORLDNONEXISTENT),
|
||||
LOAD_FAILED(MVCorei18n.DELETEWORLD_LOADFAILED),
|
||||
WORLD_FOLDER_NOT_FOUND(MVCorei18n.DELETEWORLD_WORLDFOLDERNOTFOUND),
|
||||
REMOVE_FAILED(null),
|
||||
FAILED_TO_DELETE_FOLDER(MVCorei18n.DELETEWORLD_FAILEDTODELETEFOLDER);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
DeleteWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
WORLD_NON_EXISTENT(MVCorei18n.DELETEWORLD_WORLDNONEXISTENT),
|
||||
LOAD_FAILED(MVCorei18n.DELETEWORLD_LOADFAILED),
|
||||
WORLD_FOLDER_NOT_FOUND(MVCorei18n.DELETEWORLD_WORLDFOLDERNOTFOUND),
|
||||
REMOVE_FAILED(null),
|
||||
FAILED_TO_DELETE_FOLDER(MVCorei18n.DELETEWORLD_FAILEDTODELETEFOLDER);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -4,43 +4,25 @@ import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
|
||||
/**
|
||||
* Result of a world import operation.
|
||||
*/
|
||||
public class ImportWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
IMPORTED(MVCorei18n.IMPORTWORLD_IMPORTED);
|
||||
public enum ImportWorldResult implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.IMPORTWORLD_INVALIDWORLDNAME),
|
||||
WORLD_FOLDER_INVALID(MVCorei18n.IMPORTWORLD_WORLDFOLDERINVALID),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.IMPORTWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.IMPORTWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.IMPORTWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
ImportWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
INVALID_WORLDNAME(MVCorei18n.IMPORTWORLD_INVALIDWORLDNAME),
|
||||
WORLD_FOLDER_INVALID(MVCorei18n.IMPORTWORLD_WORLDFOLDERINVALID),
|
||||
WORLD_EXIST_UNLOADED(MVCorei18n.IMPORTWORLD_WORLDEXISTUNLOADED),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.IMPORTWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.IMPORTWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -4,43 +4,25 @@ import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
|
||||
/**
|
||||
* Result of a world loading operation.
|
||||
*/
|
||||
public class LoadWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
LOADED(MVCorei18n.LOADWORLD_LOADED);
|
||||
public enum LoadWorldResult implements FailureReason {
|
||||
WORLD_ALREADY_LOADING(MVCorei18n.LOADWORLD_WORLDALREADYLOADING),
|
||||
WORLD_NON_EXISTENT(MVCorei18n.LOADWORLD_WORLDNONEXISTENT),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.LOADWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.LOADWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.LOADWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
LoadWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
WORLD_ALREADY_LOADING(MVCorei18n.LOADWORLD_WORLDALREADYLOADING),
|
||||
WORLD_NON_EXISTENT(MVCorei18n.LOADWORLD_WORLDNONEXISTENT),
|
||||
WORLD_EXIST_FOLDER(MVCorei18n.LOADWORLD_WORLDEXISTFOLDER),
|
||||
WORLD_EXIST_LOADED(MVCorei18n.LOADWORLD_WORLDEXISTLOADED),
|
||||
BUKKIT_CREATION_FAILED(MVCorei18n.LOADWORLD_BUKKITCREATIONFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -2,42 +2,23 @@ package com.onarandombox.MultiverseCore.worldnew.results;
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
|
||||
/**
|
||||
* Result of a world regeneration operation.
|
||||
*/
|
||||
public class RegenWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
REGENERATED(MVCorei18n.REGENWORLD_REGENERATED);
|
||||
public enum RegenWorldResult implements FailureReason {
|
||||
DELETE_FAILED(null),
|
||||
CREATE_FAILED(null);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
RegenWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
DELETE_FAILED(null),
|
||||
CREATE_FAILED(null);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -4,40 +4,22 @@ import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
|
||||
/**
|
||||
* Result of a world removal operation.
|
||||
*/
|
||||
public class RemoveWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
REMOVED(MVCorei18n.REMOVEWORLD_REMOVED);
|
||||
public enum RemoveWorldResult implements FailureReason {
|
||||
WORLD_NON_EXISTENT(MVCorei18n.REMOVEWORLD_WORLDNONEXISTENT),
|
||||
UNLOAD_FAILED(null);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
RemoveWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
WORLD_NON_EXISTENT(MVCorei18n.REMOVEWORLD_WORLDNONEXISTENT),
|
||||
UNLOAD_FAILED(null);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -4,42 +4,24 @@ import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
|
||||
import com.onarandombox.MultiverseCore.utils.result.FailureReason;
|
||||
import com.onarandombox.MultiverseCore.utils.result.SuccessReason;
|
||||
|
||||
/**
|
||||
* Result of a world unloading operation.
|
||||
*/
|
||||
public class UnloadWorldResult {
|
||||
public enum Success implements SuccessReason {
|
||||
UNLOADED(MVCorei18n.UNLOADWORLD_UNLOADED);
|
||||
public enum UnloadWorldResult implements FailureReason {
|
||||
WORLD_ALREADY_UNLOADING(MVCorei18n.UNLOADWORLD_WORLDALREADYUNLOADING),
|
||||
WORLD_NON_EXISTENT(MVCorei18n.UNLOADWORLD_WORLDNONEXISTENT),
|
||||
WORLD_UNLOADED(MVCorei18n.UNLOADWORLD_WORLDUNLOADED),
|
||||
BUKKIT_UNLOAD_FAILED(MVCorei18n.UNLOADWORLD_BUKKITUNLOADFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Success(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
UnloadWorldResult(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public enum Failure implements FailureReason {
|
||||
WORLD_ALREADY_UNLOADING(MVCorei18n.UNLOADWORLD_WORLDALREADYUNLOADING),
|
||||
WORLD_NON_EXISTENT(MVCorei18n.UNLOADWORLD_WORLDNONEXISTENT),
|
||||
WORLD_UNLOADED(MVCorei18n.UNLOADWORLD_WORLDUNLOADED),
|
||||
BUKKIT_UNLOAD_FAILED(MVCorei18n.UNLOADWORLD_BUKKITUNLOADFAILED);
|
||||
|
||||
private final MessageKeyProvider message;
|
||||
|
||||
Failure(MessageKeyProvider message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return message.getMessageKey();
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ mv-core.clone.description=Clones a world.
|
||||
mv-core.clone.world.description=The target world to clone.
|
||||
mv-core.clone.newWorld.description=The new cloned world name.
|
||||
mv-core.clone.cloning=Cloning world '{world}' to '{newworld}'...
|
||||
mv-core.clone.success=&aWorld cloned to '{world}'!
|
||||
|
||||
# /mv confirm
|
||||
mv-core.confirm.description=Confirms dangerous commands before executing them.
|
||||
@ -39,6 +40,7 @@ mv-core.create.properties.adjustspawn=- Adjust Spawn: &f{adjustSpawn}
|
||||
mv-core.create.properties.generator=- Generator: &f{generator}
|
||||
mv-core.create.properties.structures=- Structures: &f{structures}
|
||||
mv-core.create.loading=Creating world...
|
||||
mv-core.create.success=&aWorld '{world}' created!
|
||||
|
||||
# /mv debug
|
||||
mv-core.debug.info.description=Show the current debug level.
|
||||
@ -52,6 +54,7 @@ mv-core.debug.change.level.description=Debug level to set to.
|
||||
mv-core.delete.description=Deletes a world on your server PERMANENTLY.
|
||||
mv-core.delete.deleting=Deleting world '{world}'...
|
||||
mv-core.delete.prompt=Are you sure you want to delete world '{world}'?
|
||||
mv-core.delete.success=&aWorld '{world}' deleted!
|
||||
|
||||
# /mv dumps
|
||||
mv-core.dumps.description=Dumps version info to the console or paste services
|
||||
@ -78,11 +81,13 @@ mv-core.import.name.description=Name of the world folder.
|
||||
mv-core.import.env.description=The world's environment. See: /mv env
|
||||
mv-core.import.other.description=Other world settings. See: https://gg.gg/nn8c2
|
||||
mv-core.import.importing=Starting import of world '{world}'...
|
||||
mv-core.import.success=&aWorld '{world}' imported!
|
||||
|
||||
# /mv load
|
||||
mv-core.load.description=Loads a world. World must be already in worlds.yml, else please use /mv import.
|
||||
mv-core.load.world.description=Name of world you want to load.
|
||||
mv-core.load.loading=Loading world '{world}'...
|
||||
mv-core.load.success=&aWorld '{world}' loaded!
|
||||
|
||||
# /mv regen
|
||||
mv-core.regen.description=Regenerates a world on your server. The previous state will be lost PERMANENTLY.
|
||||
@ -90,6 +95,7 @@ mv-core.regen.world.description=World that you want to regen.
|
||||
mv-core.regen.other.description=Other world settings. See: http://gg.gg/nn8lk
|
||||
mv-core.regen.regenerating=Regenerating world '{world}'...
|
||||
mv-core.regen.prompt=Are you sure you want to regenerate world '{world}'?
|
||||
mv-core.regen.success=&aWorld '{world}' regenerated!
|
||||
|
||||
# /mv reload
|
||||
mv-core.reload.description=Reloads config files for all Multiverse modules.
|
||||
@ -99,6 +105,7 @@ mv-core.reload.success=&aReload complete!
|
||||
# /mv remove
|
||||
mv-core.remove.description=Unloads a world from Multiverse and removes it from worlds.yml. This does NOT delete the world folder.
|
||||
mv-core.remove.world.description=World you want to remove from MV's knowledge.
|
||||
mv-core.remove.success=&aWorld '{world}' removed!
|
||||
|
||||
# /mv
|
||||
mv-core.root.title=&a{name} version {version}
|
||||
@ -114,6 +121,7 @@ mv-core.teleport.success=Teleporting {player} to {destination}...
|
||||
mv-core.unload.description=Unloads a world from Multiverse. This does NOT remove the world folder. This does NOT remove it from the config file.
|
||||
mv-core.unload.world.description=Name of the world you want to unload.
|
||||
mv-core.unload.unloading=Unloading world '{world}'...
|
||||
mv-core.unload.success=&aWorld '{world}' unloaded!
|
||||
|
||||
# /mv usage
|
||||
mv-core.usage.description=Show Multiverse-Core command usage.
|
||||
@ -130,46 +138,37 @@ mv-core.entrycheck.exceedplayerlimit=the world has reached its player limit.
|
||||
mv-core.entrycheck.noworldaccess=you do not have permissions to access the world.
|
||||
|
||||
# world manager result
|
||||
mv-core.cloneworld.cloned=&aWorld '{world}' cloned to '{newworld}'!
|
||||
mv-core.cloneworld.invalidworldname=World '{world}' contains invalid characters!
|
||||
mv-core.cloneworld.worldexistfolder=World '{world}' exists in server folders! You need to delete it first before cloning.
|
||||
mv-core.cloneworld.worldexistunloaded=World '{world}' already exists and it's unloaded! You need to delete it first before cloning.
|
||||
mv-core.cloneworld.worldexistloaded=World '{world}' already exists! You need to delete it first before cloning.
|
||||
mv-core.cloneworld.copyfailed=Failed to copy world '{world}' to '{newworld}': {error}\n&fSee console for more details.
|
||||
mv-core.cloneworld.copyfailed=Failed to copy world to '{world}': {error}\n&fSee console for more details.
|
||||
|
||||
mv-core.createworld.created=&aWorld '{world}' created!
|
||||
mv-core.createworld.invalidworldname=World '{world}' contains invalid characters!
|
||||
mv-core.createworld.worldexistfolder=World '{world}' already exists in server folders!&f Type '&a/mv import {world} <environment>&f' if you wish to import it.
|
||||
mv-core.createworld.worldexistunloaded=World '{world}' already exists, but it's not loaded!&f Type '&a/mv load {world}&f' if you wish to load it.
|
||||
mv-core.createworld.worldexistloaded=World '{world}' already exists!
|
||||
mv-core.createworld.bukkitcreationfailed=Bukkit failed to create world '{world}': {error}\n&fSee console for more details.
|
||||
|
||||
mv-core.deleteworld.deleted=&aWorld '{world}' deleted!
|
||||
mv-core.deleteworld.worldnonexistent=World '{world}' not found!
|
||||
mv-core.deleteworld.loadfailed=Unable to load world '{world}', does the world folder exist?&f You can run '&a/mv remove {world}&f' to remove it from Multiverse, or attempt to load again with '&a/mv load {world}&f'.
|
||||
mv-core.deleteworld.worldfoldernotfound=World '{world}' folder not found!
|
||||
mv-core.deleteworld.failedtodeletefolder=Failed to delete world folder '{world}': {error}\n&fSee console for more details.
|
||||
|
||||
mv-core.importworld.imported=&aWorld '{world}' imported!
|
||||
mv-core.importworld.invalidworldname=World '{world}' contains invalid characters!
|
||||
mv-core.importworld.worldexistunloaded=World '{world}' already exists, but it's not loaded!&f Type '&a/mv load {world}&f' if you wish to load it.
|
||||
mv-core.importworld.worldexistloaded=World '{world}' already exists!
|
||||
mv-core.importworld.worldfolderinvalid=World '{world}' folder contents does not seem to be a valid world!
|
||||
mv-core.importworld.bukkitcreationfailed=Bukkit failed to import world '{world}': {error}\n&fSee console for more details.
|
||||
|
||||
mv-core.loadworld.loaded=&aWorld '{world}' loaded!
|
||||
mv-core.loadworld.worldalreadyloading=World '{world}' is already loading! Please wait...
|
||||
mv-core.loadworld.worldnonexistent=World '{world}' not found! Use '&a/mv create {world} <environment>&f' to create it.
|
||||
mv-core.loadworld.worldexistfolder=World '{world}' exists in server folders, but it's not known to Multiverse!&f Type '&a/mv import {world} <environment>&f' if you wish to import it.
|
||||
mv-core.loadworld.worldexistloaded=World '{world}' is already loaded!
|
||||
mv-core.loadworld.bukkitcreationfailed=Bukkit failed to load world '{world}': {error}\n&fSee console for more details.
|
||||
|
||||
mv-core.regenworld.regenerated=&aWorld '{world}' regenerated!
|
||||
|
||||
mv-core.removeworld.removed=&aWorld '{world}' removed!
|
||||
mv-core.removeworld.worldnonexistent=World '{world}' not found!
|
||||
|
||||
mv-core.unloadworld.unloaded=&aWorld '{world}' unloaded!
|
||||
mv-core.unloadworld.worldalreadyunloading=World '{world}' is already unloading! Please wait...
|
||||
mv-core.unloadworld.worldnonexistent=World '{world}' does not exist!
|
||||
mv-core.unloadworld.worldunloaded=World '{world}' is already unloaded!
|
||||
|
@ -202,7 +202,7 @@ class LocalizationTest : TestWithMockBukkit() {
|
||||
private val messageString = "Hello $replacementKey!"
|
||||
private val replacedMessageString = messageString.replace(replacementKey, replacementValue)
|
||||
|
||||
private val message = MVCorei18n.CLONEWORLD_CLONED
|
||||
private val message = MVCorei18n.CLONE_SUCCESS
|
||||
.bundle(messageString, replace(replacementKey).with(replacementValue))
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user