Load english translations even if the pack is not loaded
ci/woodpecker/push/docs Pipeline was successful Details
ci/woodpecker/push/jfmod Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2023-02-23 21:29:57 +01:00
parent 305417471b
commit 9340f981fc
Signed by: Johannes
GPG Key ID: E76429612C2929F4
5 changed files with 94 additions and 11 deletions

View File

@ -0,0 +1,24 @@
package io.gitlab.jfronny.respackopts.mixin;
import com.google.common.collect.ImmutableMap;
import io.gitlab.jfronny.respackopts.util.FallbackI18n;
import net.minecraft.client.resource.language.*;
import net.minecraft.resource.ResourceManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.*;
@Mixin(LanguageManager.class)
public class LanguageManagerMixin {
@Inject(method = "reload(Lnet/minecraft/resource/ResourceManager;)V", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILSOFT)
private void rpo$appendTranslations(ResourceManager manager, CallbackInfo ci, LanguageDefinition languageDefinition, List<LanguageDefinition> list, TranslationStorage translationStorage) {
TranslationStorageAccessor storage = (TranslationStorageAccessor) translationStorage;
Map<String, String> map = new HashMap<>(storage.getTranslations());
FallbackI18n.insertInto(map);
storage.setTranslations(ImmutableMap.copyOf(map));
}
}

View File

@ -0,0 +1,18 @@
package io.gitlab.jfronny.respackopts.mixin;
import net.minecraft.client.resource.language.TranslationStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Map;
@Mixin(TranslationStorage.class)
public interface TranslationStorageAccessor {
@Accessor("translations")
Map<String, String> getTranslations();
@Accessor("translations")
@Mutable
void setTranslations(Map<String, String> translations);
}

View File

@ -5,9 +5,11 @@
"compatibilityLevel": "JAVA_8",
"client": [
"GLImportProcessorMixin",
"LanguageManagerMixin",
"OptionsScreenMixin",
"PackScreenMixin",
"ResourcePackEntryMixin"
"ResourcePackEntryMixin",
"TranslationStorageAccessor"
],
"injectors": {
"defaultRequire": 1

View File

@ -5,9 +5,11 @@ import io.gitlab.jfronny.respackopts.RespackoptsConfig;
import io.gitlab.jfronny.respackopts.integration.SaveHook;
import io.gitlab.jfronny.respackopts.model.PackMeta;
import io.gitlab.jfronny.respackopts.model.cache.CacheKey;
import io.gitlab.jfronny.respackopts.util.FallbackI18n;
import io.gitlab.jfronny.respackopts.util.MetaCache;
import net.minecraft.resource.*;
import net.minecraft.util.Identifier;
import net.minecraft.util.Language;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -24,11 +26,13 @@ public class ResourcePackManagerMixin {
@Inject(at = @At("TAIL"), method = "scanPacks()V")
private void scanPacks(CallbackInfo info) {
FallbackI18n.clear();
Set<Path> toRemove = new HashSet<>(dataLocations);
dataLocations.clear();
profiles.forEach((s, v) -> {
try (ResourcePack rpi = v.createResourcePack()) {
rpo$checkProfile(s, v.getDisplayName().getString(), rpi, toRemove);
String id = rpo$checkProfile(s, v.getDisplayName().getString(), rpi, toRemove);
if (id != null) rpo$loadTranslations(rpi, id);
}
});
for (Path s : toRemove) {
@ -38,7 +42,7 @@ public class ResourcePackManagerMixin {
MetaCache.save(SaveHook.Arguments.DO_NOTHING);
}
private void rpo$checkProfile(String profileName, String displayName, ResourcePack rpi, Set<Path> toRemove) {
private String rpo$checkProfile(String profileName, String displayName, ResourcePack rpi, Set<Path> toRemove) {
Path dataLocation = null;
if (rpi instanceof DirectoryResourcePack drp) {
Path pack = ((DirectoryResourcePackAccessor) drp).getRoot();
@ -53,8 +57,7 @@ public class ResourcePackManagerMixin {
var conf = rpi.openRoot(Respackopts.ID + ".json5");
if (conf != null) {
try (InputStream is = conf.get()) {
rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove);
return;
return rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove);
} catch (Throwable e) {
String message = "Could not read respackopts config in root for " + profileName;
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.error(message, e);
@ -67,28 +70,44 @@ public class ResourcePackManagerMixin {
conf = rpi.open(type, confId);
if (conf != null) {
try (InputStream is = conf.get()) {
rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove);
return;
return rpo$readConfiguration(is, dataLocation, rpi.getName(), displayName, toRemove);
} catch (Throwable e) {
Respackopts.LOGGER.error("Could not initialize pack meta for " + profileName, e);
}
}
}
return null;
}
private void rpo$readConfiguration(InputStream is, Path dataLocation, String packName, String displayName, Set<Path> toRemove) throws IOException {
private String rpo$readConfiguration(InputStream is, Path dataLocation, String packName, String displayName, Set<Path> toRemove) throws IOException {
try (InputStreamReader isr = new InputStreamReader(is)) {
PackMeta conf = Respackopts.GSON.fromJson(isr, PackMeta.class);
if (RespackoptsConfig.debugLogs)
Respackopts.LOGGER.info("Discovered pack: " + conf.id);
if (RespackoptsConfig.debugLogs) Respackopts.LOGGER.info("Discovered pack: " + conf.id);
if (Respackopts.META_VERSION < conf.version) {
Respackopts.LOGGER.error(displayName + " was not loaded as it specifies a newer respackopts version than is installed");
return;
return null;
}
if (dataLocation == null) dataLocation = Respackopts.FALLBACK_CONF_DIR.resolve(conf.id + ".json");
MetaCache.addFromScan(displayName, packName, conf, dataLocation);
dataLocations.add(dataLocation);
toRemove.remove(dataLocation);
return conf.id;
}
}
private void rpo$loadTranslations(ResourcePack rpi, String id) {
for (String namespace : rpi.getNamespaces(ResourceType.CLIENT_RESOURCES)) {
var translation = rpi.open(ResourceType.CLIENT_RESOURCES, new Identifier(namespace, "lang/en_us.json"));
if (translation == null) continue;
try (InputStream is = translation.get()) {
Language.load(is, (key, value) -> {
if (key.startsWith("rpo." + id + ".")) {
FallbackI18n.put(key, value);
}
});
} catch (Throwable ignored) {
}
}
}
}

View File

@ -0,0 +1,20 @@
package io.gitlab.jfronny.respackopts.util;
import java.util.HashMap;
import java.util.Map;
public class FallbackI18n {
private static final Map<String, String> translations = new HashMap<>();
public static void clear() {
translations.clear();
}
public static void put(String key, String value) {
translations.put(key, value);
}
public static void insertInto(Map<String, String> target) {
translations.forEach(target::putIfAbsent);
}
}