diff --git a/bukkit/src/main/java/me/lucko/luckperms/BukkitCommand.java b/bukkit/src/main/java/me/lucko/luckperms/BukkitCommand.java index 25c5fbde..5ed11d13 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/BukkitCommand.java +++ b/bukkit/src/main/java/me/lucko/luckperms/BukkitCommand.java @@ -44,7 +44,7 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { onCommand( - BukkitSenderFactory.get().wrap(sender), + BukkitSenderFactory.get(getPlugin()).wrap(sender), label, Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))), Callback.empty() @@ -55,6 +55,6 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut @Override public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { - return onTabComplete(BukkitSenderFactory.get().wrap(sender), Arrays.asList(args)); + return onTabComplete(BukkitSenderFactory.get(getPlugin()).wrap(sender), Arrays.asList(args)); } } diff --git a/bukkit/src/main/java/me/lucko/luckperms/BukkitSenderFactory.java b/bukkit/src/main/java/me/lucko/luckperms/BukkitSenderFactory.java index a5c8a678..a2292949 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/BukkitSenderFactory.java +++ b/bukkit/src/main/java/me/lucko/luckperms/BukkitSenderFactory.java @@ -22,8 +22,6 @@ package me.lucko.luckperms; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import me.lucko.luckperms.commands.SenderFactory; import me.lucko.luckperms.constants.Constants; import org.bukkit.command.CommandSender; @@ -31,12 +29,16 @@ import org.bukkit.entity.Player; import java.util.UUID; -@NoArgsConstructor(access = AccessLevel.PRIVATE) public class BukkitSenderFactory extends SenderFactory { private static BukkitSenderFactory instance = null; - public static synchronized BukkitSenderFactory get() { + + private BukkitSenderFactory(LuckPermsPlugin plugin) { + super(plugin); + } + + public static synchronized BukkitSenderFactory get(LuckPermsPlugin plugin) { if (instance == null) { - instance = new BukkitSenderFactory(); + instance = new BukkitSenderFactory(plugin); } return instance; } diff --git a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java index a65c4859..edf1b532 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java @@ -42,6 +42,7 @@ import me.lucko.luckperms.storage.Datastore; import me.lucko.luckperms.storage.StorageFactory; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.BukkitUserManager; +import me.lucko.luckperms.utils.LocaleManager; import me.lucko.luckperms.utils.LogFactory; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Player; @@ -70,6 +71,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { private Importer importer; private ConsecutiveExecutor consecutiveExecutor; private DefaultsProvider defaultsProvider; + private LocaleManager localeManager; @Override public void onEnable() { @@ -77,6 +79,18 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { getLog().info("Loading configuration..."); configuration = new BukkitConfig(this); + + localeManager = new LocaleManager(); + File locale = new File(getDataFolder(), "lang.yml"); + if (locale.exists()) { + getLog().info("Found locale file. Attempting to load from it."); + try { + localeManager.loadFromFile(locale); + } catch (Exception e) { + e.printStackTrace(); + } + } + defaultsProvider = new DefaultsProvider(); getServer().getScheduler().runTaskLater(this, () -> defaultsProvider.refresh(), 1L); @@ -108,7 +122,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { getServer().getScheduler().runTaskTimerAsynchronously(this, new UpdateTask(this), ticks, ticks); } - getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(), 1L, 1L); + getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(this), 1L, 1L); getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L); getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L); @@ -200,14 +214,14 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { @Override public List getNotifyListeners() { return getServer().getOnlinePlayers().stream() - .map(p -> BukkitSenderFactory.get().wrap(p, Collections.singleton(me.lucko.luckperms.constants.Permission.LOG_NOTIFY))) + .map(p -> BukkitSenderFactory.get(this).wrap(p, Collections.singleton(me.lucko.luckperms.constants.Permission.LOG_NOTIFY))) .filter(me.lucko.luckperms.constants.Permission.LOG_NOTIFY::isAuthorized) .collect(Collectors.toList()); } @Override public Sender getConsoleSender() { - return BukkitSenderFactory.get().wrap(getServer().getConsoleSender()); + return BukkitSenderFactory.get(this).wrap(getServer().getConsoleSender()); } @Override diff --git a/bungee/src/main/java/me/lucko/luckperms/BungeeCommand.java b/bungee/src/main/java/me/lucko/luckperms/BungeeCommand.java index 6d344501..28cbeedb 100644 --- a/bungee/src/main/java/me/lucko/luckperms/BungeeCommand.java +++ b/bungee/src/main/java/me/lucko/luckperms/BungeeCommand.java @@ -45,7 +45,7 @@ class BungeeCommand extends Command implements TabExecutor { @Override public void execute(CommandSender sender, String[] args) { manager.onCommand( - BungeeSenderFactory.get().wrap(sender), + BungeeSenderFactory.get(manager.getPlugin()).wrap(sender), "bperms", Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))), Callback.empty() @@ -54,6 +54,6 @@ class BungeeCommand extends Command implements TabExecutor { @Override public Iterable onTabComplete(CommandSender sender, String[] args) { - return manager.onTabComplete(BungeeSenderFactory.get().wrap(sender), Arrays.asList(args)); + return manager.onTabComplete(BungeeSenderFactory.get(manager.getPlugin()).wrap(sender), Arrays.asList(args)); } } diff --git a/bungee/src/main/java/me/lucko/luckperms/BungeeSenderFactory.java b/bungee/src/main/java/me/lucko/luckperms/BungeeSenderFactory.java index 10a86560..80c64a08 100644 --- a/bungee/src/main/java/me/lucko/luckperms/BungeeSenderFactory.java +++ b/bungee/src/main/java/me/lucko/luckperms/BungeeSenderFactory.java @@ -22,8 +22,6 @@ package me.lucko.luckperms; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import me.lucko.luckperms.commands.SenderFactory; import me.lucko.luckperms.constants.Constants; import net.md_5.bungee.api.CommandSender; @@ -32,12 +30,16 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.UUID; -@NoArgsConstructor(access = AccessLevel.PRIVATE) public class BungeeSenderFactory extends SenderFactory { private static BungeeSenderFactory instance = null; - public static synchronized BungeeSenderFactory get() { + + private BungeeSenderFactory(LuckPermsPlugin plugin) { + super(plugin); + } + + public static synchronized BungeeSenderFactory get(LuckPermsPlugin plugin) { if (instance == null) { - instance = new BungeeSenderFactory(); + instance = new BungeeSenderFactory(plugin); } return instance; } diff --git a/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java b/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java index 0e06178f..788e6b53 100644 --- a/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java +++ b/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java @@ -42,6 +42,7 @@ import me.lucko.luckperms.storage.StorageFactory; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.BungeeUserManager; import me.lucko.luckperms.users.UserManager; +import me.lucko.luckperms.utils.LocaleManager; import me.lucko.luckperms.utils.LogFactory; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Plugin; @@ -66,6 +67,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { private Logger log; private Importer importer; private ConsecutiveExecutor consecutiveExecutor; + private LocaleManager localeManager; @Override public void onEnable() { @@ -74,6 +76,17 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { getLog().info("Loading configuration..."); configuration = new BungeeConfig(this); + localeManager = new LocaleManager(); + File locale = new File(getDataFolder(), "lang.yml"); + if (locale.exists()) { + getLog().info("Found locale file. Attempting to load from it."); + try { + localeManager.loadFromFile(locale); + } catch (Exception e) { + e.printStackTrace(); + } + } + // register events getProxy().getPluginManager().registerListener(this, new BungeeListener(this)); @@ -101,7 +114,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { } // 20 times per second (once per "tick") - getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(), 50L, 50L, TimeUnit.MILLISECONDS); + getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(this), 50L, 50L, TimeUnit.MILLISECONDS); getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS); getProxy().getScheduler().schedule(this, consecutiveExecutor, 1L, 1L, TimeUnit.SECONDS); @@ -162,14 +175,14 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { @Override public List getNotifyListeners() { return getProxy().getPlayers().stream() - .map(p -> BungeeSenderFactory.get().wrap(p, Collections.singleton(Permission.LOG_NOTIFY))) + .map(p -> BungeeSenderFactory.get(this).wrap(p, Collections.singleton(Permission.LOG_NOTIFY))) .filter(Permission.LOG_NOTIFY::isAuthorized) .collect(Collectors.toList()); } @Override public Sender getConsoleSender() { - return BungeeSenderFactory.get().wrap(getProxy().getConsole()); + return BungeeSenderFactory.get(this).wrap(getProxy().getConsole()); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java index 47df48f5..7cae3420 100644 --- a/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java @@ -35,6 +35,7 @@ import me.lucko.luckperms.groups.GroupManager; import me.lucko.luckperms.storage.Datastore; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.UserManager; +import me.lucko.luckperms.utils.LocaleManager; import java.io.File; import java.util.List; @@ -60,6 +61,7 @@ public interface LuckPermsPlugin { ApiProvider getApiProvider(); Importer getImporter(); ConsecutiveExecutor getConsecutiveExecutor(); + LocaleManager getLocaleManager(); /** * @return the version of the plugin diff --git a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java index c87b2b99..b3e305a4 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java +++ b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java @@ -39,7 +39,6 @@ import me.lucko.luckperms.commands.track.DeleteTrack; import me.lucko.luckperms.commands.track.ListTracks; import me.lucko.luckperms.commands.track.TrackMainCommand; import me.lucko.luckperms.commands.user.UserMainCommand; -import me.lucko.luckperms.constants.Message; import java.util.ArrayList; import java.util.Collections; @@ -49,6 +48,7 @@ import java.util.stream.Collectors; @AllArgsConstructor public class CommandManager { + @Getter private final LuckPermsPlugin plugin; @Getter @@ -177,7 +177,7 @@ public class CommandManager { } private void sendCommandUsage(Sender sender, String label) { - Message.INFO_BRIEF.send(sender, plugin.getVersion()); + sender.sendMessage(Util.color("&6Running &bLuckPerms v" + plugin.getVersion() + "&6.")); mainCommands.stream() .filter(c -> c.isAuthorized(sender)) diff --git a/common/src/main/java/me/lucko/luckperms/commands/Sender.java b/common/src/main/java/me/lucko/luckperms/commands/Sender.java index 669adb1f..ca672082 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/Sender.java +++ b/common/src/main/java/me/lucko/luckperms/commands/Sender.java @@ -22,6 +22,7 @@ package me.lucko.luckperms.commands; +import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.constants.Permission; import java.util.UUID; @@ -31,6 +32,7 @@ import java.util.UUID; */ public interface Sender { + LuckPermsPlugin getPlatform(); String getName(); UUID getUuid(); void sendMessage(String s); diff --git a/common/src/main/java/me/lucko/luckperms/commands/SenderFactory.java b/common/src/main/java/me/lucko/luckperms/commands/SenderFactory.java index a804b2ed..2e7fc384 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/SenderFactory.java +++ b/common/src/main/java/me/lucko/luckperms/commands/SenderFactory.java @@ -24,6 +24,8 @@ package me.lucko.luckperms.commands; import com.google.common.collect.ImmutableMap; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.constants.Constants; import me.lucko.luckperms.constants.Permission; @@ -36,7 +38,9 @@ import java.util.stream.Collectors; * Factory class to make a thread-safe sender instance * @param the command sender type */ +@RequiredArgsConstructor public abstract class SenderFactory implements Runnable { + private final LuckPermsPlugin plugin; private final Map> messages = new HashMap<>(); private final AtomicBoolean shouldSend = new AtomicBoolean(false); private final SenderFactory factory = this; @@ -47,11 +51,11 @@ public abstract class SenderFactory implements Runnable { protected abstract boolean hasPermission(T t, String node); public final Sender wrap(T t) { - return new SenderImp(t, null); + return new SenderImp(plugin, t, null); } public final Sender wrap(T t, Set toCheck) { - return new SenderImp(t, toCheck); + return new SenderImp(plugin, t, toCheck); } @Override @@ -85,7 +89,11 @@ public abstract class SenderFactory implements Runnable { private final boolean console; - private SenderImp(T t, Set toCheck) { + @Getter + private final LuckPermsPlugin platform; + + private SenderImp(LuckPermsPlugin platform, T t, Set toCheck) { + this.platform = platform; this.tRef = new WeakReference<>(t); this.name = factory.getName(t); this.uuid = factory.getUuid(t); diff --git a/common/src/main/java/me/lucko/luckperms/constants/Message.java b/common/src/main/java/me/lucko/luckperms/constants/Message.java index de6a2752..407b3bd9 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Message.java @@ -23,10 +23,11 @@ package me.lucko.luckperms.constants; import lombok.AllArgsConstructor; +import lombok.Getter; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.commands.Util; -import java.util.IllegalFormatException; +import java.text.MessageFormat; @SuppressWarnings("SpellCheckingInspection") @AllArgsConstructor @@ -36,21 +37,20 @@ public enum Message { * General & Commands */ PREFIX("&7&l[&b&lL&a&lP&7&l] &c", false), - EMPTY("%s", true), + EMPTY("{0}", true), PLAYER_ONLINE("&aOnline", false), PLAYER_OFFLINE("&cOffline", false), LOADING_ERROR("Permissions data could not be loaded. Please contact an administrator.", true), OP_DISABLED("&eThe vanilla OP system is disabled on this server.", false), - LOG("&3LOG &3&l> %s", true), + LOG("&3LOG &3&l> {0}", true), COMMAND_NOT_RECOGNISED("Command not recognised.", true), COMMAND_NO_PERMISSION("You do not have permission to use this command!", true), - INFO_BRIEF("&6Running &bLuckPerms v%s&6.", true), - ALREADY_HASPERMISSION("%s already has this permission!", true), - DOES_NOT_HAVEPERMISSION("%s does not have this permission set.", true), - ALREADY_HAS_TEMP_PERMISSION("%s already has this permission set temporarily!", true), - DOES_NOT_HAVE_TEMP_PERMISSION("%s does not have this permission set temporarily.", true), + ALREADY_HASPERMISSION("{0} already has this permission!", true), + DOES_NOT_HAVEPERMISSION("{0} does not have this permission set.", true), + ALREADY_HAS_TEMP_PERMISSION("{0} already has this permission set temporarily!", true), + DOES_NOT_HAVE_TEMP_PERMISSION("{0} does not have this permission set temporarily.", true), @@ -78,7 +78,7 @@ public enum Message { */ USER_USE_ADDGROUP("Use the addgroup command instead of specifying the node.", true), USER_USE_REMOVEGROUP("Use the removegroup command instead of specifying the node.", true), - USER_INVALID_ENTRY("&d%s&c is not a valid username/uuid.", true), + USER_INVALID_ENTRY("&d{0}&c is not a valid username/uuid.", true), GROUP_USE_INHERIT("Use the setinherit command instead of specifying the node.", true), GROUP_USE_UNINHERIT("Use the unsetinherit command instead of specifying the node.", true), @@ -92,22 +92,22 @@ public enum Message { /* * Commands */ - CREATE_SUCCESS("&b%s&a was successfully created.", true), - DELETE_SUCCESS("&b%s&a was successfully deleted.", true), - RENAME_SUCCESS("&b%s&a was successfully renamed to &b%s&a.", true), + CREATE_SUCCESS("&b{0}&a was successfully created.", true), + DELETE_SUCCESS("&b{0}&a was successfully deleted.", true), + RENAME_SUCCESS("&b{0}&a was successfully renamed to &b{0}&a.", true), - USER_ALREADY_MEMBER_OF("%s is already a member of '%s'.", true), - USER_NOT_MEMBER_OF("%s is not a member of '%s'.", true), - GROUP_ALREADY_INHERITS("%s already inherits '%s'.", true), - GROUP_DOES_NOT_INHERIT("%s does not inherit '%s'.", true), + USER_ALREADY_MEMBER_OF("{0} is already a member of '{1}'.", true), + USER_NOT_MEMBER_OF("{0} is not a member of '{1}'.", true), + GROUP_ALREADY_INHERITS("{0} already inherits '{1}'.", true), + GROUP_DOES_NOT_INHERIT("{0} does not inherit '{1}'.", true), - USER_ALREADY_TEMP_MEMBER_OF("%s is already a temporary member of '%s'.", true), - USER_NOT_TEMP_MEMBER_OF("%s is not a temporary member of '%s'.", true), - GROUP_ALREADY_TEMP_INHERITS("%s already temporarily inherits '%s'.", true), - GROUP_DOES_NOT_TEMP_INHERIT("%s does not temporarily inherit '%s'.", true), + USER_ALREADY_TEMP_MEMBER_OF("{0} is already a temporary member of '{1}'.", true), + USER_NOT_TEMP_MEMBER_OF("{0} is not a temporary member of '{1}'.", true), + GROUP_ALREADY_TEMP_INHERITS("{0} already temporarily inherits '{1}'.", true), + GROUP_DOES_NOT_TEMP_INHERIT("{0} does not temporarily inherit '{1}'.", true), - TRACK_ALREADY_CONTAINS("Track %s already contains the group '%s'.", true), - TRACK_DOES_NOT_CONTAIN("Track %s does not contain the group '%s'.", true), + TRACK_ALREADY_CONTAINS("Track {0} already contains the group '{1}'.", true), + TRACK_DOES_NOT_CONTAIN("Track {0} does not contain the group '{1}'.", true), GROUP_ALREADY_EXISTS("That group already exists!", true), GROUP_DOES_NOT_EXIST("That group does not exist!", true), @@ -122,186 +122,186 @@ public enum Message { UPDATE_TASK_RUN("&bRunning update task for all online users.", true), INFO( - PREFIX + "&6Running &bLuckPerms v%s&6 by &bLuck&6." + "\n" + - PREFIX + "&f-> &ePlatform: &6%s" + "\n" + - PREFIX + "&f-> &eStorage Method: &6%s" + "\n" + - PREFIX + "&f-> &eServer Name: &6%s" + "\n" + - PREFIX + "&f-> &eSync Interval: &6%s minutes" + "\n" + - PREFIX + "&f-> &eInclude Global: &6%s" + "\n" + - PREFIX + "&f-> &eInclude Global World: &6%s" + "\n" + - PREFIX + "&f-> &eApply Global Groups: &6%s" + "\n" + - PREFIX + "&f-> &eApply Global World Groups: &6%s" + "\n" + - PREFIX + "&f-> &eOnline Mode: &6%s" + "\n" + - PREFIX + "&f-> &eApply Wildcards: &6%s" + "\n" + - PREFIX + "&f-> &eApply Regex: &6%s" + "\n" + - PREFIX + "&f-> &eApply Shorthand: &6%s", + PREFIX + "&6Running &bLuckPerms v{0}&6 by &bLuck&6." + "\n" + + PREFIX + "&f-> &ePlatform: &6{1}" + "\n" + + PREFIX + "&f-> &eStorage Method: &6{2}" + "\n" + + PREFIX + "&f-> &eServer Name: &6{3}" + "\n" + + PREFIX + "&f-> &eSync Interval: &6{4} minutes" + "\n" + + PREFIX + "&f-> &eInclude Global: &6{5}" + "\n" + + PREFIX + "&f-> &eInclude Global World: &6{6}" + "\n" + + PREFIX + "&f-> &eApply Global Groups: &6{7}" + "\n" + + PREFIX + "&f-> &eApply Global World Groups: &6{8}" + "\n" + + PREFIX + "&f-> &eOnline Mode: &6{9}" + "\n" + + PREFIX + "&f-> &eApply Wildcards: &6{10}" + "\n" + + PREFIX + "&f-> &eApply Regex: &6{11}" + "\n" + + PREFIX + "&f-> &eApply Shorthand: &6{12}", false ), DEBUG( PREFIX + "&d&l> &dDebug Info" + "\n" + - PREFIX + "&f> &eOnline Players: &6%s" + "\n" + - PREFIX + "&f> &eLoaded Users: &6%s" + "\n" + - PREFIX + "&f> &eLoaded Groups: &6%s" + "\n" + - PREFIX + "&f> &eLoaded Tracks: &6%s", + PREFIX + "&f> &eOnline Players: &6{0}" + "\n" + + PREFIX + "&f> &eLoaded Users: &6{1}" + "\n" + + PREFIX + "&f> &eLoaded Groups: &6{2}" + "\n" + + PREFIX + "&f> &eLoaded Tracks: &6{3}", false ), CREATE_GROUP_ERROR("There was an error whilst creating the group.", true), DELETE_GROUP_ERROR("There was an error whilst deleting the group.", true), DELETE_GROUP_ERROR_DEFAULT("You cannot delete the default group.", true), - GROUPS_LIST("&aGroups: %s", true), + GROUPS_LIST("&aGroups: {0}", true), CREATE_TRACK_ERROR("There was an error whilst creating the track.", true), DELETE_TRACK_ERROR("There was an error whilst deleting the track.", true), - TRACKS_LIST("&aTracks: %s", true), + TRACKS_LIST("&aTracks: {0}", true), - LISTNODES("&e%s's Nodes:" + "\n" + "%s", true), - LISTNODES_TEMP("&e%s's Temporary Nodes:" + "\n" + "%s", true), - LISTPARENTS("&e%s's Parent Groups:" + "\n" + "%s", true), - LISTPARENTS_TEMP("&e%s's Temporary Parent Groups:" + "\n" + "%s", true), - LISTGROUPS("&e%s's Groups:" + "\n" + "%s", true), - LISTGROUPS_TEMP("&e%s's Temporary Groups:" + "\n" + "%s", true), - SETPERMISSION_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a.", true), - SETPERMISSION_SERVER_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a.", true), - SETPERMISSION_SERVER_WORLD_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a, world &b%s&a.", true), - SETPERMISSION_TEMP_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a for a duration of &b%s&a.", true), - SETPERMISSION_TEMP_SERVER_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a for a duration of &b%s&a.", true), - SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS("&aSet &b%s&a to &b%s&a for &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true), - UNSETPERMISSION_SUCCESS("&aUnset &b%s&a for &b%s&a.", true), - UNSETPERMISSION_SERVER_SUCCESS("&aUnset &b%s&a for &b%s&a on server &b%s&a.", true), - UNSETPERMISSION_SERVER_WORLD_SUCCESS("&aUnset &b%s&a for &b%s&a on server &b%s&a, world &b%s&a.", true), - UNSET_TEMP_PERMISSION_SUCCESS("&aUnset temporary permission &b%s&a for &b%s&a.", true), - UNSET_TEMP_PERMISSION_SERVER_SUCCESS("&aUnset temporary permission &b%s&a for &b%s&a on server &b%s&a.", true), - UNSET_TEMP_PERMISSION_SERVER_WORLD_SUCCESS("&aUnset temporary permission &b%s&a for &b%s&a on server &b%s&a, world &b%s&a.", true), - CLEAR_SUCCESS("&b%s&a's permissions were cleared.", true), - ILLEGAL_DATE_ERROR("Could not parse date '%s'.", true), + LISTNODES("&e{0}'s Nodes:" + "\n" + "{1}", true), + LISTNODES_TEMP("&e{0}'s Temporary Nodes:" + "\n" + "{1}", true), + LISTPARENTS("&e{0}'s Parent Groups:" + "\n" + "{1}", true), + LISTPARENTS_TEMP("&e{0}'s Temporary Parent Groups:" + "\n" + "{1}", true), + LISTGROUPS("&e{0}'s Groups:" + "\n" + "{1}", true), + LISTGROUPS_TEMP("&e{0}'s Temporary Groups:" + "\n" + "{1}", true), + SETPERMISSION_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a.", true), + SETPERMISSION_SERVER_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a.", true), + SETPERMISSION_SERVER_WORLD_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a, world &b{4}&a.", true), + SETPERMISSION_TEMP_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a for a duration of &b{3}&a.", true), + SETPERMISSION_TEMP_SERVER_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a for a duration of &b{4}&a.", true), + SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS("&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a.", true), + UNSETPERMISSION_SUCCESS("&aUnset &b{0}&a for &b{1}&a.", true), + UNSETPERMISSION_SERVER_SUCCESS("&aUnset &b{0}&a for &b{1}&a on server &b{2}&a.", true), + UNSETPERMISSION_SERVER_WORLD_SUCCESS("&aUnset &b{0}&a for &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + UNSET_TEMP_PERMISSION_SUCCESS("&aUnset temporary permission &b{0}&a for &b{1}&a.", true), + UNSET_TEMP_PERMISSION_SERVER_SUCCESS("&aUnset temporary permission &b{0}&a for &b{1}&a on server &b{2}&a.", true), + UNSET_TEMP_PERMISSION_SERVER_WORLD_SUCCESS("&aUnset temporary permission &b{0}&a for &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + CLEAR_SUCCESS("&b{0}&a's permissions were cleared.", true), + ILLEGAL_DATE_ERROR("Could not parse date '{0}'.", true), PAST_DATE_ERROR("You cannot set a date in the past!", true), - CHAT_META_PREFIX_HEADER("&e%s's Prefixes", true), - CHAT_META_SUFFIX_HEADER("&e%s's Suffixes", true), - CHAT_META_ENTRY("&d-> &e%s &6- &f\"%s&f\"", true), - CHAT_META_PREFIX_NONE("&e%s has no prefixes.", true), - CHAT_META_SUFFIX_NONE("&e%s has no suffixes.", true), + CHAT_META_PREFIX_HEADER("&e{0}'s Prefixes", true), + CHAT_META_SUFFIX_HEADER("&e{0}'s Suffixes", true), + CHAT_META_ENTRY("&d-> &e{0} &6- &f\"{1}&f\"", true), + CHAT_META_PREFIX_NONE("&e{0} has no prefixes.", true), + CHAT_META_SUFFIX_NONE("&e{0} has no suffixes.", true), - META_INVALID_PRIORITY("Invalid priority '%s'. Expected a number.", true), - ALREADY_HAS_PREFIX("%s already has that prefix set.", true), - ALREADY_HAS_SUFFIX("%s already has that suffix set.", true), - DOES_NOT_HAVE_PREFIX("%s doesn't have that prefix set.", true), - DOES_NOT_HAVE_SUFFIX("%s doesn't have that suffix set.", true), + META_INVALID_PRIORITY("Invalid priority '{0}'. Expected a number.", true), + ALREADY_HAS_PREFIX("{0} already has that prefix set.", true), + ALREADY_HAS_SUFFIX("{0} already has that suffix set.", true), + DOES_NOT_HAVE_PREFIX("{0} doesn't have that prefix set.", true), + DOES_NOT_HAVE_SUFFIX("{0} doesn't have that suffix set.", true), - ADDPREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a.", true), - ADDPREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a.", true), - ADDPREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a.", true), - REMOVEPREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed.", true), - REMOVEPREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true), - REMOVEPREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true), + ADDPREFIX_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a.", true), + ADDPREFIX_SERVER_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a.", true), + ADDPREFIX_SERVER_WORLD_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a.", true), + REMOVEPREFIX_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed.", true), + REMOVEPREFIX_SERVER_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a.", true), + REMOVEPREFIX_SERVER_WORLD_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a.", true), - ADDSUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a.", true), - ADDSUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a.", true), - ADDSUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a.", true), - REMOVESUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed.", true), - REMOVESUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true), - REMOVESUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true), + ADDSUFFIX_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a.", true), + ADDSUFFIX_SERVER_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a.", true), + ADDSUFFIX_SERVER_WORLD_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a.", true), + REMOVESUFFIX_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed.", true), + REMOVESUFFIX_SERVER_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a.", true), + REMOVESUFFIX_SERVER_WORLD_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a.", true), - ADD_TEMP_PREFIX_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a for a duration of &b%s&a.", true), - ADD_TEMP_PREFIX_SERVER_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, for a duration of &b%s&a.", true), - ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b%s&a had prefix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true), - REMOVE_TEMP_PREFIX_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed.", true), - REMOVE_TEMP_PREFIX_SERVER_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true), - REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b%s&a had temporary prefix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true), + ADD_TEMP_PREFIX_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a for a duration of &b{3}&a.", true), + ADD_TEMP_PREFIX_SERVER_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, for a duration of &b{4}&a.", true), + ADD_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a.", true), + REMOVE_TEMP_PREFIX_SUCCESS("&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed.", true), + REMOVE_TEMP_PREFIX_SERVER_SUCCESS("&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a.", true), + REMOVE_TEMP_PREFIX_SERVER_WORLD_SUCCESS("&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a.", true), - ADD_TEMP_SUFFIX_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a for a duration of &b%s&a.", true), - ADD_TEMP_SUFFIX_SERVER_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, for a duration of &b%s&a.", true), - ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had suffix &f\"%s&f\"&a set at a priority of &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true), - REMOVE_TEMP_SUFFIX_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed.", true), - REMOVE_TEMP_SUFFIX_SERVER_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a.", true), - REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b%s&a had temporary suffix &f\"%s&f\"&a at priority &b%s&a removed on server &b%s&a, world &b%s&a.", true), + ADD_TEMP_SUFFIX_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a for a duration of &b{3}&a.", true), + ADD_TEMP_SUFFIX_SERVER_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, for a duration of &b{4}&a.", true), + ADD_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a.", true), + REMOVE_TEMP_SUFFIX_SUCCESS("&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{1}&a removed.", true), + REMOVE_TEMP_SUFFIX_SERVER_SUCCESS("&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a.", true), + REMOVE_TEMP_SUFFIX_SERVER_WORLD_SUCCESS("&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a.", true), USER_INFO( - PREFIX + "&d-> &eUser: &6%s" + "\n" + - PREFIX + "&d-> &eUUID: &6%s" + "\n" + - PREFIX + "&d-> &eStatus: %s" + "\n" + - PREFIX + "&d-> &ePrimary Group: &6%s" + "\n" + - PREFIX + "&d-> &ePermissions: &6%s" + "\n" + - PREFIX + "&d-> &eTemporary Permissions: &6%s" + "\n" + - PREFIX + "&d-> &bUse &a/%s user %s listnodes &bto see all permissions.", + PREFIX + "&d-> &eUser: &6{0}" + "\n" + + PREFIX + "&d-> &eUUID: &6{1}" + "\n" + + PREFIX + "&d-> &eStatus: {2}" + "\n" + + PREFIX + "&d-> &ePrimary Group: &6{3}" + "\n" + + PREFIX + "&d-> &ePermissions: &6{4}" + "\n" + + PREFIX + "&d-> &eTemporary Permissions: &6{5}" + "\n" + + PREFIX + "&d-> &bUse &a/{6} user {7} listnodes &bto see all permissions.", false ), - USER_GETUUID("&bThe UUID of &e%s&b is &e%s&b.", true), - USER_ADDGROUP_SUCCESS("&b%s&a successfully added to group &b%s&a.", true), - USER_ADDGROUP_SERVER_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a.", true), - USER_ADDGROUP_SERVER_WORLD_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a, world &b%s&a.", true), - USER_ADDTEMPGROUP_SUCCESS("&b%s&a successfully added to group &b%s&a for a duration of &b%s&a.", true), - USER_ADDTEMPGROUP_SERVER_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a for a duration of &b%s&a.", true), - USER_ADDTEMPGROUP_SERVER_WORLD_SUCCESS("&b%s&a successfully added to group &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true), - USER_REMOVEGROUP_SUCCESS("&b%s&a was removed from group &b%s&a.", true), - USER_REMOVEGROUP_SERVER_SUCCESS("&b%s&a was removed from group &b%s&a on server &b%s&a.", true), - USER_REMOVEGROUP_SERVER_WORLD_SUCCESS("&b%s&a was removed from group &b%s&a on server &b%s&a, world &b%s&a.", true), - USER_REMOVETEMPGROUP_SUCCESS("&b%s&a was removed from temproary group &b%s&a.", true), - USER_REMOVETEMPGROUP_SERVER_SUCCESS("&b%s&a was removed from temporary group &b%s&a on server &b%s&a.", true), - USER_REMOVETEMPGROUP_SERVER_WORLD_SUCCESS("&b%s&a was removed from temporary group &b%s&a on server &b%s&a, world &b%s&a.", true), + USER_GETUUID("&bThe UUID of &e{0}&b is &e{1}&b.", true), + USER_ADDGROUP_SUCCESS("&b{0}&a successfully added to group &b{1}&a.", true), + USER_ADDGROUP_SERVER_SUCCESS("&b{0}&a successfully added to group &b{1}&a on server &b{2}&a.", true), + USER_ADDGROUP_SERVER_WORLD_SUCCESS("&b{0}&a successfully added to group &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + USER_ADDTEMPGROUP_SUCCESS("&b{0}&a successfully added to group &b{1}&a for a duration of &b{2}&a.", true), + USER_ADDTEMPGROUP_SERVER_SUCCESS("&b{0}&a successfully added to group &b{1}&a on server &b{2}&a for a duration of &b{3}&a.", true), + USER_ADDTEMPGROUP_SERVER_WORLD_SUCCESS("&b{0}&a successfully added to group &b{1}&a on server &b{2}&a, world &b{3}&a, for a duration of &b{4}&a.", true), + USER_REMOVEGROUP_SUCCESS("&b{0}&a was removed from group &b{1}&a.", true), + USER_REMOVEGROUP_SERVER_SUCCESS("&b{0}&a was removed from group &b{1}&a on server &b{2}&a.", true), + USER_REMOVEGROUP_SERVER_WORLD_SUCCESS("&b{0}&a was removed from group &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + USER_REMOVETEMPGROUP_SUCCESS("&b{0}&a was removed from temproary group &b{1}&a.", true), + USER_REMOVETEMPGROUP_SERVER_SUCCESS("&b{0}&a was removed from temporary group &b{1}&a on server &b{2}&a.", true), + USER_REMOVETEMPGROUP_SERVER_WORLD_SUCCESS("&b{0}&a was removed from temporary group &b{1}&a on server &b{2}&a, world &b{3}&a.", true), USER_REMOVEGROUP_ERROR_PRIMARY("You cannot remove a user from their primary group.", true), - USER_PRIMARYGROUP_SUCCESS("&b%s&a's primary group was set to &b%s&a.", true), + USER_PRIMARYGROUP_SUCCESS("&b{0}&a's primary group was set to &b{1}&a.", true), USER_PRIMARYGROUP_ERROR_ALREADYHAS("The user already has this group set as their primary group.", true), - USER_PRIMARYGROUP_ERROR_NOTMEMBER("&b%s&a was not already a member of &b%s&a, adding them now.", true), - USER_SHOWTRACKS_INFO("&aShowing tracks that contain the group '&b%s&a' (%s's primary group)", true), - USER_PROMOTE_SUCCESS_PROMOTE("&aPromoting user along track &b%s&a from &b%s&a to &b%s&a.", true), - USER_PROMOTE_SUCCESS_REMOVE("&b%s&a was removed from &b%s&a, added to &b%s&a, and their primary group was set to &b%s&a.", true), - USER_PROMOTE_ERROR_ENDOFTRACK("The end of track &4%s&c was reached. Unable to promote user.", true), + USER_PRIMARYGROUP_ERROR_NOTMEMBER("&b{0}&a was not already a member of &b{1}&a, adding them now.", true), + USER_SHOWTRACKS_INFO("&aShowing tracks that contain the group '&b{0}&a' ({1}'s primary group)", true), + USER_PROMOTE_SUCCESS_PROMOTE("&aPromoting user along track &b{0}&a from &b{1}&a to &b{2}&a.", true), + USER_PROMOTE_SUCCESS_REMOVE("&b{0}&a was removed from &b{1}&a, added to &b{2}&a, and their primary group was set to &b{3}&a.", true), + USER_PROMOTE_ERROR_ENDOFTRACK("The end of track &4{0}&c was reached. Unable to promote user.", true), USER_PROMOTE_ERROR_MALFORMED( - PREFIX + "The next group on the track, %s, no longer exists. Unable to promote user." + "\n" + + PREFIX + "The next group on the track, {0}, no longer exists. Unable to promote user." + "\n" + PREFIX + "Either create the group, or remove it from the track and try again.", false ), USER_PROMOTE_ERROR_NOT_CONTAIN_GROUP("Promotions are done based on primary groups. The users primary group is not on the track specified.", true), - USER_DEMOTE_SUCCESS_PROMOTE("&aDemoting user along track &b%s&a from &b%s&a to &b%s&a.", true), - USER_DEMOTE_SUCCESS_REMOVE("&b%s&a was removed from &b%s&a, added to &b%s&a, and their primary group was set to &b%s&a.", true), - USER_DEMOTE_ERROR_ENDOFTRACK("The end of track &4%s&c was reached. Unable to demote user.", true), + USER_DEMOTE_SUCCESS_PROMOTE("&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a.", true), + USER_DEMOTE_SUCCESS_REMOVE("&b{0}&a was removed from &b{1}&a, added to &b{2}&a, and their primary group was set to &b{3}&a.", true), + USER_DEMOTE_ERROR_ENDOFTRACK("The end of track &4{0}&c was reached. Unable to demote user.", true), USER_DEMOTE_ERROR_MALFORMED( - PREFIX + "The previous group on the track, %s, no longer exists. Unable to demote user." + "\n" + + PREFIX + "The previous group on the track, {0}, no longer exists. Unable to demote user." + "\n" + PREFIX + "Either create the group, or remove it from the track and try again.", false ), USER_DEMOTE_ERROR_NOT_CONTAIN_GROUP("Demotions are done based on primary groups. The users primary group is not on the track specified.", true), - USER_SHOWPOS("&aShowing &b%s&a's position on track &b%s&a.\n%s", true), + USER_SHOWPOS("&aShowing &b{0}&a's position on track &b{1}&a.\n{2}", true), GROUP_INFO( - PREFIX + "&d-> &eGroup: &6%s" + "\n" + - PREFIX + "&d-> &ePermissions: &6%s" + "\n" + - PREFIX + "&d-> &eTemporary Permissions: &6%s" + "\n" + - PREFIX + "&d-> &bUse &a/%s group %s listnodes &bto see all permissions.", + PREFIX + "&d-> &eGroup: &6{0}" + "\n" + + PREFIX + "&d-> &ePermissions: &6{1}" + "\n" + + PREFIX + "&d-> &eTemporary Permissions: &6{2}" + "\n" + + PREFIX + "&d-> &bUse &a/{3} group {4} listnodes &bto see all permissions.", false ), - GROUP_SETINHERIT_SUCCESS("&b%s&a now inherits permissions from &b%s&a.", true), - GROUP_SETINHERIT_SERVER_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a.", true), - GROUP_SETINHERIT_SERVER_WORLD_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a, world &b%s&a.", true), - GROUP_SET_TEMP_INHERIT_SUCCESS("&b%s&a now inherits permissions from &b%s&a for a duration of &b%s&a.", true), - GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a for a duration of &b%s&a.", true), - GROUP_SET_TEMP_INHERIT_SERVER_WORLD_SUCCESS("&b%s&a now inherits permissions from &b%s&a on server &b%s&a, world &b%s&a, for a duration of &b%s&a.", true), - GROUP_UNSETINHERIT_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a.", true), - GROUP_UNSETINHERIT_SERVER_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a on server &b%s&a.", true), - GROUP_UNSETINHERIT_SERVER_WORLD_SUCCESS("&b%s&a no longer inherits permissions from &b%s&a on server &b%s&a, world &b%s&a.", true), - GROUP_UNSET_TEMP_INHERIT_SUCCESS("&b%s&a no longer temporarily inherits permissions from &b%s&a.", true), - GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS("&b%s&a no longer temporarily inherits permissions from &b%s&a on server &b%s&a.", true), - GROUP_UNSET_TEMP_INHERIT_SERVER_WORLD_SUCCESS("&b%s&a no longer temporarily inherits permissions from &b%s&a on server &b%s&a, world &b%s&a.", true), + GROUP_SETINHERIT_SUCCESS("&b{0}&a now inherits permissions from &b{1}&a.", true), + GROUP_SETINHERIT_SERVER_SUCCESS("&b{0}&a now inherits permissions from &b{2}&a on server &b{3}&a.", true), + GROUP_SETINHERIT_SERVER_WORLD_SUCCESS("&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + GROUP_SET_TEMP_INHERIT_SUCCESS("&b{0}&a now inherits permissions from &b{1}&a for a duration of &b{2}&a.", true), + GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS("&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a for a duration of &b{3}&a.", true), + GROUP_SET_TEMP_INHERIT_SERVER_WORLD_SUCCESS("&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a, for a duration of &b{4}&a.", true), + GROUP_UNSETINHERIT_SUCCESS("&b{0}&a no longer inherits permissions from &b{1}&a.", true), + GROUP_UNSETINHERIT_SERVER_SUCCESS("&b{0}&a no longer inherits permissions from &b{1}&a on server &b{2}&a.", true), + GROUP_UNSETINHERIT_SERVER_WORLD_SUCCESS("&b{0}&a no longer inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a.", true), + GROUP_UNSET_TEMP_INHERIT_SUCCESS("&b{0}&a no longer temporarily inherits permissions from &b{1}&a.", true), + GROUP_UNSET_TEMP_INHERIT_SERVER_SUCCESS("&b{0}&a no longer temporarily inherits permissions from &b{1}&a on server &b{2}&a.", true), + GROUP_UNSET_TEMP_INHERIT_SERVER_WORLD_SUCCESS("&b{0}&a no longer temporarily inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a.", true), TRACK_INFO( - PREFIX + "&d-> &eTrack: &6%s" + "\n" + - PREFIX + "&d-> &ePath: &6%s", + PREFIX + "&d-> &eTrack: &6{0}" + "\n" + + PREFIX + "&d-> &ePath: &6{1}", false ), - TRACK_CLEAR("&b%s&a's groups track was cleared.", true), - TRACK_APPEND_SUCCESS("&aGroup &b%s&a was successfully appended to track &b%s&a.", true), - TRACK_INSERT_SUCCESS("&aGroup &b%s&a was successfully inserted into track &b%s&a at position &b%s&a.", true), - TRACK_INSERT_ERROR_NUMBER("Expected number but instead received: %s", true), - TRACK_INSERT_ERROR_INVALID_POS("Unable to insert at position %s. Index out of bounds.", true), - TRACK_REMOVE_SUCCESS("&aGroup &b%s&a was successfully removed from track &b%s&a.", true), + TRACK_CLEAR("&b{0}&a's groups track was cleared.", true), + TRACK_APPEND_SUCCESS("&aGroup &b{0}&a was successfully appended to track &b{1}&a.", true), + TRACK_INSERT_SUCCESS("&aGroup &b{0}&a was successfully inserted into track &b{1}&a at position &b{2}&a.", true), + TRACK_INSERT_ERROR_NUMBER("Expected number but instead received: {0}", true), + TRACK_INSERT_ERROR_INVALID_POS("Unable to insert at position {0}. Index out of bounds.", true), + TRACK_REMOVE_SUCCESS("&aGroup &b{0}&a was successfully removed from track &b{1}&a.", true), LOG_LOAD_ERROR("The log could not be loaded.", true), LOG_INVALID_PAGE("Invalid page number.", true), - LOG_INVALID_PAGE_RANGE("Invalid page number. Please enter a value between 1 and %s.", true), + LOG_INVALID_PAGE_RANGE("Invalid page number. Please enter a value between 1 and {0}.", true), LOG_NO_ENTRIES("&eNo log entries to show.", true), - LOG_ENTRY("&e#%s -> &8(&7%s ago&8) %s", true), + LOG_ENTRY("&e#{0} -> &8(&7{1} ago&8) {2}", true), LOG_NOTIFY_TOGGLE_ON("&aEnabled&b logging output.", true), LOG_NOTIFY_TOGGLE_OFF("&cDisabled&b logging output.", true), @@ -309,47 +309,48 @@ public enum Message { LOG_NOTIFY_ALREADY_OFF("You aren't currently receiving notifications.", true), LOG_NOTIFY_UNKNOWN("State unknown. Expecting \"on\" or \"off\".", true), - LOG_SEARCH_HEADER("&aShowing recent actions for query &b%s &a(page &f%s&a of &f%s&a)", true), + LOG_SEARCH_HEADER("&aShowing recent actions for query &b{0} &a(page &f{1}&a of &f{2}&a)", true), - LOG_RECENT_HEADER("&aShowing recent actions (page &f%s&a of &f%s&a)", true), - LOG_RECENT_BY_HEADER("&aShowing recent actions by &b%s &a(page &f%s&a of &f%s&a)", true), + LOG_RECENT_HEADER("&aShowing recent actions (page &f{0}&a of &f{1}&a)", true), + LOG_RECENT_BY_HEADER("&aShowing recent actions by &b{0} &a(page &f{1}&a of &f{2}&a)", true), - LOG_HISTORY_USER_HEADER("&aShowing history for user &b%s &a(page &f%s&a of &f%s&a)", true), - LOG_HISTORY_GROUP_HEADER("&aShowing history for group &b%s &a(page &f%s&a of &f%s&a)", true), - LOG_HISTORY_TRACK_HEADER("&aShowing history for track &b%s &a(page &f%s&a of &f%s&a)", true), + LOG_HISTORY_USER_HEADER("&aShowing history for user &b{0} &a(page &f{1}&a of &f{2}&a)", true), + LOG_HISTORY_GROUP_HEADER("&aShowing history for group &b{0} &a(page &f{1}&a of &f{2}&a)", true), + LOG_HISTORY_TRACK_HEADER("&aShowing history for track &b{0} &a(page &f{1}&a of &f{2}&a)", true), - LOG_EXPORT_ALREADY_EXISTS("Error: File %s already exists.", true), - LOG_EXPORT_NOT_WRITABLE("Error: File %s is not writable.", true), + LOG_EXPORT_ALREADY_EXISTS("Error: File {0} already exists.", true), + LOG_EXPORT_NOT_WRITABLE("Error: File {0} is not writable.", true), LOG_EXPORT_EMPTY("The log is empty and therefore cannot be exported.", true), LOG_EXPORT_FAILURE("An unexpected error occured whilst writing to the file.", true), - LOG_EXPORT_SUCCESS("&aSuccessfully exported the log to &b%s&a.", true), + LOG_EXPORT_SUCCESS("&aSuccessfully exported the log to &b{0}&a.", true), IMPORT_ALREADY_RUNNING("Another import process is already running. Please wait for it to finish and try again.", true), - IMPORT_LOG_DOESNT_EXIST("Error: File %s does not exist.", true), - IMPORT_LOG_NOT_READABLE("Error: File %s is not readable.", true), + IMPORT_LOG_DOESNT_EXIST("Error: File {0} does not exist.", true), + IMPORT_LOG_NOT_READABLE("Error: File {0} is not readable.", true), IMPORT_LOG_FAILURE("An unexpected error occured whilst reading from the log file.", true), - IMPORT_PROGRESS("&e(Import) &d-> &f%s &6percent complete &7- &e%s&6/&e%s &6operations complete with &c%s &6errors.", true), - IMPORT_PROGRESS_SIN("&e(Import) &d-> &f%s &6percent complete &7- &e%s&6/&e%s &6operations complete with &c%s &6error.", true), + IMPORT_PROGRESS("&e(Import) &d-> &f{0} &6percent complete &7- &e{1}&6/&e{2} &6operations complete with &c{3} &6errors.", true), + IMPORT_PROGRESS_SIN("&e(Import) &d-> &f{0} &6percent complete &7- &e{1}&6/&e{2} &6operations complete with &c{3} &6error.", true), IMPORT_START("&e(Import) &d-> &6Starting import process.", true), - IMPORT_END_COMPLETE("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &7No errors.", true), - IMPORT_END_COMPLETE_ERR("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &c%s errors.", true), - IMPORT_END_COMPLETE_ERR_SIN("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &c%s error.", true), + IMPORT_END_COMPLETE("&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &7No errors.", true), + IMPORT_END_COMPLETE_ERR("&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &c{1} errors.", true), + IMPORT_END_COMPLETE_ERR_SIN("&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &c{1} error.", true), IMPORT_END_ERROR_HEADER( - PREFIX + "&e(Import) &7------------> &6Showing Error #&e%s &7<------------" + "\n" + - PREFIX + "&e(Import) &6Whilst executing: &fCommand #%s" + "\n" + - PREFIX + "&e(Import) &6Command: &7%s" + "\n" + - PREFIX + "&e(Import) &6Type: &f%s" + "\n" + + PREFIX + "&e(Import) &7------------> &6Showing Error #&e{0} &7<------------" + "\n" + + PREFIX + "&e(Import) &6Whilst executing: &fCommand #{1}" + "\n" + + PREFIX + "&e(Import) &6Command: &7{2}" + "\n" + + PREFIX + "&e(Import) &6Type: &f{3}" + "\n" + PREFIX + "&e(Import) &6Output:", false ), - IMPORT_END_ERROR_CONTENT("&e(Import) &d-> &c%s", true), + IMPORT_END_ERROR_CONTENT("&e(Import) &d-> &c{0}", true), IMPORT_END_ERROR_FOOTER("&e(Import) &7<------------------------------------------>", true), MIGRATION_NOT_CONSOLE("Migration must be performed from the Console.", true); + @Getter private String message; private boolean showPrefix; @@ -359,13 +360,20 @@ public enum Message { } public void send(Sender sender, Object... objects) { + String s = sender.getPlatform().getLocaleManager().getTranslation(this); + if (s == null) { + s = message; + } else { + s = s.replace("{PREFIX}", PREFIX.getMessage()).replace("\\n", "\n"); + } + try { if (showPrefix) { - sender.sendMessage(Util.color(PREFIX + String.format(message, objects))); + sender.sendMessage(Util.color(PREFIX + MessageFormat.format(s, objects))); } else { - sender.sendMessage(Util.color(String.format(message, objects))); + sender.sendMessage(Util.color(MessageFormat.format(s, objects))); } - } catch (IllegalFormatException e) { + } catch (IllegalArgumentException e) { System.out.println("Could not format message: " + this); e.printStackTrace(); } diff --git a/common/src/main/java/me/lucko/luckperms/data/Importer.java b/common/src/main/java/me/lucko/luckperms/data/Importer.java index be62ba87..243daf6e 100644 --- a/common/src/main/java/me/lucko/luckperms/data/Importer.java +++ b/common/src/main/java/me/lucko/luckperms/data/Importer.java @@ -26,6 +26,7 @@ import com.google.common.base.Splitter; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import me.lucko.luckperms.LuckPermsPlugin; import me.lucko.luckperms.commands.CommandManager; import me.lucko.luckperms.commands.CommandResult; import me.lucko.luckperms.commands.Sender; @@ -183,6 +184,11 @@ public class Importer { this.instance = instance; } + @Override + public LuckPermsPlugin getPlatform() { + return instance.commandManager.getPlugin(); + } + @Override public String getName() { return Constants.getImporterName(); diff --git a/common/src/main/java/me/lucko/luckperms/utils/LocaleManager.java b/common/src/main/java/me/lucko/luckperms/utils/LocaleManager.java new file mode 100644 index 00000000..d7183767 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/utils/LocaleManager.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.utils; + +import com.google.common.collect.ImmutableMap; +import lombok.Cleanup; +import me.lucko.luckperms.constants.Message; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileReader; +import java.util.Map; + +/** + * Manages translations + */ +public class LocaleManager { + + private Map translations = null; + + @SuppressWarnings("unchecked") + public void loadFromFile(File file) throws Exception { + @Cleanup FileReader fileReader = new FileReader(file); + translations = ImmutableMap.copyOf((Map) new Yaml().load(fileReader)); + } + + public String getTranslation(Message key) { + if (translations == null) { + return null; + } + + String k = key.name().toLowerCase().replace('_', '-'); + return translations.get(k); + } + +} diff --git a/default-lang.yml b/default-lang.yml new file mode 100644 index 00000000..b68f7c01 --- /dev/null +++ b/default-lang.yml @@ -0,0 +1,293 @@ +# LuckPerms Language File +# Locale: en_US +# Author: Luck + +prefix: "&7&l[&b&lL&a&lP&7&l] &c" +empty: "{0}" +player-online: "&aOnline" +player-offline: "&cOffline" +loading-error: "Permissions data could not be loaded. Please contact an administrator." +op-disabled: "&eThe vanilla OP system is disabled on this server." +log: "&3LOG &3&l> {0}" + +command-not-recognised: "Command not recognised." +command-no-permission: "You do not have permission to use this command!" + +already-haspermission: "{0} already has this permission!" +does-not-havepermission: "{0} does not have this permission set." +already-has-temp-permission: "{0} already has this permission set temporarily!" +does-not-have-temp-permission: "{0} does not have this permission set temporarily." + + + +user-not-found: "&eUser could not be found." +user-save-success: "&7(User data was saved to the datastore)" +user-save-error: "There was an error whilst saving the user." +user-attempting-lookup: "&7(Attempting UUID lookup, since you specified a username)" +user-create-fail: "There was an error whilst creating a new user." + +group-not-found: "&eGroup could not be found." +group-save-success: "&7(Group data was saved to the datastore)" +group-save-error: "There was an error whilst saving the group." + +track-not-found: "&eTrack could not be found." +track-save-success: "&7(Track data was saved to the datastore)" +track-save-error: "There was an error whilst saving the track." + + + +user-use-addgroup: "Use the addgroup command instead of specifying the node." +user-use-removegroup: "Use the removegroup command instead of specifying the node." +user-invalid-entry: "&d{0}&c is not a valid username/uuid." + +group-use-inherit: "Use the setinherit command instead of specifying the node." +group-use-uninherit: "Use the unsetinherit command instead of specifying the node." +group-invalid-entry: "Group names can only contain alphanumeric characters." + +track-invalid-entry: "Track names can only contain alphanumeric characters." + +server-invalid-entry: "Server names can only contain alphanumeric characters." + + + +create-success: "&b{0}&a was successfully created." +delete-success: "&b{0}&a was successfully deleted." +rename-success: "&b{0}&a was successfully renamed to &b{0}&a." + +user-already-member-of: "{0} is already a member of '{1}'." +user-not-member-of: "{0} is not a member of '{1}'." +group-already-inherits: "{0} already inherits '{1}'." +group-does-not-inherit: "{0} does not inherit '{1}'." + +user-already-temp-member-of: "{0} is already a temporary member of '{1}'." +user-not-temp-member-of: "{0} is not a temporary member of '{1}'." +group-already-temp-inherits: "{0} already temporarily inherits '{1}'." +group-does-not-temp-inherit: "{0} does not temporarily inherit '{1}'." + +track-already-contains: "Track {0} already contains the group '{1}'." +track-does-not-contain: "Track {0} does not contain the group '{1}'." + +group-already-exists: "That group already exists!" +group-does-not-exist: "That group does not exist!" +group-load-error: "An unexpected error occurred. Group not loaded." +groups-load-error: "An unexpected error occurred. Unable to load all groups." + +track-already-exists: "That track already exists!" +track-does-not-exist: "That track does not exist!" +track-load-error: "An unexpected error occurred. Track not loaded." +tracks-load-error: "An unexpected error occurred. Unable to load all tracks." +track-empty: "The track cannot be used as it is empty or contains only one group." + +update-task-run: "&bRunning update task for all online users." +info: > + {PREFIX}&6Running &bLuckPerms v{0}&6 by &bLuck&6.\n + {PREFIX}&f-> &ePlatform: &6{1}\n + {PREFIX}&f-> &eStorage Method: &6{2}\n + {PREFIX}&f-> &eServer Name: &6{3}\n + {PREFIX}&f-> &eSync Interval: &6{4} minutes\n + {PREFIX}&f-> &eInclude Global: &6{5}\n + {PREFIX}&f-> &eInclude Global World: &6{6}\n + {PREFIX}&f-> &eApply Global Groups: &6{7}\n + {PREFIX}&f-> &eApply Global World Groups: &6{8}\n + {PREFIX}&f-> &eOnline Mode: &6{9}\n + {PREFIX}&f-> &eApply Wildcards: &6{10}\n + {PREFIX}&f-> &eApply Regex: &6{11}\n + {PREFIX}&f-> &eApply Shorthand: &6{12} +debug: > + {PREFIX}&d&l> &dDebug Info\n + {PREFIX}&f> &eOnline Players: &6{0}\n + {PREFIX}&f> &eLoaded Users: &6{1}\n + {PREFIX}&f> &eLoaded Groups: &6{2}\n + {PREFIX}&f> &eLoaded Tracks: &6{3} + +create-group-error: "There was an error whilst creating the group." +delete-group-error: "There was an error whilst deleting the group." +delete-group-error-default: "You cannot delete the default group." +groups-list: "&aGroups: {0}" + +create-track-error: "There was an error whilst creating the track." +delete-track-error: "There was an error whilst deleting the track." +tracks-list: "&aTracks: {0}" + +listnodes: "&e{0}'s Nodes:\n{1}" +listnodes-temp: "&e{0}'s Temporary Nodes:\n{1}" +listparents: "&e{0}'s Parent Groups:\n{1}" +listparents-temp: "&e{0}'s Temporary Parent Groups:\n{1}" +listgroups: "&e{0}'s Groups:\n{1}" +listgroups-temp: "&e{0}'s Temporary Groups:\n{1}" +setpermission-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a." +setpermission-server-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a." +setpermission-server-world-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a, world &b{4}&a." +setpermission-temp-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a for a duration of &b{3}&a." +setpermission-temp-server-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a for a duration of &b{4}&a." +setpermission-temp-server-world-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a." +unsetpermission-success: "&aUnset &b{0}&a for &b{1}&a." +unsetpermission-server-success: "&aUnset &b{0}&a for &b{1}&a on server &b{2}&a." +unsetpermission-server-world-success: "&aUnset &b{0}&a for &b{1}&a on server &b{2}&a, world &b{3}&a." +unset-temp-permission-success: "&aUnset temporary permission &b{0}&a for &b{1}&a." +unset-temp-permission-server-success: "&aUnset temporary permission &b{0}&a for &b{1}&a on server &b{2}&a." +unset-temp-permission-server-world-success: "&aUnset temporary permission &b{0}&a for &b{1}&a on server &b{2}&a, world &b{3}&a." +clear-success: "&b{0}&a's permissions were cleared." +illegal-date-error: "Could not parse date '{0}'." +past-date-error: "You cannot set a date in the past!" + +chat-meta-prefix-header: "&e{0}'s Prefixes" +chat-meta-suffix-header: "&e{0}'s Suffixes" +chat-meta-entry: "&d-> &e{0} &6- &f\"{1}&f\"" +chat-meta-prefix-none: "&e{0} has no prefixes." +chat-meta-suffix-none: "&e{0} has no suffixes." + +meta-invalid-priority: "Invalid priority '{0}'. Expected a number." +already-has-prefix: "{0} already has that prefix set." +already-has-suffix: "{0} already has that suffix set." +does-not-have-prefix: "{0} doesn't have that prefix set." +does-not-have-suffix: "{0} doesn't have that suffix set." + +addprefix-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a." +addprefix-server-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a." +addprefix-server-world-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a." +removeprefix-success: "&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed." +removeprefix-server-success: "&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a." +removeprefix-server-world-success: "&b{0}&a had prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a." + +addsuffix-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a." +addsuffix-server-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a." +addsuffix-server-world-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a." +removesuffix-success: "&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed." +removesuffix-server-success: "&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a." +removesuffix-server-world-success: "&b{0}&a had suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a." + +add-temp-prefix-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a for a duration of &b{3}&a." +add-temp-prefix-server-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, for a duration of &b{4}&a." +add-temp-prefix-server-world-success: "&b{0}&a had prefix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a." +remove-temp-prefix-success: "&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed." +remove-temp-prefix-server-success: "&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a." +remove-temp-prefix-server-world-success: "&b{0}&a had temporary prefix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a." + +add-temp-suffix-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a for a duration of &b{3}&a." +add-temp-suffix-server-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, for a duration of &b{4}&a." +add-temp-suffix-server-world-success: "&b{0}&a had suffix &f\"{1}&f\"&a set at a priority of &b{2}&a on server &b{3}&a, world &b{4}&a, for a duration of &b{5}&a." +remove-temp-suffix-success: "&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{1}&a removed." +remove-temp-suffix-server-success: "&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a." +remove-temp-suffix-server-world-success: "&b{0}&a had temporary suffix &f\"{1}&f\"&a at priority &b{2}&a removed on server &b{3}&a, world &b{4}&a." + +user-info: > + {PREFIX}&d-> &eUser: &6{0}\n + {PREFIX}&d-> &eUUID: &6{1}\n + {PREFIX}&d-> &eStatus: {2}\n + {PREFIX}&d-> &ePrimary Group: &6{3}\n + {PREFIX}&d-> &ePermissions: &6{4}\n + {PREFIX}&d-> &eTemporary Permissions: &6{5}\n + {PREFIX}&d-> &bUse &a/{6} user {7} listnodes &bto see all permissions. +user-getuuid: "&bThe UUID of &e{0}&b is &e{1}&b." +user-addgroup-success: "&b{0}&a successfully added to group &b{1}&a." +user-addgroup-server-success: "&b{0}&a successfully added to group &b{1}&a on server &b{2}&a." +user-addgroup-server-world-success: "&b{0}&a successfully added to group &b{1}&a on server &b{2}&a, world &b{3}&a." +user-addtempgroup-success: "&b{0}&a successfully added to group &b{1}&a for a duration of &b{2}&a." +user-addtempgroup-server-success: "&b{0}&a successfully added to group &b{1}&a on server &b{2}&a for a duration of &b{3}&a." +user-addtempgroup-server-world-success: "&b{0}&a successfully added to group &b{1}&a on server &b{2}&a, world &b{3}&a, for a duration of &b{4}&a." +user-removegroup-success: "&b{0}&a was removed from group &b{1}&a." +user-removegroup-server-success: "&b{0}&a was removed from group &b{1}&a on server &b{2}&a." +user-removegroup-server-world-success: "&b{0}&a was removed from group &b{1}&a on server &b{2}&a, world &b{3}&a." +user-removetempgroup-success: "&b{0}&a was removed from temproary group &b{1}&a." +user-removetempgroup-server-success: "&b{0}&a was removed from temporary group &b{1}&a on server &b{2}&a." +user-removetempgroup-server-world-success: "&b{0}&a was removed from temporary group &b{1}&a on server &b{2}&a, world &b{3}&a." +user-removegroup-error-primary: "You cannot remove a user from their primary group." +user-primarygroup-success: "&b{0}&a's primary group was set to &b{1}&a." +user-primarygroup-error-alreadyhas: "The user already has this group set as their primary group." +user-primarygroup-error-notmember: "&b{0}&a was not already a member of &b{1}&a, adding them now." +user-showtracks-info: "&aShowing tracks that contain the group '&b{0}&a' ({1}'s primary group)" +user-promote-success-promote: "&aPromoting user along track &b{0}&a from &b{1}&a to &b{2}&a." +user-promote-success-remove: "&b{0}&a was removed from &b{1}&a, added to &b{2}&a, and their primary group was set to &b{3}&a." +user-promote-error-endoftrack: "The end of track &4{0}&c was reached. Unable to promote user." +user-promote-error-malformed: > + {PREFIX}The next group on the track, {0}, no longer exists. Unable to promote user. + {PREFIX}Either create the group, or remove it from the track and try again. +user-promote-error-not-contain-group: "Promotions are done based on primary groups. The users primary group is not on the track specified." +user-demote-success-promote: "&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a." +user-demote-success-remove: "&b{0}&a was removed from &b{1}&a, added to &b{2}&a, and their primary group was set to &b{3}&a." +user-demote-error-endoftrack: "The end of track &4{0}&c was reached. Unable to demote user." +user-demote-error-malformed: > + {PREFIX}The previous group on the track, {0}, no longer exists. Unable to demote user.\n + {PREFIX}Either create the group, or remove it from the track and try again. +user-demote-error-not-contain-group: "Demotions are done based on primary groups. The users primary group is not on the track specified." +user-showpos: "&aShowing &b{0}&a's position on track &b{1}&a.\n{2}" + +group-info: > + {PREFIX}&d-> &eGroup: &6{0}\n + {PREFIX}&d-> &ePermissions: &6{1}\n + {PREFIX}&d-> &eTemporary Permissions: &6{2}\n + {PREFIX}&d-> &bUse &a/{3} group {4} listnodes &bto see all permissions. +group-setinherit-success: "&b{0}&a now inherits permissions from &b{1}&a." +group-setinherit-server-success: "&b{0}&a now inherits permissions from &b{2}&a on server &b{3}&a." +group-setinherit-server-world-success: "&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a." +group-set-temp-inherit-success: "&b{0}&a now inherits permissions from &b{1}&a for a duration of &b{2}&a." +group-set-temp-inherit-server-success: "&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a for a duration of &b{3}&a." +group-set-temp-inherit-server-world-success: "&b{0}&a now inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a, for a duration of &b{4}&a." +group-unsetinherit-success: "&b{0}&a no longer inherits permissions from &b{1}&a." +group-unsetinherit-server-success: "&b{0}&a no longer inherits permissions from &b{1}&a on server &b{2}&a." +group-unsetinherit-server-world-success: "&b{0}&a no longer inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a." +group-unset-temp-inherit-success: "&b{0}&a no longer temporarily inherits permissions from &b{1}&a." +group-unset-temp-inherit-server-success: "&b{0}&a no longer temporarily inherits permissions from &b{1}&a on server &b{2}&a." +group-unset-temp-inherit-server-world-success: "&b{0}&a no longer temporarily inherits permissions from &b{1}&a on server &b{2}&a, world &b{3}&a." + +track-info: > + {PREFIX}&d-> &eTrack: &6{0}\n + {PREFIX}&d-> &ePath: &6{1} +track-clear: "&b{0}&a's groups track was cleared." +track-append-success: "&aGroup &b{0}&a was successfully appended to track &b{1}&a." +track-insert-success: "&aGroup &b{0}&a was successfully inserted into track &b{1}&a at position &b{2}&a." +track-insert-error-number: "Expected number but instead received: {0}" +track-insert-error-invalid-pos: "Unable to insert at position {0}. Index out of bounds." +track-remove-success: "&aGroup &b{0}&a was successfully removed from track &b{1}&a." + +log-load-error: "The log could not be loaded." +log-invalid-page: "Invalid page number." +log-invalid-page-range: "Invalid page number. Please enter a value between 1 and {0}." +log-no-entries: "&eNo log entries to show." +log-entry: "&e#{0} -> &8(&7{1} ago&8) {2}" + +log-notify-toggle-on: "&aEnabled&b logging output." +log-notify-toggle-off: "&cDisabled&b logging output." +log-notify-already-on: "You are already receiving notifications." +log-notify-already-off: "You aren't currently receiving notifications." +log-notify-unknown: "State unknown. Expecting \"on\" or \"off\"." + +log-search-header: "&aShowing recent actions for query &b{0} &a(page &f{1}&a of &f{2}&a)" + +log-recent-header: "&aShowing recent actions (page &f{0}&a of &f{1}&a)" +log-recent-by-header: "&aShowing recent actions by &b{0} &a(page &f{1}&a of &f{2}&a)" + +log-history-user-header: "&aShowing history for user &b{0} &a(page &f{1}&a of &f{2}&a)" +log-history-group-header: "&aShowing history for group &b{0} &a(page &f{1}&a of &f{2}&a)" +log-history-track-header: "&aShowing history for track &b{0} &a(page &f{1}&a of &f{2}&a)" + +log-export-already-exists: "Error: File {0} already exists." +log-export-not-writable: "Error: File {0} is not writable." +log-export-empty: "The log is empty and therefore cannot be exported." +log-export-failure: "An unexpected error occured whilst writing to the file." +log-export-success: "&aSuccessfully exported the log to &b{0}&a." + +import-already-running: "Another import process is already running. Please wait for it to finish and try again." +import-log-doesnt-exist: "Error: File {0} does not exist." +import-log-not-readable: "Error: File {0} is not readable." +import-log-failure: "An unexpected error occured whilst reading from the log file." + +import-progress: "&e(Import) &d-> &f{0} &6percent complete &7- &e{1}&6/&e{2} &6operations complete with &c{3} &6errors." +import-progress-sin: "&e(Import) &d-> &f{0} &6percent complete &7- &e{1}&6/&e{2} &6operations complete with &c{3} &6error." +import-start: "&e(Import) &d-> &6Starting import process." + +import-end-complete: "&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &7No errors." +import-end-complete-err: "&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &c{1} errors." +import-end-complete-err-sin: "&e(Import) &a&lCOMPLETED &7- took &e{0} &7seconds - &c{1} error." +import-end-error-header: > + {PREFIX}&e(Import) &7------------> &6Showing Error #&e{0} &7<------------\n + {PREFIX}&e(Import) &6Whilst executing: &fCommand #{1}\n + {PREFIX}&e(Import) &6Command: &7{2}\n + {PREFIX}&e(Import) &6Type: &f{3}\n + {PREFIX}&e(Import) &6Output: + +import-end-error-content: "&e(Import) &d-> &c{0}" +import-end-error-footer: "&e(Import) &7<------------------------------------------>" + +migration-not-console: "Migration must be performed from the Console." diff --git a/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java index e28f1827..a14c6624 100644 --- a/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java @@ -43,6 +43,7 @@ import me.lucko.luckperms.storage.StorageFactory; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.SpongeUserManager; import me.lucko.luckperms.users.UserManager; +import me.lucko.luckperms.utils.LocaleManager; import me.lucko.luckperms.utils.LogFactory; import org.slf4j.Logger; import org.spongepowered.api.Game; @@ -95,6 +96,7 @@ public class LPSpongePlugin implements LuckPermsPlugin { private Importer importer; private ConsecutiveExecutor consecutiveExecutor; private LuckPermsService service; + private LocaleManager localeManager; @Listener public void onEnable(GamePreInitializationEvent event) { @@ -103,6 +105,17 @@ public class LPSpongePlugin implements LuckPermsPlugin { getLog().info("Loading configuration..."); configuration = new SpongeConfig(this); + localeManager = new LocaleManager(); + File locale = new File(getMainDir(), "lang.yml"); + if (locale.exists()) { + getLog().info("Found locale file. Attempting to load from it."); + try { + localeManager.loadFromFile(locale); + } catch (Exception e) { + e.printStackTrace(); + } + } + // register events Sponge.getEventManager().registerListeners(this, new SpongeListener(this)); @@ -139,7 +152,7 @@ public class LPSpongePlugin implements LuckPermsPlugin { runUpdateTask(); } - scheduler.createTaskBuilder().intervalTicks(1L).execute(SpongeSenderFactory.get()).submit(this); + scheduler.createTaskBuilder().intervalTicks(1L).execute(SpongeSenderFactory.get(this)).submit(this); scheduler.createTaskBuilder().async().intervalTicks(60L).execute(new ExpireTemporaryTask(this)).submit(this); scheduler.createTaskBuilder().async().intervalTicks(20L).execute(consecutiveExecutor).submit(this); @@ -219,14 +232,14 @@ public class LPSpongePlugin implements LuckPermsPlugin { @Override public List getNotifyListeners() { return game.getServer().getOnlinePlayers().stream() - .map(s -> SpongeSenderFactory.get().wrap(s, Collections.singleton(Permission.LOG_NOTIFY))) + .map(s -> SpongeSenderFactory.get(this).wrap(s, Collections.singleton(Permission.LOG_NOTIFY))) .filter(Permission.LOG_NOTIFY::isAuthorized) .collect(Collectors.toList()); } @Override public Sender getConsoleSender() { - return SpongeSenderFactory.get().wrap(game.getServer().getConsole()); + return SpongeSenderFactory.get(this).wrap(game.getServer().getConsole()); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/SpongeCommand.java b/sponge/src/main/java/me/lucko/luckperms/SpongeCommand.java index 88b1ae79..6f7e450d 100644 --- a/sponge/src/main/java/me/lucko/luckperms/SpongeCommand.java +++ b/sponge/src/main/java/me/lucko/luckperms/SpongeCommand.java @@ -48,7 +48,7 @@ class SpongeCommand extends CommandManager implements CommandCallable { @Override public CommandResult process(CommandSource source, String s) throws CommandException { onCommand( - SpongeSenderFactory.get().wrap(source), + SpongeSenderFactory.get(getPlugin()).wrap(source), "perms", Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s)), Callback.empty() @@ -58,11 +58,11 @@ class SpongeCommand extends CommandManager implements CommandCallable { @Override public List getSuggestions(CommandSource source, String s, @Nullable Location location) throws CommandException { - return onTabComplete(SpongeSenderFactory.get().wrap(source), Splitter.on(' ').splitToList(s)); + return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s)); } public List getSuggestions(CommandSource source, String s) throws CommandException { - return onTabComplete(SpongeSenderFactory.get().wrap(source), Splitter.on(' ').splitToList(s)); + return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s)); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/SpongeSenderFactory.java b/sponge/src/main/java/me/lucko/luckperms/SpongeSenderFactory.java index d02ed84c..d7c1d500 100644 --- a/sponge/src/main/java/me/lucko/luckperms/SpongeSenderFactory.java +++ b/sponge/src/main/java/me/lucko/luckperms/SpongeSenderFactory.java @@ -22,8 +22,6 @@ package me.lucko.luckperms; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; import me.lucko.luckperms.commands.SenderFactory; import me.lucko.luckperms.constants.Constants; import org.spongepowered.api.command.CommandSource; @@ -32,12 +30,16 @@ import org.spongepowered.api.text.serializer.TextSerializers; import java.util.UUID; -@NoArgsConstructor(access = AccessLevel.PRIVATE) public class SpongeSenderFactory extends SenderFactory { private static SpongeSenderFactory instance = null; - public static synchronized SpongeSenderFactory get() { + + private SpongeSenderFactory(LuckPermsPlugin plugin) { + super(plugin); + } + + public static synchronized SpongeSenderFactory get(LuckPermsPlugin plugin) { if (instance == null) { - instance = new SpongeSenderFactory(); + instance = new SpongeSenderFactory(plugin); } return instance; } diff --git a/standalone/src/main/java/me/lucko/luckperms/internal/StandaloneBase.java b/standalone/src/main/java/me/lucko/luckperms/internal/StandaloneBase.java index 3e07a41f..22cebadb 100644 --- a/standalone/src/main/java/me/lucko/luckperms/internal/StandaloneBase.java +++ b/standalone/src/main/java/me/lucko/luckperms/internal/StandaloneBase.java @@ -41,6 +41,7 @@ import me.lucko.luckperms.storage.Datastore; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.StandaloneUserManager; import me.lucko.luckperms.users.UserManager; +import me.lucko.luckperms.utils.LocaleManager; import me.lucko.luckperms.utils.LogFactory; import java.io.File; @@ -65,12 +66,14 @@ public class StandaloneBase implements LuckPermsPlugin { private final Logger log; private final UuidCache uuidCache; private final ApiProvider apiProvider; + private final LocaleManager localeManager; public StandaloneBase(LPStandaloneApp app) { logger = java.util.logging.Logger.getGlobal(); log = LogFactory.wrap(logger); configuration = new StandaloneConfiguration(this); + localeManager = new LocaleManager(); // TODO datastore datastore = null; @@ -165,7 +168,13 @@ public class StandaloneBase implements LuckPermsPlugin { @Override public Sender getConsoleSender() { + final LuckPermsPlugin instance = this; return new Sender() { + @Override + public LuckPermsPlugin getPlatform() { + return instance; + } + @Override public String getName() { return Constants.getConsoleName();