Files
fabric-carpet/src/main/java/carpet/utils/Translations.java
T

127 lines
4.9 KiB
Java

package carpet.utils;
import carpet.CarpetExtension;
import carpet.CarpetServer;
import carpet.CarpetSettings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class Translations
{
private static Map<String, String> translationMap = Collections.emptyMap();
public static String tr(String key)
{
return translationMap.getOrDefault(key, key);
}
public static String trOrNull(String key)
{
return translationMap.get(key);
}
public static String tr(String key, String str)
{
return translationMap.getOrDefault(key, str);
}
public static boolean hasTranslations()
{
return !translationMap.isEmpty();
}
public static boolean hasTranslation(String key)
{
return translationMap.containsKey(key);
}
public static Map<String, String> getTranslationFromResourcePath(String path)
{
InputStream langFile = Translations.class.getClassLoader().getResourceAsStream(path);
if (langFile == null) {
// we don't have that language
return Collections.emptyMap();
}
Gson gson = new GsonBuilder().setLenient().create();
return gson.fromJson(new InputStreamReader(langFile, StandardCharsets.UTF_8),
new TypeToken<Map<String, String>>() {});
}
public static void updateLanguage()
{
Map<String, String> translations = new HashMap<>();
translations.putAll(getTranslationFromResourcePath(String.format("assets/carpet/lang/%s.json", CarpetSettings.language)));
for (CarpetExtension ext : CarpetServer.extensions)
{
Map<String, String> extMappings = ext.canHasTranslations(CarpetSettings.language);
if (extMappings == null) continue; // would be nice to get rid of this, but too many extensions return null where they don't know they do
boolean warned = false;
for (var entry : extMappings.entrySet()) {
var key = entry.getKey();
// Migrate the old format
if (!key.startsWith("carpet.")) {
if (key.startsWith("rule.")) {
// default to carpet's settings manager. Custom managers are really uncommon and the known ones don't provide translations anyway
key = TranslationKeys.BASE_RULE_NAMESPACE.formatted("carpet") + key.substring(5);
} else if (key.startsWith("category.")) {
key = TranslationKeys.CATEGORY_PATTERN.formatted("carpet", key.substring(9));
}
if (!warned && key != entry.getKey()) {
CarpetSettings.LOG.warn("""
Found outdated translation keys in extension '%s'!
These won't be supported in a later Carpet version!
Carpet will now try to map them to the correct keys in a best-effort basis""".formatted(ext.getClass().getName()));
warned = true;
}
}
translations.putIfAbsent(key, entry.getValue());
}
}
translations.keySet().removeIf(e -> {
if (e.startsWith("//")) {
CarpetSettings.LOG.warn("""
Found translation key starting with // while preparing translations!
Doing this is deprecated and may cause issues in later versions! Consider settings GSON to "lenient" mode and
using regular comments instead!
Translation key is '%s'""".formatted(e));
return true;
} else
return false;
});
// Remove after deprecated settings api is removed
addFallbacksTo(translations);
translationMap = translations;
}
public static boolean isValidLanguage(String newValue)
{
// will put some validations for availble languages at some point
return true;
}
// fallbacks for old rules that don't define rule descriptions or stuff in language files yet
// to be removed when old settings system is removed and translation refactor is finished
private static final Map<String, String> FALLBACKS = new HashMap<>();
/**
* @deprecated if you compile against this method I'll steal your kneecaps
*/
@Deprecated(forRemoval = true)
public static void registerFallbackTranslation(String key, String description) {
FALLBACKS.put(key, description);
}
private static void addFallbacksTo(Map<String, String> translationMap) {
FALLBACKS.forEach(translationMap::putIfAbsent);
}
}