Intial i18n messages support

Send different languages of messages based on player's client setting
This commit is contained in:
Dreeam 2024-05-29 00:11:25 +08:00
parent de69919c01
commit 2219dd55dd
No known key found for this signature in database
GPG Key ID: 0998F8AFD8F667AB
5 changed files with 88 additions and 1 deletions

View File

@ -14,6 +14,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.File; import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE; import static fr.xephi.authme.message.MessagePathHelper.DEFAULT_LANGUAGE;
@ -33,6 +34,7 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
private String filename; private String filename;
private FileConfiguration configuration; private FileConfiguration configuration;
private ConcurrentHashMap<String, FileConfiguration> i18nConfiguration;
private final String defaultFile; private final String defaultFile;
protected AbstractMessageFileHandler() { protected AbstractMessageFileHandler() {
@ -46,6 +48,7 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
filename = createFilePath(language); filename = createFilePath(language);
File messagesFile = initializeFile(filename); File messagesFile = initializeFile(filename);
configuration = YamlConfiguration.loadConfiguration(messagesFile); configuration = YamlConfiguration.loadConfiguration(messagesFile);
i18nConfiguration = null;
} }
protected String getLanguage() { protected String getLanguage() {
@ -83,6 +86,24 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
: message; : message;
} }
/**
* Returns the i18n message for the given key and given locale.
*
* @param key the key to retrieve the message for
* @param locale the locale that player client setting uses
* @return the message
*/
public String getMessageByLocale(String key, String locale) {
if (locale == null || !settings.getProperty(PluginSettings.I18N_MESSAGES)) {
return getMessage(key);
}
String message = getI18nConfiguration(locale).getString(key);
return message == null
? "Error retrieving message '" + key + "'"
: message;
}
/** /**
* Returns the message for the given key only if it exists, * Returns the message for the given key only if it exists,
* i.e. without falling back to the default file. * i.e. without falling back to the default file.
@ -94,6 +115,25 @@ public abstract class AbstractMessageFileHandler implements Reloadable {
return configuration.getString(key); return configuration.getString(key);
} }
public FileConfiguration getI18nConfiguration(String locale) {
if (i18nConfiguration == null) {
i18nConfiguration = new ConcurrentHashMap<>();
}
if (i18nConfiguration.containsKey(locale)) {
return i18nConfiguration.get(locale);
} else {
// Sync with reload();
String i18nFilename = createFilePath(locale);
File i18nMessagesFile = initializeFile(i18nFilename);
FileConfiguration config = YamlConfiguration.loadConfiguration(i18nMessagesFile);
i18nConfiguration.put(locale, config);
return config;
}
}
/** /**
* Creates the path to the messages file for the given language code. * Creates the path to the messages file for the given language code.
* *

View File

@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.output.ConsoleLoggerFactory;
import fr.xephi.authme.util.PlayerUtils;
import fr.xephi.authme.util.expiring.Duration; import fr.xephi.authme.util.expiring.Duration;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -120,7 +121,8 @@ public class Messages {
* @return The message from the file * @return The message from the file
*/ */
private String retrieveMessage(MessageKey key, CommandSender sender) { private String retrieveMessage(MessageKey key, CommandSender sender) {
String message = messagesFileHandler.getMessage(key.getKey()); String locale = PlayerUtils.getLocale(sender);
String message = messagesFileHandler.getMessageByLocale(key.getKey(), locale);
String displayName = sender.getName(); String displayName = sender.getName();
if (sender instanceof Player) { if (sender instanceof Player) {
displayName = ((Player) sender).getDisplayName(); displayName = ((Player) sender).getDisplayName();

View File

@ -16,6 +16,13 @@ public final class PluginSettings implements SettingsHolder {
public static final Property<Boolean> MENU_UNREGISTER_COMPATIBILITY = public static final Property<Boolean> MENU_UNREGISTER_COMPATIBILITY =
newProperty("3rdPartyFeature.compatibility.menuPlugins", false); newProperty("3rdPartyFeature.compatibility.menuPlugins", false);
@Comment({
"Send i18n messages to player based on their client settings, this option will override `settings.messagesLanguage`",
"This will not affect language of authme help command."
})
public static final Property<Boolean> I18N_MESSAGES =
newProperty("3rdPartyFeature.features.i18nMessages.enabled", false);
@Comment({ @Comment({
"Do you want to enable the session feature?", "Do you want to enable the session feature?",
"If enabled, when a player authenticates successfully,", "If enabled, when a player authenticates successfully,",

View File

@ -1,7 +1,10 @@
package fr.xephi.authme.util; package fr.xephi.authme.util;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.lang.reflect.Method;
/** /**
* Player utilities. * Player utilities.
*/ */
@ -36,4 +39,30 @@ public final class PlayerUtils {
} }
} }
/**
* Returns the locale that player uses.
*
* @param sender The player
*/
public static String getLocale(CommandSender sender) {
String locale = null;
if (sender instanceof Player) {
Player player = (Player) sender;
if (Utils.majorVersion >= 12) {
locale = player.getLocale();
} else {
try {
Method spigotMethod = player.getClass().getMethod("spigot");
Object spigot = spigotMethod.invoke(player);
Method spigotGetLocaleMethod = spigot.getClass().getMethod("getLocale");
locale = (String) spigotGetLocaleMethod.invoke(spigot);
} catch (Exception ignored) {
}
}
}
return locale;
}
} }

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.util;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.output.ConsoleLoggerFactory;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
@ -107,4 +108,12 @@ public final class Utils {
public static boolean isEmailEmpty(String email) { public static boolean isEmailEmpty(String email) {
return StringUtils.isBlank(email) || "your@email.com".equalsIgnoreCase(email); return StringUtils.isBlank(email) || "your@email.com".equalsIgnoreCase(email);
} }
private final static String[] serverVersion = Bukkit.getServer().getBukkitVersion()
.substring(0, Bukkit.getServer().getBukkitVersion().indexOf("-"))
.split("\\.");
private final static int mcFirstVersion = Integer.parseInt(serverVersion[0]);
public final static int majorVersion = Integer.parseInt(serverVersion[1]);
public final static int minorVersion = Integer.parseInt(serverVersion[2]);
} }