mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-15 07:05:28 +01:00
Merge remote-tracking branch 'origin/MV5' into better-revamp-config
This commit is contained in:
commit
2a5b670ce6
@ -114,6 +114,7 @@ dependencies {
|
||||
}
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-test'
|
||||
testImplementation 'com.natpryce:hamkrest:1.8.0.1'
|
||||
testImplementation 'org.mockito.kotlin:mockito-kotlin:4.1.0'
|
||||
|
||||
// Old Tests
|
||||
oldTestImplementation 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT'
|
||||
@ -241,7 +242,7 @@ javadoc {
|
||||
project.configurations.api.canBeResolved = true
|
||||
|
||||
shadowJar {
|
||||
relocate 'co.aikar', 'com.onarandombox.acf'
|
||||
relocate 'co.aikar.commands', 'com.onarandombox.acf'
|
||||
relocate 'com.dumptruckman.minecraft.util.Logging', 'com.onarandombox.MultiverseCore.utils.CoreLogging'
|
||||
relocate 'com.dumptruckman.minecraft.util.DebugLog', 'com.onarandombox.MultiverseCore.utils.DebugFileLogger'
|
||||
relocate 'de.themoep.idconverter', 'com.onarandombox.idconverter'
|
||||
|
13
src/main/java/co/aikar/commands/OpenBukkitCommandIssuer.java
Normal file
13
src/main/java/co/aikar/commands/OpenBukkitCommandIssuer.java
Normal file
@ -0,0 +1,13 @@
|
||||
package co.aikar.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Exists just so we can extend BukkitCommandIssuer since it has a package-private constructor.
|
||||
*/
|
||||
public abstract class OpenBukkitCommandIssuer extends BukkitCommandIssuer {
|
||||
|
||||
protected OpenBukkitCommandIssuer(BukkitCommandManager manager, CommandSender sender) {
|
||||
super(manager, sender);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
|
||||
import com.onarandombox.MultiverseCore.commandtools.PluginLocales;
|
||||
import com.onarandombox.MultiverseCore.config.MVCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
||||
@ -68,6 +69,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
private Provider<MetricsConfigurator> metricsConfiguratorProvider;
|
||||
@Inject
|
||||
private Provider<MVEconomist> economistProvider;
|
||||
@Inject
|
||||
private Provider<PluginLocales> pluginLocalesProvider;
|
||||
|
||||
// Counter for the number of plugins that have registered with us
|
||||
private int pluginCount;
|
||||
@ -129,8 +132,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
// Init all the other stuff
|
||||
this.loadAnchors();
|
||||
this.registerEvents();
|
||||
this.registerCommands();
|
||||
this.setUpLocales();
|
||||
this.registerCommands();
|
||||
this.registerDestinations();
|
||||
this.setupMetrics();
|
||||
this.loadPlaceholderAPIIntegration();
|
||||
@ -173,13 +176,19 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
|
||||
private void loadEconomist() {
|
||||
Try.run(() -> economistProvider.get())
|
||||
.onFailure(e -> Logging.severe("Failed to load economy integration", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to load economy integration");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
private void loadAnchors() {
|
||||
Try.of(() -> anchorManagerProvider.get())
|
||||
.onSuccess(AnchorManager::loadAnchors)
|
||||
.onFailure(e -> Logging.severe("Failed to load anchors", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to load anchors");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +213,10 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
serviceLocator.getAllServices(MultiverseCommand.class)
|
||||
.forEach(commandManager::registerCommand);
|
||||
})
|
||||
.onFailure(e -> Logging.severe("Failed to register commands", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to register commands");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,12 +224,18 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
*/
|
||||
private void setUpLocales() {
|
||||
Try.of(() -> commandManagerProvider.get())
|
||||
.andThenTry(commandManager -> {
|
||||
.andThen(commandManager -> {
|
||||
commandManager.usePerIssuerLocale(true, true);
|
||||
commandManager.getLocales().addFileResClassLoader(this);
|
||||
commandManager.getLocales().addMessageBundles("multiverse-core");
|
||||
})
|
||||
.onFailure(e -> Logging.severe("Failed to register locales", e));
|
||||
.mapTry(commandManager -> pluginLocalesProvider.get())
|
||||
.andThen(pluginLocales -> {
|
||||
pluginLocales.addFileResClassLoader(this);
|
||||
pluginLocales.addMessageBundles("multiverse-core");
|
||||
})
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to register locales");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +247,10 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
serviceLocator.getAllServices(Destination.class)
|
||||
.forEach(destinationsProvider::registerDestination);
|
||||
})
|
||||
.onFailure(e -> Logging.severe("Failed to register destinations", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to register destinations");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,7 +260,10 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
if (TestingMode.isDisabled()) {
|
||||
// Load metrics
|
||||
Try.of(() -> metricsConfiguratorProvider.get())
|
||||
.onFailure(e -> Logging.severe("Failed to setup metrics", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to setup metrics");
|
||||
e.printStackTrace();
|
||||
});
|
||||
} else {
|
||||
Logging.info("Metrics are disabled in testing mode.");
|
||||
}
|
||||
@ -261,7 +285,10 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
if (config.isRegisterPapiHook()
|
||||
&& getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
Try.run(() -> serviceLocator.createAndInitialize(MultiverseCorePlaceholders.class))
|
||||
.onFailure(e -> Logging.severe("Failed to load PlaceholderAPI integration.", e));
|
||||
.onFailure(e -> {
|
||||
Logging.severe("Failed to load PlaceholderAPI integration.");
|
||||
e.printStackTrace();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools;
|
||||
|
||||
import co.aikar.commands.MessageType;
|
||||
import co.aikar.commands.OpenBukkitCommandIssuer;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.message.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MVCommandIssuer extends OpenBukkitCommandIssuer {
|
||||
|
||||
private final MVCommandManager commandManager;
|
||||
|
||||
MVCommandIssuer(@NotNull MVCommandManager commandManager, @NotNull CommandSender sender) {
|
||||
super(commandManager, sender);
|
||||
this.commandManager = commandManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MVCommandManager getManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
public void sendError(Message message) {
|
||||
sendMessage(MessageType.ERROR, message);
|
||||
}
|
||||
|
||||
public void sendSyntax(Message message) {
|
||||
sendMessage(MessageType.SYNTAX, message);
|
||||
}
|
||||
|
||||
public void sendInfo(Message message) {
|
||||
sendMessage(MessageType.INFO, message);
|
||||
}
|
||||
|
||||
private void sendMessage(MessageType messageType, Message message) {
|
||||
if (message instanceof MessageKeyProvider) {
|
||||
sendMessage(messageType, (MessageKeyProvider) message, message.getReplacements());
|
||||
} else {
|
||||
var formatter = getManager().getFormat(messageType);
|
||||
if (formatter != null) {
|
||||
sendMessage(formatter.format(message.formatted()));
|
||||
} else {
|
||||
sendMessage(message.formatted());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import java.util.List;
|
||||
|
||||
import co.aikar.commands.BukkitCommandCompletionContext;
|
||||
import co.aikar.commands.BukkitCommandExecutionContext;
|
||||
import co.aikar.commands.BukkitLocales;
|
||||
import co.aikar.commands.CommandCompletions;
|
||||
import co.aikar.commands.CommandContexts;
|
||||
import co.aikar.commands.CommandHelp;
|
||||
@ -15,6 +16,8 @@ import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagsManager;
|
||||
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
@ -28,7 +31,6 @@ public class MVCommandManager extends PaperCommandManager {
|
||||
private final CommandQueueManager commandQueueManager;
|
||||
private final Provider<MVCommandContexts> commandContextsProvider;
|
||||
private final Provider<MVCommandCompletions> commandCompletionsProvider;
|
||||
private PluginLocales pluginLocales;
|
||||
|
||||
@Inject
|
||||
public MVCommandManager(
|
||||
@ -48,6 +50,18 @@ public class MVCommandManager extends PaperCommandManager {
|
||||
MVCommandConditions.load(this, worldManager);
|
||||
}
|
||||
|
||||
void loadLanguages(PluginLocales locales) {
|
||||
if (this.locales == null) {
|
||||
this.locales = locales;
|
||||
this.locales.loadLanguages();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitLocales getLocales() {
|
||||
return this.locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets class responsible for flag handling.
|
||||
*
|
||||
@ -57,21 +71,6 @@ public class MVCommandManager extends PaperCommandManager {
|
||||
return flagsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets class responsible for locale handling.
|
||||
*
|
||||
* @return A not-null {@link PluginLocales}.
|
||||
*/
|
||||
@Override
|
||||
public PluginLocales getLocales() {
|
||||
if (this.pluginLocales == null) {
|
||||
this.pluginLocales = new PluginLocales(this);
|
||||
this.locales = pluginLocales; // For parent class
|
||||
this.pluginLocales.loadLanguages();
|
||||
}
|
||||
return this.pluginLocales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manager for command that requires /mv confirm before execution.
|
||||
*
|
||||
@ -120,4 +119,17 @@ public class MVCommandManager extends PaperCommandManager {
|
||||
}
|
||||
help.showHelp();
|
||||
}
|
||||
|
||||
public @NotNull MVCommandIssuer getConsoleCommandIssuer() {
|
||||
return getCommandIssuer(Bukkit.getConsoleSender());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MVCommandIssuer getCommandIssuer(Object issuer) {
|
||||
if (!(issuer instanceof CommandSender)) {
|
||||
throw new IllegalArgumentException(issuer.getClass().getName() + " is not a Command Issuer.");
|
||||
} else {
|
||||
return new MVCommandIssuer(this, (CommandSender)issuer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
package com.onarandombox.MultiverseCore.commandtools;
|
||||
|
||||
import co.aikar.commands.BukkitCommandManager;
|
||||
import co.aikar.commands.BukkitLocales;
|
||||
import com.onarandombox.MultiverseCore.utils.file.FileResClassLoader;
|
||||
import jakarta.inject.Inject;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
/**
|
||||
* Locale manager with additional methods for loading locales from plugin's locales folder.
|
||||
*/
|
||||
@Service
|
||||
public class PluginLocales extends BukkitLocales {
|
||||
|
||||
private static final String DEFAULT_LOCALE_FOLDER_PATH = "locales";
|
||||
@ -18,8 +20,10 @@ public class PluginLocales extends BukkitLocales {
|
||||
*
|
||||
* @param manager The command manager.
|
||||
*/
|
||||
public PluginLocales(BukkitCommandManager manager) {
|
||||
@Inject
|
||||
public PluginLocales(MVCommandManager manager) {
|
||||
super(manager);
|
||||
manager.loadLanguages(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,52 @@
|
||||
package com.onarandombox.MultiverseCore.exceptions;
|
||||
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandIssuer;
|
||||
import com.onarandombox.MultiverseCore.utils.message.Message;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A base exception for Multiverse.
|
||||
* <br/>
|
||||
* {@link #getMVMessage()} provides access to a {@link Message} which can be used to provide a localized message. See
|
||||
* {@link MVCommandIssuer#sendInfo(Message)}.
|
||||
*/
|
||||
public class MultiverseException extends Exception {
|
||||
|
||||
private final @Nullable Message message;
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message and cause.
|
||||
* <br/>
|
||||
* If the message is not null, this exception will also contain a {@link Message} which can be accessed via
|
||||
* {@link #getMVMessage()}. This message will just be the given message wrapped in a {@link Message}.
|
||||
*
|
||||
* @param message The message for the exception
|
||||
* @param cause The cause of the exception
|
||||
*/
|
||||
public MultiverseException(@Nullable String message, @Nullable Throwable cause) {
|
||||
this(message != null ? Message.of(message) : null, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message and cause.
|
||||
* <br/>
|
||||
* If the message is not null, this exception will also contain a String message which can be accessed via
|
||||
* {@link #getMessage()}. This message will just be the given message formatted without locale support.
|
||||
*
|
||||
* @param message The message for the exception
|
||||
* @param cause The cause of the exception
|
||||
*/
|
||||
public MultiverseException(@Nullable Message message, @Nullable Throwable cause) {
|
||||
super(message != null ? message.formatted() : null, cause);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Message} for this exception.
|
||||
*
|
||||
* @return The message, or null if none was provided
|
||||
*/
|
||||
public final @Nullable Message getMVMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
@ -2,6 +2,9 @@ package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.utils.message.Message;
|
||||
import com.onarandombox.MultiverseCore.utils.message.MessageReplacement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum MVCorei18n implements MessageKeyProvider {
|
||||
// config status
|
||||
@ -84,4 +87,9 @@ public enum MVCorei18n implements MessageKeyProvider {
|
||||
public MessageKey getMessageKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Message bundle(@NotNull String nonLocalizedMessage, @NotNull MessageReplacement... replacements) {
|
||||
return Message.of(this, nonLocalizedMessage, replacements);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package com.onarandombox.MultiverseCore.utils.message;
|
||||
|
||||
import co.aikar.commands.ACFUtil;
|
||||
import co.aikar.commands.CommandIssuer;
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.commandtools.PluginLocales;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
final class LocalizedMessage extends Message implements MessageKeyProvider {
|
||||
|
||||
private final @NotNull MessageKeyProvider messageKeyProvider;
|
||||
|
||||
LocalizedMessage(
|
||||
@NotNull MessageKeyProvider messageKeyProvider,
|
||||
@NotNull String message,
|
||||
@NotNull MessageReplacement... replacements
|
||||
) {
|
||||
super(message, replacements);
|
||||
this.messageKeyProvider = messageKeyProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageKey getMessageKey() {
|
||||
return messageKeyProvider.getMessageKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String formatted(@NotNull PluginLocales locales, @Nullable CommandIssuer commandIssuer) {
|
||||
Objects.requireNonNull(locales, "locales must not be null");
|
||||
|
||||
if (getReplacements().length == 0) {
|
||||
return raw();
|
||||
}
|
||||
return ACFUtil.replaceStrings(locales.getMessage(commandIssuer, getMessageKey()), getReplacements());
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package com.onarandombox.MultiverseCore.utils.message;
|
||||
|
||||
import co.aikar.commands.ACFUtil;
|
||||
import co.aikar.commands.CommandIssuer;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
||||
import com.onarandombox.MultiverseCore.commandtools.PluginLocales;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A message that can be formatted with replacements and localized.
|
||||
*/
|
||||
public sealed class Message permits LocalizedMessage {
|
||||
|
||||
/**
|
||||
* Creates a basic non-localized Message with the given message and replacements.
|
||||
*
|
||||
* @param message The message
|
||||
* @param replacements The replacements
|
||||
* @return A new Message
|
||||
*/
|
||||
@Contract(value = "_, _ -> new", pure = true)
|
||||
public static Message of(@NotNull String message, @NotNull MessageReplacement... replacements) {
|
||||
Objects.requireNonNull(message, "message must not be null");
|
||||
for (MessageReplacement replacement : replacements) {
|
||||
Objects.requireNonNull(replacement, "replacements must not contain null");
|
||||
}
|
||||
|
||||
return new Message(message, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a localized Message with the given message key provider, non-localized message and replacements.
|
||||
* <br/>
|
||||
* The non-localized message is required for conditions where it is not practical to provide a localized message.
|
||||
* <br/>
|
||||
* This message will extend {@link MessageKeyProvider} and delegate to the given message key provider.
|
||||
*
|
||||
* @param messageKeyProvider The message key provider
|
||||
* @param nonLocalizedMessage The non-localized message
|
||||
* @param replacements The replacements
|
||||
* @return A new localizable Message
|
||||
*/
|
||||
@Contract(value = "_, _, _ -> new", pure = true)
|
||||
public static Message of(
|
||||
@NotNull MessageKeyProvider messageKeyProvider,
|
||||
@NotNull String nonLocalizedMessage,
|
||||
@NotNull MessageReplacement... replacements
|
||||
) {
|
||||
Objects.requireNonNull(messageKeyProvider, "messageKeyProvider must not be null");
|
||||
Objects.requireNonNull(nonLocalizedMessage, "message must not be null");
|
||||
for (MessageReplacement replacement : replacements) {
|
||||
Objects.requireNonNull(replacement, "replacements must not contain null");
|
||||
}
|
||||
|
||||
return new LocalizedMessage(messageKeyProvider, nonLocalizedMessage, replacements);
|
||||
}
|
||||
|
||||
private final @NotNull String message;
|
||||
private final @NotNull String[] replacements;
|
||||
|
||||
protected Message(@NotNull String message, @NotNull MessageReplacement... replacements) {
|
||||
this.message = message;
|
||||
this.replacements = toReplacementsArray(replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the replacements for this message.
|
||||
* <br/>
|
||||
* This array is guaranteed to be of even length and suitable for use with
|
||||
* {@link ACFUtil#replaceStrings(String, String...)}.
|
||||
*
|
||||
* @return The replacements
|
||||
*/
|
||||
public @NotNull String[] getReplacements() {
|
||||
return replacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw, non-localized, non-replaced message.
|
||||
*
|
||||
* @return The raw message
|
||||
*/
|
||||
public @NotNull String raw() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted message.
|
||||
* <br/>
|
||||
* This is the raw, non-localized message with replacements applied.
|
||||
*
|
||||
* @return The formatted message
|
||||
*/
|
||||
public @NotNull String formatted() {
|
||||
if (replacements.length == 0) {
|
||||
return raw();
|
||||
}
|
||||
return ACFUtil.replaceStrings(message, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted message from localization data.
|
||||
* <br/>
|
||||
* This is the localized message with replacements applied. The message is localized using the default locale.
|
||||
*
|
||||
* @param locales The MultiverseCore locales provider
|
||||
* @return The formatted, localized message
|
||||
*/
|
||||
public @NotNull String formatted(@NotNull PluginLocales locales) {
|
||||
return formatted(locales, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted message from localization data.
|
||||
* <br/>
|
||||
* This is the localized message with replacements applied. The message is localized using the locale of the given
|
||||
* command issuer, if not null.
|
||||
*
|
||||
* @param locales The MultiverseCore locales provider
|
||||
* @param commandIssuer The command issuer the message is for, or null for the console (default locale)
|
||||
* @return The formatted, localized message
|
||||
*/
|
||||
public @NotNull String formatted(@NotNull PluginLocales locales, @Nullable CommandIssuer commandIssuer) {
|
||||
return formatted();
|
||||
}
|
||||
|
||||
private static String[] toReplacementsArray(@NotNull MessageReplacement... replacements) {
|
||||
String[] replacementsArray = new String[replacements.length * 2];
|
||||
int i = 0;
|
||||
for (MessageReplacement replacement : replacements) {
|
||||
replacementsArray[i++] = replacement.getKey();
|
||||
replacementsArray[i++] = replacement.getReplacement();
|
||||
}
|
||||
return replacementsArray;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.onarandombox.MultiverseCore.utils.message;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Captures string replacements for {@link Message}s.
|
||||
*/
|
||||
public final class MessageReplacement {
|
||||
|
||||
/**
|
||||
* Creates a replacement key for the given key string.
|
||||
*
|
||||
* @param key The string to replace
|
||||
* @return A new replacement key which can be used to create a replacement
|
||||
*/
|
||||
@Contract(value = "_ -> new", pure = true)
|
||||
public static MessageReplacement.Key replace(@NotNull String key) {
|
||||
return new MessageReplacement.Key(key);
|
||||
}
|
||||
|
||||
public static final class Key {
|
||||
|
||||
private final @NotNull String key;
|
||||
|
||||
private Key(@NotNull String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a replacement for this key.
|
||||
*
|
||||
* @param replacement The replacement value, if null it will be replaced with a string equal to "null"
|
||||
* @return A new message replacement
|
||||
*/
|
||||
@Contract(value = "_ -> new", pure = true)
|
||||
public MessageReplacement with(@Nullable Object replacement) {
|
||||
return new MessageReplacement(key, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
private final @NotNull String key;
|
||||
private final @NotNull String replacement;
|
||||
|
||||
private MessageReplacement(@NotNull String key, @Nullable Object replacement) {
|
||||
this.key = key;
|
||||
this.replacement = String.valueOf(replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string to be replaced.
|
||||
*
|
||||
* @return The key
|
||||
*/
|
||||
public @NotNull String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the replacement value.
|
||||
*
|
||||
* @return The replacement
|
||||
*/
|
||||
public @NotNull String getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
package org.mvplugins.multiverse.core.commandtools
|
||||
|
||||
import com.natpryce.hamkrest.assertion.assertThat
|
||||
import com.natpryce.hamkrest.containsSubstring
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandIssuer
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager
|
||||
import com.onarandombox.MultiverseCore.commandtools.PluginLocales
|
||||
import com.onarandombox.MultiverseCore.utils.MVCorei18n
|
||||
import com.onarandombox.MultiverseCore.utils.message.Message
|
||||
import com.onarandombox.MultiverseCore.utils.message.MessageReplacement.replace
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class LocalizationTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var locales: PluginLocales
|
||||
private lateinit var commandManager: MVCommandManager
|
||||
|
||||
@BeforeTest
|
||||
fun setUpLocale() {
|
||||
locales = assertNotNull(multiverseCore.getService(PluginLocales::class.java))
|
||||
commandManager = assertNotNull(multiverseCore.getService(MVCommandManager::class.java))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with only a non-localized message")
|
||||
inner class BasicMessage {
|
||||
|
||||
private val messageString = "This is a test message"
|
||||
private val message = Message.of(messageString)
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$messageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a non-localized message and one replacement")
|
||||
inner class MessageWithOneReplacement {
|
||||
|
||||
private val replacementKey = "{count}"
|
||||
private val messageString = "This is a test message with $replacementKey replacement"
|
||||
private val replacedMessageString = messageString.replace(replacementKey, "one")
|
||||
|
||||
private val message = Message.of(messageString, replace(replacementKey).with("one"))
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$replacedMessageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a non-localized message and two replacements")
|
||||
inner class MessageWithTwoReplacements {
|
||||
|
||||
private val replacementKey1 = "{thing1}"
|
||||
private val replacementKey2 = "{thing2}"
|
||||
private val messageString = "$replacementKey1 $replacementKey2"
|
||||
private val replacedMessageString = messageString
|
||||
.replace(replacementKey1, "one")
|
||||
.replace(replacementKey2, "two")
|
||||
|
||||
private val message = Message.of(
|
||||
messageString,
|
||||
replace(replacementKey1).with("one"),
|
||||
replace(replacementKey2).with("two"),
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$replacedMessageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a localized message with one replacement")
|
||||
inner class LocalizedMessage {
|
||||
|
||||
private val replacementKey = "{world}"
|
||||
private val replacementValue = "World"
|
||||
private val messageString = "Hello $replacementKey!"
|
||||
private val replacedMessageString = messageString.replace(replacementKey, replacementValue)
|
||||
|
||||
private val message = MVCorei18n.CLONE_SUCCESS
|
||||
.bundle(messageString, replace(replacementKey).with(replacementValue))
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced original string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be different from the replaced original string`() {
|
||||
assertNotEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should have performed replacement`() {
|
||||
assertThat(message.formatted(locales), !containsSubstring(replacementKey))
|
||||
assertThat(message.formatted(locales), containsSubstring(replacementValue))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
val sentMessage = argumentCaptor<String> {
|
||||
verify(sender).sendMessage(capture())
|
||||
}.firstValue
|
||||
|
||||
assertNotEquals(replacedMessageString, sentMessage)
|
||||
assertThat(sentMessage, !containsSubstring(replacementKey))
|
||||
assertThat(sentMessage, containsSubstring(replacementValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager
|
||||
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand
|
||||
import com.onarandombox.MultiverseCore.commandtools.PluginLocales
|
||||
import com.onarandombox.MultiverseCore.config.MVCoreConfig
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist
|
||||
import com.onarandombox.MultiverseCore.listeners.MVChatListener
|
||||
@ -135,4 +136,9 @@ class InjectionTest : TestWithMockBukkit() {
|
||||
// Also making sure this is not loaded automatically since it's supposed to be disabled during tests
|
||||
assertNull(multiverseCore.getService(MetricsConfigurator::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PluginLocales is available as a service`() {
|
||||
assertNotNull(multiverseCore.getService(PluginLocales::class.java))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user