Allow language file overrides

By placing a locale file in `languages/ll_CC.properties`, any strings in that file will take priority over Geyser's own.
This commit is contained in:
Camotoy 2022-05-15 14:23:52 -04:00
parent b885e22fa3
commit 8c9d1fe09f
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
2 changed files with 38 additions and 8 deletions

3
.gitignore vendored
View file

@ -244,4 +244,5 @@ locales/
/cache/ /cache/
/packs/ /packs/
/dump.json /dump.json
/saved-refresh-tokens.json /saved-refresh-tokens.json
/languages/

View file

@ -28,10 +28,10 @@ package org.geysermc.geyser.text;
import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import java.io.IOException; import java.io.*;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -116,12 +116,22 @@ public class GeyserLocale {
return locale; return locale;
} }
Properties localeProp = new Properties();
File localLanguage;
Path localFolder = bootstrap.getConfigFolder().resolve("languages");
if (Files.exists(localFolder)) {
localLanguage = localFolder.resolve(locale + ".properties").toFile();
} else {
localLanguage = null;
}
boolean validLocalLanguage = localLanguage != null && localLanguage.exists();
InputStream localeStream = bootstrap.getResourceOrNull("languages/texts/" + locale + ".properties"); InputStream localeStream = bootstrap.getResourceOrNull("languages/texts/" + locale + ".properties");
// Load the locale // Load the locale
if (localeStream != null) { if (localeStream != null) {
try { try {
Properties localeProp = new Properties();
try (InputStreamReader reader = new InputStreamReader(localeStream, StandardCharsets.UTF_8)) { try (InputStreamReader reader = new InputStreamReader(localeStream, StandardCharsets.UTF_8)) {
localeProp.load(reader); localeProp.load(reader);
} catch (Exception e) { } catch (Exception e) {
@ -130,18 +140,37 @@ public class GeyserLocale {
// Insert the locale into the mappings // Insert the locale into the mappings
LOCALE_MAPPINGS.put(locale, localeProp); LOCALE_MAPPINGS.put(locale, localeProp);
return locale;
} finally { } finally {
try { try {
localeStream.close(); localeStream.close();
} catch (IOException ignored) {} } catch (IOException ignored) {}
} }
} else { } else {
if (GeyserImpl.getInstance() != null) { if (GeyserImpl.getInstance() != null && !validLocalLanguage) {
// Don't warn on missing locales if a local file has been found
GeyserImpl.getInstance().getLogger().warning("Missing locale: " + locale); GeyserImpl.getInstance().getLogger().warning("Missing locale: " + locale);
} }
return null;
} }
// Load any language overrides that exist after, to override any strings that we just added
// By loading both, we ensure that if a language string doesn't exist in the custom properties folder,
// it's loaded from our jar
if (validLocalLanguage) {
try (InputStream stream = new FileInputStream(localLanguage)) {
localeProp.load(stream);
} catch (IOException e) {
String message = "Unable to load custom language override!";
if (GeyserImpl.getInstance() != null) {
GeyserImpl.getInstance().getLogger().error(message, e);
} else {
System.err.println(message);
e.printStackTrace();
}
}
LOCALE_MAPPINGS.putIfAbsent(locale, localeProp);
}
return localeProp.isEmpty() ? null : locale;
} }
/** /**