mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-01 08:39:31 +01:00
Allow loading extra languages on Bukkit
This commit is contained in:
parent
ad01ee5748
commit
3e3438f0d2
@ -274,6 +274,9 @@ public interface DiscordSRVApi {
|
||||
MODULES(false),
|
||||
DISCORD_COMMANDS(false),
|
||||
|
||||
// Bukkit only
|
||||
TRANSLATIONS(false)
|
||||
|
||||
;
|
||||
|
||||
public static final Set<ReloadFlag> ALL = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(values())));
|
||||
|
@ -20,6 +20,7 @@ package com.discordsrv.bukkit;
|
||||
|
||||
import com.discordsrv.api.DiscordSRVApi;
|
||||
import com.discordsrv.bukkit.command.game.handler.AbstractBukkitCommandHandler;
|
||||
import com.discordsrv.bukkit.component.translation.BukkitTranslationLoader;
|
||||
import com.discordsrv.bukkit.config.connection.BukkitConnectionConfig;
|
||||
import com.discordsrv.bukkit.config.main.BukkitConfig;
|
||||
import com.discordsrv.bukkit.config.manager.BukkitConfigManager;
|
||||
@ -39,30 +40,25 @@ import com.discordsrv.bukkit.scheduler.FoliaScheduler;
|
||||
import com.discordsrv.bukkit.scheduler.IBukkitScheduler;
|
||||
import com.discordsrv.common.ServerDiscordSRV;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.component.translation.Translation;
|
||||
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||
import com.discordsrv.common.debug.data.OnlineMode;
|
||||
import com.discordsrv.common.messageforwarding.game.minecrafttodiscord.MinecraftToDiscordChatModule;
|
||||
import com.discordsrv.common.plugin.PluginManager;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap, BukkitConfig, BukkitConnectionConfig> {
|
||||
|
||||
private BukkitAudiences audiences;
|
||||
private BukkitTranslationLoader translationLoader;
|
||||
|
||||
private final IBukkitScheduler scheduler;
|
||||
private final BukkitConsole console;
|
||||
@ -171,55 +167,6 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
||||
return configManager;
|
||||
}
|
||||
|
||||
private URL findResource(String name) {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
URL url = null;
|
||||
while (classLoader != null && url == null) {
|
||||
url = classLoader.getResource(name);
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private void loadMCTranslations() {
|
||||
Map<String, Translation> translations = new HashMap<>();
|
||||
try {
|
||||
URL enUS = findResource("assets/minecraft/lang/en_US.lang");
|
||||
if (enUS == null) {
|
||||
enUS = findResource("assets/minecraft/lang/en_us.lang");
|
||||
}
|
||||
if (enUS != null) {
|
||||
Properties properties = new Properties();
|
||||
try (InputStream inputStream = enUS.openStream()) {
|
||||
properties.load(inputStream);
|
||||
}
|
||||
|
||||
properties.forEach((k, v) -> translations.put((String) k, Translation.stringFormat((String) v)));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger().debug("Failed to load locale", t);
|
||||
}
|
||||
try {
|
||||
URL enUS = findResource("assets/minecraft/lang/en_us.json");
|
||||
if (enUS != null) {
|
||||
JsonNode node = json().readTree(enUS);
|
||||
node.fields().forEachRemaining(entry -> translations.put(
|
||||
entry.getKey(),
|
||||
Translation.stringFormat(entry.getValue().textValue()))
|
||||
);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger().debug("Failed to load locale", t);
|
||||
}
|
||||
|
||||
if (translations.isEmpty()) {
|
||||
logger().warning("No Minecraft translations were found, some components may not render correctly");
|
||||
} else {
|
||||
componentFactory().translationRegistry().register(Locale.US, translations);
|
||||
logger().debug("Found " + translations.size() + " Minecraft translations for en_us");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() throws Throwable {
|
||||
// Service provider
|
||||
@ -227,7 +174,7 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
||||
|
||||
// Adventure related stuff
|
||||
this.audiences = BukkitAudiences.create(bootstrap.getPlugin());
|
||||
loadMCTranslations();
|
||||
this.translationLoader = new BukkitTranslationLoader(this);
|
||||
|
||||
// Command handler
|
||||
commandHandler = AbstractBukkitCommandHandler.get(this);
|
||||
@ -260,10 +207,22 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
||||
server().getPluginManager().registerEvents(new BukkitConnectionListener(this), plugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReloadResult> reload(Set<ReloadFlag> flags, boolean initial) throws Throwable {
|
||||
List<ReloadResult> results = super.reload(flags, initial);
|
||||
|
||||
if (flags.contains(ReloadFlag.TRANSLATIONS)) {
|
||||
translationLoader.reload();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
super.disable();
|
||||
|
||||
requiredLinkingListener.disable();
|
||||
audiences.close();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,149 @@
|
||||
package com.discordsrv.bukkit.component.translation;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.component.translation.Translation;
|
||||
import com.discordsrv.common.component.translation.TranslationRegistry;
|
||||
import com.discordsrv.common.logging.NamedLogger;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BukkitTranslationLoader {
|
||||
|
||||
private final BukkitDiscordSRV discordSRV;
|
||||
private final NamedLogger logger;
|
||||
|
||||
public BukkitTranslationLoader(BukkitDiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "TRANSLATION_LOADER");
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
try {
|
||||
TranslationRegistry registry = discordSRV.componentFactory().translationRegistry();
|
||||
registry.clear();
|
||||
|
||||
AtomicBoolean any = new AtomicBoolean(false);
|
||||
|
||||
Path languages = discordSRV.dataDirectory().resolve("game_languages");
|
||||
if (Files.exists(languages)) {
|
||||
loadFromFiles(languages, registry, any);
|
||||
}
|
||||
loadMCTranslations(any);
|
||||
|
||||
if (!any.get()) {
|
||||
logger.warning("No Minecraft translations were found, some components may not render correctly");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to reload languages", t);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromFiles(Path folder, TranslationRegistry registry, AtomicBoolean any) throws IOException {
|
||||
try (Stream<Path> paths = Files.list(folder)) {
|
||||
paths.forEach(path -> {
|
||||
String fileName = path.getFileName().toString();
|
||||
int lastDot = fileName.lastIndexOf("\\.");
|
||||
String extension = lastDot == -1 ? null : fileName.substring(lastDot + 1);
|
||||
if (extension == null || !(extension.equals("json") || extension.equals("lang"))) {
|
||||
discordSRV.logger().warning("Unexpected file in game_languages: " + fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String language = fileName.substring(0, lastDot);
|
||||
Locale locale = Locale.forLanguageTag(language);
|
||||
URL url = path.toUri().toURL();
|
||||
|
||||
Map<String, Translation> translations = null;
|
||||
if (path.endsWith(".json")) {
|
||||
translations = getFromJson(url);
|
||||
} else if (path.endsWith(".lang")) {
|
||||
translations = getFromProperties(url);
|
||||
}
|
||||
if (translations != null && !translations.isEmpty()) {
|
||||
registry.register(locale, translations);
|
||||
logger.debug("Loaded " + translations.size() + " translations for " + locale);
|
||||
any.set(true);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.warning("Failed to read language file " + fileName, t);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Translation> getFromProperties(URL url) throws IOException {
|
||||
Map<String, Translation> translations = new HashMap<>();
|
||||
|
||||
Properties properties = new Properties();
|
||||
try (InputStream inputStream = url.openStream()) {
|
||||
properties.load(inputStream);
|
||||
}
|
||||
|
||||
properties.forEach((k, v) -> translations.put((String) k, Translation.stringFormat((String) v)));
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
private Map<String, Translation> getFromJson(URL url) throws IOException {
|
||||
Map<String, Translation> translations = new HashMap<>();
|
||||
|
||||
JsonNode node = discordSRV.json().readTree(url);
|
||||
node.fields().forEachRemaining(entry -> translations.put(
|
||||
entry.getKey(),
|
||||
Translation.stringFormat(entry.getValue().textValue()))
|
||||
);
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
private URL findResource(String name) {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
URL url = null;
|
||||
while (classLoader != null && url == null) {
|
||||
url = classLoader.getResource(name);
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private void loadMCTranslations(AtomicBoolean any) {
|
||||
Map<String, Translation> translations = new HashMap<>();
|
||||
try {
|
||||
URL enUS = findResource("assets/minecraft/lang/en_US.lang");
|
||||
if (enUS == null) {
|
||||
enUS = findResource("assets/minecraft/lang/en_us.lang");
|
||||
}
|
||||
if (enUS != null) {
|
||||
translations = getFromProperties(enUS);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.debug("Failed to load locale", t);
|
||||
}
|
||||
try {
|
||||
URL enUS = findResource("assets/minecraft/lang/en_us.json");
|
||||
if (enUS != null) {
|
||||
translations = getFromJson(enUS);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.debug("Failed to load locale", t);
|
||||
}
|
||||
|
||||
if (!translations.isEmpty()) {
|
||||
discordSRV.componentFactory().translationRegistry().register(Locale.US, translations);
|
||||
logger.debug("Found " + translations.size() + " Minecraft translations for en_us");
|
||||
any.set(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -55,4 +55,8 @@ public class TranslationRegistry {
|
||||
).get(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
translations.clear();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user