Skip to content

Commit 8c9d1fe

Browse files
committed
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.
1 parent b885e22 commit 8c9d1fe

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,5 @@ locales/
244244
/cache/
245245
/packs/
246246
/dump.json
247-
/saved-refresh-tokens.json
247+
/saved-refresh-tokens.json
248+
/languages/

core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java

+36-7
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
import org.geysermc.geyser.GeyserBootstrap;
2929
import org.geysermc.geyser.GeyserImpl;
3030

31-
import java.io.IOException;
32-
import java.io.InputStream;
33-
import java.io.InputStreamReader;
31+
import java.io.*;
3432
import java.nio.charset.StandardCharsets;
33+
import java.nio.file.Files;
34+
import java.nio.file.Path;
3535
import java.text.MessageFormat;
3636
import java.util.HashMap;
3737
import java.util.Locale;
@@ -116,12 +116,22 @@ private static String loadGeyserLocale(String locale, GeyserBootstrap bootstrap)
116116
return locale;
117117
}
118118

119+
Properties localeProp = new Properties();
120+
121+
File localLanguage;
122+
Path localFolder = bootstrap.getConfigFolder().resolve("languages");
123+
if (Files.exists(localFolder)) {
124+
localLanguage = localFolder.resolve(locale + ".properties").toFile();
125+
} else {
126+
localLanguage = null;
127+
}
128+
boolean validLocalLanguage = localLanguage != null && localLanguage.exists();
129+
119130
InputStream localeStream = bootstrap.getResourceOrNull("languages/texts/" + locale + ".properties");
120131

121132
// Load the locale
122133
if (localeStream != null) {
123134
try {
124-
Properties localeProp = new Properties();
125135
try (InputStreamReader reader = new InputStreamReader(localeStream, StandardCharsets.UTF_8)) {
126136
localeProp.load(reader);
127137
} catch (Exception e) {
@@ -130,18 +140,37 @@ private static String loadGeyserLocale(String locale, GeyserBootstrap bootstrap)
130140

131141
// Insert the locale into the mappings
132142
LOCALE_MAPPINGS.put(locale, localeProp);
133-
return locale;
134143
} finally {
135144
try {
136145
localeStream.close();
137146
} catch (IOException ignored) {}
138147
}
139148
} else {
140-
if (GeyserImpl.getInstance() != null) {
149+
if (GeyserImpl.getInstance() != null && !validLocalLanguage) {
150+
// Don't warn on missing locales if a local file has been found
141151
GeyserImpl.getInstance().getLogger().warning("Missing locale: " + locale);
142152
}
143-
return null;
144153
}
154+
155+
// Load any language overrides that exist after, to override any strings that we just added
156+
// By loading both, we ensure that if a language string doesn't exist in the custom properties folder,
157+
// it's loaded from our jar
158+
if (validLocalLanguage) {
159+
try (InputStream stream = new FileInputStream(localLanguage)) {
160+
localeProp.load(stream);
161+
} catch (IOException e) {
162+
String message = "Unable to load custom language override!";
163+
if (GeyserImpl.getInstance() != null) {
164+
GeyserImpl.getInstance().getLogger().error(message, e);
165+
} else {
166+
System.err.println(message);
167+
e.printStackTrace();
168+
}
169+
}
170+
171+
LOCALE_MAPPINGS.putIfAbsent(locale, localeProp);
172+
}
173+
return localeProp.isEmpty() ? null : locale;
145174
}
146175

147176
/**

0 commit comments

Comments
 (0)