NEW translate to client language with setting

This commit is contained in:
PikaMug 2022-06-14 14:24:23 -04:00
parent 86df2aa0b0
commit df2716074f
14 changed files with 135 additions and 69 deletions

View File

@ -43,6 +43,8 @@ public interface ISettings {
void setKillDelay(final int killDelay);
String getLanguage();
void setLanguage(final String language);
boolean canLanguageOverrideClient();
void setLanguageOverrideClient(final boolean languageOverrideClient);
int getMaxQuests();
void setMaxQuests(final int maxQuests);
boolean canNpcEffects();

View File

@ -16,10 +16,12 @@ import me.blackvein.quests.QuestsAPI;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.FileInputStream;
@ -37,20 +39,27 @@ import java.util.regex.Pattern;
public class Lang {
//private static String iso = "en-US";
private static final LinkedHashMap<String, String> langMap = new LinkedHashMap<>();
private static QuestsAPI plugin;
private static final LinkedHashMap<String, String> defaultLang = new LinkedHashMap<>();
private static final LinkedHashMap<String, LinkedHashMap<String, String>> otherLang = new LinkedHashMap<>();
private static final Pattern hexPattern = Pattern.compile("(?i)%#([0-9A-F]{6})%");
/*public static String getISO() {
return iso;
/**
* @deprecated Use Settings#getLanguage()
*/
public static String getISO() {
return plugin.getSettings().getLanguage();
}
/**
* @deprecated Use Settings#setLanguage(String)
*/
public static void setISO(final String iso) {
plugin.getSettings().setLanguage(iso);
}
public static void setISO(final String iso) {
Lang.iso = iso;
}*/
public static Collection<String> values() {
return langMap.values();
return defaultLang.values();
}
/**
@ -60,16 +69,49 @@ public class Lang {
* @param key label as it appears in lang file, such as "journalNoQuests"
* @return formatted string, plus processing through PlaceholderAPI by clip
*/
@SuppressWarnings("deprecation")
public static String get(final Player player, final String key) {
if (player == null) {
return get(key);
}
String locale;
try {
locale = player.getLocale();
} catch (NoSuchMethodError e) {
// Older version of Minecraft
locale = player.spigot().getLocale();
}
final int separator = locale.indexOf("_");
if (separator == -1) {
return defaultLang.containsKey(key) ? LangToken.convertString(player, defaultLang.get(key)) : "NULL";
}
final String language = locale.substring(0, separator);
final String country = locale.substring(separator + 1).toUpperCase();
locale = language + "-" + country;
if (plugin.getSettings().canLanguageOverrideClient() || locale.equals(getISO())) {
return defaultLang.containsKey(key) ? LangToken.convertString(player, defaultLang.get(key)) : "NULL";
}
if (!otherLang.containsKey(locale)) {
try {
init(plugin, locale);
} catch (Exception e) {
return defaultLang.containsKey(key) ? LangToken.convertString(player, defaultLang.get(key)) : "NULL";
}
}
return LangToken.convertString(otherLang.get(locale).get(key));
}
return langMap.containsKey(key) ? LangToken.convertString(player, langMap.get(key)) : "NULL";
/**
* Get lang string AND pass sender for use with PlaceholderAPI, if installed
*
* @param commandSender the sender whom will receive the string
* @param key label as it appears in lang file, such as "journalNoQuests"
* @return formatted string, plus processing through PlaceholderAPI by clip
*/
public static String get(final CommandSender commandSender, final String key) {
if (commandSender instanceof Player) {
return get((Player)commandSender, key);
}
return get(key);
}
/**
@ -79,7 +121,7 @@ public class Lang {
* @return formatted string
*/
public static String get(final String key) {
return langMap.containsKey(key) ? LangToken.convertString(langMap.get(key)) : "NULL";
return defaultLang.containsKey(key) ? LangToken.convertString(defaultLang.get(key)) : "NULL";
}
/**
@ -89,7 +131,7 @@ public class Lang {
* @return key or "NULL" as String
*/
public static String getKey(final String value) {
for (final Entry<String, String> entry : langMap.entrySet()) {
for (final Entry<String, String> entry : defaultLang.entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
@ -105,7 +147,7 @@ public class Lang {
* @return full key or "NULL" as String
*/
public static String getKeyFromPrefix(final String keyPrefix, final String value) {
for (final Entry<String, String> entry : langMap.entrySet()) {
for (final Entry<String, String> entry : defaultLang.entrySet()) {
if (entry.getValue().equalsIgnoreCase(value) && entry.getKey().toUpperCase().startsWith(keyPrefix)) {
return entry.getKey();
}
@ -114,15 +156,15 @@ public class Lang {
}
public static void clear() {
langMap.clear();
defaultLang.clear();
}
public static int size() {
return langMap.size();
return defaultLang.size();
}
public static String getModified(final String key, final String[] tokens) {
String orig = langMap.get(key);
String orig = defaultLang.get(key);
for (int i = 0; i < tokens.length; i++) {
orig = orig.replace("%" + (i + 1), tokens[i]);
}
@ -142,25 +184,28 @@ public class Lang {
}
public static void init(final QuestsAPI plugin, String iso) throws InvalidConfigurationException, IOException {
final File langFile = new File(plugin.getPluginDataFolder(), File.separator + "lang" + File.separator + iso + File.separator
+ "strings.yml");
Lang.plugin = plugin;
final File langFile = new File(plugin.getPluginDataFolder(), File.separator + "lang" + File.separator + iso
+ File.separator + "strings.yml");
final File langFile_new = new File(plugin.getPluginDataFolder(), File.separator + "lang" + File.separator + iso
+ File.separator + "strings_new.yml");
final boolean exists_new = langFile_new.exists();
final LinkedHashMap<String, String> allStrings = new LinkedHashMap<>();
if (!(langFile.exists() && iso.split("-").length > 1)) {
plugin.getPluginLogger().severe("Failed loading lang files for " + iso
+ " because they were not found. Using default en-US");
plugin.getPluginLogger()
.info("If the plugin has not generated language files, ensure Quests has write permissions");
plugin.getPluginLogger()
.info("For help, visit https://github.com/PikaMug/Quests/wiki/Casual-%E2%80%90-Translations");
plugin.getSettings().setLanguage("en-US");
if (plugin.getSettings().getConsoleLogging() > 3) {
plugin.getPluginLogger().info("CodeSource: " + plugin.getClass().getProtectionDomain().getCodeSource()
.toString());
plugin.getPluginLogger().info("LocationPath: " + plugin.getClass().getProtectionDomain().getCodeSource()
.getLocation().getPath());
if (defaultLang.isEmpty()) {
plugin.getPluginLogger().severe("Failed loading lang files for " + iso
+ " because they were not found. Using default en-US instead");
plugin.getPluginLogger()
.info("If the plugin has not generated language files, ensure Quests has write permissions");
plugin.getPluginLogger()
.info("For help, visit https://pikamug.gitbook.io/quests/casual/translations");
plugin.getSettings().setLanguage("en-US");
if (plugin.getSettings().getConsoleLogging() > 3) {
plugin.getPluginLogger().info("CodeSource: " + plugin.getClass().getProtectionDomain().getCodeSource()
.toString());
plugin.getPluginLogger().info("LocationPath: " + plugin.getClass().getProtectionDomain().getCodeSource()
.getLocation().getPath());
}
}
final FileConfiguration config = YamlConfiguration.loadConfiguration(new InputStreamReader(Objects
.requireNonNull(plugin.getPluginResource("strings.yml")), StandardCharsets.UTF_8));
@ -182,7 +227,7 @@ public class Lang {
config_new.set(key, null);
}
}
// Add new strings and notify user
// Add new strings and notify console
if (exists_new) {
for (final String key : config_new.getKeys(false)) {
final String value = config_new.getString(key);
@ -236,7 +281,12 @@ public class Lang {
allStrings.put(entry.getKey(), entry.getValue().replace("<semicolon>", strSemicolon));
}
}
langMap.putAll(allStrings);
if (iso.equals(getISO())) {
defaultLang.clear();
defaultLang.putAll(allStrings);
} else {
otherLang.put(iso, allStrings);
}
plugin.getPluginLogger().info("Loaded language " + iso + ". Translations via Crowdin");
}
@ -298,8 +348,9 @@ public class Lang {
LangToken.init();
}
s = convertString(s);
if (Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null ) {
if (Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI").isEnabled()) {
final Plugin placeholderApi = Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI");
if (placeholderApi != null ) {
if (placeholderApi.isEnabled()) {
s = PlaceholderAPI.setPlaceholders(p, s);
}
}

View File

@ -38,6 +38,7 @@ public class Settings implements ISettings {
private boolean ignoreLockedQuests = false;
private int killDelay = 0;
private String language = "en-US";
private boolean languageOverrideClient;
private int maxQuests = 0;
private boolean npcEffects = true;
private String effect = "note";
@ -159,6 +160,12 @@ public class Settings implements ISettings {
public void setLanguage(final String language) {
this.language = language;
}
public boolean canLanguageOverrideClient() {
return languageOverrideClient;
}
public void setLanguageOverrideClient(final boolean languageOverrideClient) {
this.languageOverrideClient = languageOverrideClient;
}
public int getMaxQuests() {
return maxQuests;
}
@ -259,6 +266,7 @@ public class Settings implements ISettings {
} else {
language = config.getString("language", "en-US");
}
languageOverrideClient = config.getBoolean("language-override-client", false);
maxQuests = config.getInt("max-quests", maxQuests);
npcEffects = config.getBoolean("npc-effects.enabled", true);
effect = config.getString("npc-effects.new-quest", "note");

View File

@ -70,7 +70,7 @@ public class QuestadminCommandHandler {
for (Map.Entry<String, QuestsSubCommand> cmd : subCommands.entrySet()) {
if (args[0].equalsIgnoreCase(cmd.getKey()) || args[0].equalsIgnoreCase(cmd.getValue().getNameI18N())) {
if (args.length < cmd.getValue().getMaxArguments()) {
cs.sendMessage(getAdminCommandUsage(args[0]));
cs.sendMessage(getAdminCommandUsage(cs, args[0]));
}
cmd.getValue().execute(cs, args);
return true;
@ -183,9 +183,9 @@ public class QuestadminCommandHandler {
}
}
private String getAdminCommandUsage(final String cmd) {
return ChatColor.RED + Lang.get("usage") + ": " + ChatColor.YELLOW + "/questadmin "
+ Lang.get(Lang.getKeyFromPrefix("COMMAND_QUESTADMIN_", cmd) + "_HELP")
private String getAdminCommandUsage(final CommandSender cs, final String cmd) {
return ChatColor.RED + Lang.get(cs, "usage") + ": " + ChatColor.YELLOW + "/questadmin "
+ Lang.get(cs, Lang.getKeyFromPrefix("COMMAND_QUESTADMIN_", cmd) + "_HELP")
.replace("<command>", cmd.toLowerCase());
}
}

View File

@ -65,13 +65,13 @@ public class QuestsCommandHandler {
for (Map.Entry<String, QuestsSubCommand> cmd : subCommands.entrySet()) {
if (args[0].equalsIgnoreCase(cmd.getKey()) || args[0].equalsIgnoreCase(cmd.getValue().getNameI18N())) {
if (args.length < cmd.getValue().getMaxArguments()) {
cs.sendMessage(getCommandUsage(args[0]));
cs.sendMessage(getCommandUsage(cs, args[0]));
}
cmd.getValue().execute(cs, args);
return true;
}
}
cs.sendMessage(ChatColor.YELLOW + Lang.get("questsUnknownCommand"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(cs, "questsUnknownCommand"));
return true;
}
@ -106,20 +106,21 @@ public class QuestsCommandHandler {
+ ChatColor.YELLOW));
}
if (cs instanceof Player) {
cs.sendMessage(ChatColor.DARK_AQUA + "/quest " + ChatColor.YELLOW + Lang.get("COMMAND_QUEST_HELP"));
cs.sendMessage(ChatColor.DARK_AQUA + "/quest " + ChatColor.YELLOW + Lang.get(cs, "COMMAND_QUEST_HELP"));
if (cs.hasPermission("quests.questinfo")) {
cs.sendMessage(ChatColor.DARK_AQUA + "/quest " + ChatColor.YELLOW
+ Lang.get("COMMAND_QUESTINFO_HELP"));
+ Lang.get(cs, "COMMAND_QUESTINFO_HELP"));
}
}
if (cs.hasPermission("quests.admin.*") || cs.hasPermission("quests.admin")) {
cs.sendMessage(ChatColor.YELLOW + "/questadmin " + ChatColor.RED
+ Lang.get("COMMAND_QUESTADMIN_HELP"));
+ Lang.get(cs, "COMMAND_QUESTADMIN_HELP"));
}
}
private String getCommandUsage(final String cmd) {
return ChatColor.RED + Lang.get("usage") + ": " + ChatColor.YELLOW + "/quests "
+ Lang.get(Lang.getKeyFromPrefix("COMMAND_", cmd) + "_HELP").replace("<command>", cmd.toLowerCase());
private String getCommandUsage(final CommandSender cs, final String cmd) {
return ChatColor.RED + Lang.get(cs, "usage") + ": " + ChatColor.YELLOW + "/quests "
+ Lang.get(cs, Lang.getKeyFromPrefix("COMMAND_", cmd) + "_HELP")
.replace("<command>", cmd.toLowerCase());
}
}

View File

@ -66,10 +66,10 @@ public class QuestsActionsCommand extends QuestsSubCommand {
if (!c.isConversing()) {
plugin.getActionFactory().getConversationFactory().buildConversation(c).begin();
} else {
cs.sendMessage(ChatColor.RED + Lang.get("duplicateEditor"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "duplicateEditor"));
}
} else {
cs.sendMessage(ChatColor.RED + Lang.get("noPermission"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "noPermission"));
}
}
}

View File

@ -65,10 +65,10 @@ public class QuestsConditionsCommand extends QuestsSubCommand {
if (!c.isConversing()) {
plugin.getConditionFactory().getConversationFactory().buildConversation(c).begin();
} else {
cs.sendMessage(ChatColor.RED + Lang.get("duplicateEditor"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "duplicateEditor"));
}
} else {
cs.sendMessage(ChatColor.RED + Lang.get("noPermission"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "noPermission"));
}
}
}

View File

@ -79,10 +79,10 @@ public class QuestsEditorCommand extends QuestsSubCommand {
}
cn.begin();
} else {
cs.sendMessage(ChatColor.RED + Lang.get("duplicateEditor"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "duplicateEditor"));
}
} else {
cs.sendMessage(ChatColor.RED + Lang.get("noPermission"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "noPermission"));
}
}
}

View File

@ -59,8 +59,9 @@ public class QuestsInfoCommand extends QuestsSubCommand {
public void execute(CommandSender cs, String[] args) {
if (cs.hasPermission("quests.info")) {
cs.sendMessage(ChatColor.YELLOW + "Quests " + ChatColor.GOLD + plugin.getDescription().getVersion());
cs.sendMessage(ChatColor.GOLD + Lang.get("createdBy") + " " + ChatColor.RED + "Blackvein"
+ ChatColor.GOLD + " " + Lang.get("continuedBy") + " " + ChatColor.RED + "PikaMug & contributors");
cs.sendMessage(ChatColor.GOLD + Lang.get(cs, "createdBy") + " " + ChatColor.RED + "Blackvein"
+ ChatColor.GOLD + " " + Lang.get(cs, "continuedBy") + " " + ChatColor.RED
+ "PikaMug & contributors");
cs.sendMessage(ChatColor.DARK_AQUA + "" + ChatColor.UNDERLINE + "https://github.com/PikaMug/Quests");
}
}

View File

@ -87,7 +87,7 @@ public class QuestsListCommand extends QuestsSubCommand {
try {
page = Integer.parseInt(args[1]);
if (page < 1) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("pageSelectionPosNum"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "pageSelectionPosNum"));
} else {
final Quester quester = plugin.getQuester(player.getUniqueId());
final QuestsCommandPreQuestsListEvent preEvent
@ -100,11 +100,11 @@ public class QuestsListCommand extends QuestsSubCommand {
plugin.listQuests(quester, page);
}
} catch (final NumberFormatException e) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("pageSelectionNum"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "pageSelectionNum"));
}
}
} else {
cs.sendMessage(ChatColor.RED + Lang.get("noPermission"));
cs.sendMessage(ChatColor.RED + Lang.get(cs, "noPermission"));
}
}
}

View File

@ -80,7 +80,7 @@ public class QuestsQuitCommand extends QuestsSubCommand {
final IQuest quest = plugin.getQuestTemp(concatArgArray(args, 1, args.length - 1, ' '));
if (quest != null) {
if (quest.getOptions().canAllowQuitting()) {
final String msg = ChatColor.YELLOW + Lang.get("questQuit").replace("<quest>",
final String msg = ChatColor.YELLOW + Lang.get(player, "questQuit").replace("<quest>",
ChatColor.DARK_PURPLE + quest.getName() + ChatColor.YELLOW);
quester.abandonQuest(quest, msg);
} else {

View File

@ -70,20 +70,22 @@ public class QuestsStatsCommand extends QuestsSubCommand {
if (cs.hasPermission(getPermission())) {
final IQuester quester = plugin.getQuester(player.getUniqueId());
cs.sendMessage(ChatColor.GOLD + "- " + player.getName() + " -");
cs.sendMessage(ChatColor.YELLOW + Lang.get("questPoints") + " - " + ChatColor.DARK_PURPLE
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "questPoints") + " - " + ChatColor.DARK_PURPLE
+ quester.getQuestPoints());
if (quester.getCurrentQuestsTemp().isEmpty()) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("currentQuest") + " " + ChatColor.DARK_PURPLE+ Lang.get("none"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "currentQuest") + " " + ChatColor.DARK_PURPLE
+ Lang.get("none"));
} else {
cs.sendMessage(ChatColor.YELLOW + Lang.get("currentQuest"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "currentQuest"));
for (final Map.Entry<IQuest, Integer> set : quester.getCurrentQuestsTemp().entrySet()) {
final IQuest q = set.getKey();
final String msg = ChatColor.LIGHT_PURPLE + " - " + ChatColor.DARK_PURPLE + q.getName()
+ ChatColor.LIGHT_PURPLE + " (" + Lang.get("stageEditorStage") + " " + (set.getValue() + 1) + ")";
+ ChatColor.LIGHT_PURPLE + " (" + Lang.get(player, "stageEditorStage") + " "
+ (set.getValue() + 1) + ")";
cs.sendMessage(msg);
}
}
cs.sendMessage(ChatColor.YELLOW + Lang.get("completedQuest"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(player, "completedQuest"));
if (quester.getCompletedQuestsTemp().isEmpty()) {
cs.sendMessage(ChatColor.DARK_PURPLE + Lang.get("none"));

View File

@ -76,12 +76,12 @@ public class QuestsTopCommand extends QuestsSubCommand {
try {
topNumber = Integer.parseInt(args[1]);
} catch (final NumberFormatException e) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("inputNum"));
cs.sendMessage(ChatColor.YELLOW + Lang.get(cs, "inputNum"));
return;
}
}
if (topNumber < 1 || topNumber > plugin.getSettings().getTopLimit()) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("invalidRange").replace("<least>", "1")
cs.sendMessage(ChatColor.YELLOW + Lang.get(cs, "invalidRange").replace("<least>", "1")
.replace("<greatest>", String.valueOf(plugin.getSettings().getTopLimit())));
return;
}
@ -105,14 +105,14 @@ public class QuestsTopCommand extends QuestsSubCommand {
}
final LinkedHashMap<String, Integer> sortedMap = (LinkedHashMap<String, Integer>) sort(questPoints);
int numPrinted = 0;
String msg = Lang.get("topQuestersTitle");
String msg = Lang.get(cs, "topQuestersTitle");
msg = msg.replace("<number>", ChatColor.DARK_PURPLE + "" + topNumber + ChatColor.GOLD);
cs.sendMessage(ChatColor.GOLD + msg);
for (final Map.Entry<String, Integer> entry : sortedMap.entrySet()) {
numPrinted++;
cs.sendMessage(ChatColor.YELLOW + String.valueOf(numPrinted) + ". " + entry.getKey() + " - "
+ ChatColor.DARK_PURPLE + entry.getValue() + ChatColor.YELLOW + " "
+ Lang.get("questPoints"));
+ Lang.get(cs, "questPoints"));
if (numPrinted == topNumber) {
break;
}

View File

@ -14,6 +14,7 @@ give-journal-item: false
ignore-locked-quests: false
kill-delay: 600
language: en-US
language-override-client: false
max-quests: 0
npc-effects:
enabled: true