Compare commits
No commits in common. "master" and "1.7.1" have entirely different histories.
@ -1,17 +1,16 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("jfmod") version "1.6-SNAPSHOT"
|
id("jfmod") version "1.5-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects { group = "io.gitlab.jfronny" }
|
allprojects { group = "io.gitlab.jfronny" }
|
||||||
base.archivesName = "translater"
|
base.archivesName = "translater"
|
||||||
|
|
||||||
val modmenuVersion = "11.0.0-beta.1"
|
val modmenuVersion = "8.0.0-beta.2"
|
||||||
jfMod {
|
jfMod {
|
||||||
minecraftVersion = "1.21"
|
minecraftVersion = "1.20.2"
|
||||||
yarn("build.1")
|
yarn("build.1")
|
||||||
loaderVersion = "0.15.11"
|
loaderVersion = "0.14.22"
|
||||||
libJfVersion = "3.16.0"
|
libJfVersion = "3.13.1"
|
||||||
fabricApiVersion = "0.100.1+1.21"
|
|
||||||
|
|
||||||
modrinth {
|
modrinth {
|
||||||
projectId = "translater"
|
projectId = "translater"
|
||||||
@ -26,15 +25,11 @@ jfMod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v2")
|
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v2:${jfMod.libJfVersion.get()}")
|
||||||
modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1")
|
modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1:${jfMod.libJfVersion.get()}")
|
||||||
|
|
||||||
// Dev env
|
// Dev env
|
||||||
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny")
|
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny:${jfMod.libJfVersion.get()}")
|
||||||
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil")
|
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${jfMod.libJfVersion.get()}")
|
||||||
modLocalRuntime("com.terraformersmc:modmenu:$modmenuVersion")
|
modLocalRuntime("com.terraformersmc:modmenu:$modmenuVersion")
|
||||||
// for modmenu
|
|
||||||
modLocalRuntime("net.fabricmc.fabric-api:fabric-resource-loader-v0")
|
|
||||||
modLocalRuntime("net.fabricmc.fabric-api:fabric-screen-api-v1")
|
|
||||||
modLocalRuntime("net.fabricmc.fabric-api:fabric-key-binding-api-v1")
|
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,13 @@ package io.gitlab.jfronny.translater;
|
|||||||
import io.gitlab.jfronny.libjf.config.api.v2.Entry;
|
import io.gitlab.jfronny.libjf.config.api.v2.Entry;
|
||||||
import io.gitlab.jfronny.libjf.config.api.v2.JfConfig;
|
import io.gitlab.jfronny.libjf.config.api.v2.JfConfig;
|
||||||
|
|
||||||
@JfConfig(referencedConfigs = "libjf-translate-v1", tweaker = CfgMigration.class)
|
@JfConfig(referencedConfigs = "libjf-translate-v1")
|
||||||
public class Cfg {
|
public class Cfg {
|
||||||
@Entry public static int rounds = 5;
|
@Entry public static int rounds = 5;
|
||||||
@Entry public static boolean breakFully = false;
|
@Entry public static boolean breakFully = false;
|
||||||
@Entry public static String targetLanguage = "en";
|
@Entry public static String targetLanguage = "en";
|
||||||
@Entry public static boolean progressGui = false;
|
@Entry public static ProgressMode renderProgress = ProgressMode.None;
|
||||||
@Entry public static boolean progressConsole = true;
|
|
||||||
@Entry public static boolean detailedProgress = false;
|
|
||||||
@Entry public static boolean forceRegenerate = false;
|
@Entry public static boolean forceRegenerate = false;
|
||||||
@Entry public static boolean useDefaultCache = true;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
JFC_Cfg.ensureInitialized();
|
JFC_Cfg.ensureInitialized();
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
package io.gitlab.jfronny.translater;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.config.api.v2.dsl.ConfigBuilder;
|
|
||||||
import io.gitlab.jfronny.libjf.config.api.v2.dsl.Migration;
|
|
||||||
|
|
||||||
public class CfgMigration {
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public static ConfigBuilder<?> tweak(ConfigBuilder<?> cb) {
|
|
||||||
return cb.addMigration("renderProgress", Migration.of(reader -> {
|
|
||||||
String renderMode = reader.nextString();
|
|
||||||
if (renderMode == null) return;
|
|
||||||
switch (renderMode.toLowerCase()) {
|
|
||||||
case "full" -> Cfg.progressGui = Cfg.progressConsole = Cfg.detailedProgress = true;
|
|
||||||
case "gui" -> {
|
|
||||||
Cfg.progressConsole = Cfg.detailedProgress = false;
|
|
||||||
Cfg.progressGui = true;
|
|
||||||
}
|
|
||||||
case "console" -> {
|
|
||||||
Cfg.progressGui = Cfg.detailedProgress = false;
|
|
||||||
Cfg.progressConsole = true;
|
|
||||||
}
|
|
||||||
case "none" -> Cfg.progressGui = Cfg.progressConsole = Cfg.detailedProgress = false;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package io.gitlab.jfronny.translater;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.translater.mixin.MinecraftClientAccessor;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
public class RenderScheduler {
|
|
||||||
private final AtomicBoolean shouldRun = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
public void scheduleRender() {
|
|
||||||
shouldRun.set(true);
|
|
||||||
MinecraftClient mc = MinecraftClient.getInstance();
|
|
||||||
if (mc != null && mc.isOnThread()) performTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deschedule() {
|
|
||||||
shouldRun.set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void performTask() {
|
|
||||||
do {
|
|
||||||
((MinecraftClientAccessor) MinecraftClient.getInstance()).invokeRender(false);
|
|
||||||
} while (shouldRun.compareAndSet(true, false));
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ package io.gitlab.jfronny.translater;
|
|||||||
|
|
||||||
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
||||||
import io.gitlab.jfronny.translater.transformer.CachingTransformer;
|
import io.gitlab.jfronny.translater.transformer.CachingTransformer;
|
||||||
import io.gitlab.jfronny.translater.transformer.FailTransformer;
|
|
||||||
import io.gitlab.jfronny.translater.transformer.TransformingMap;
|
import io.gitlab.jfronny.translater.transformer.TransformingMap;
|
||||||
import io.gitlab.jfronny.translater.transformer.TranslatingTransformer;
|
import io.gitlab.jfronny.translater.transformer.TranslatingTransformer;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
@ -18,16 +17,13 @@ import java.util.Map;
|
|||||||
public class Translater {
|
public class Translater {
|
||||||
public static final String MOD_ID = "translater";
|
public static final String MOD_ID = "translater";
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||||
private static final TransformingMap map;
|
private static final TransformingMap map = new TransformingMap(new CachingTransformer(new TranslatingTransformer<>(TranslateService.getConfigured())));
|
||||||
|
|
||||||
static {
|
public static boolean progressUIEnabled() {
|
||||||
TranslateService<?> ts = TranslateService.getConfigured();
|
return Cfg.renderProgress == ProgressMode.Full || Cfg.renderProgress == ProgressMode.Gui;
|
||||||
if (ts == null || ts.getName().equals("Noop")) {
|
}
|
||||||
LOGGER.error("No translation service found! Please configure a translation service in the libjf-translate config and restart the game!\nThis means NO NEW TRANSLATIONS WILL BE GENERATED!");
|
public static boolean progressLogsEnabled() {
|
||||||
map = new TransformingMap(new CachingTransformer(new FailTransformer()));
|
return Cfg.renderProgress == ProgressMode.Full || Cfg.renderProgress == ProgressMode.Console;
|
||||||
} else {
|
|
||||||
map = new TransformingMap(new CachingTransformer(new TranslatingTransformer<>(ts)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull TransformingMap getMap(@Nullable Map<String, String> base) {
|
public static @NotNull TransformingMap getMap(@Nullable Map<String, String> base) {
|
||||||
|
@ -4,29 +4,18 @@ import io.gitlab.jfronny.translater.Translater;
|
|||||||
import net.minecraft.client.resource.language.TranslationStorage;
|
import net.minecraft.client.resource.language.TranslationStorage;
|
||||||
import net.minecraft.util.Language;
|
import net.minecraft.util.Language;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.*;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Map;
|
@Mixin(Language.class)
|
||||||
|
|
||||||
@Mixin(value = Language.class, priority = 900)
|
|
||||||
public class LanguageMixin {
|
public class LanguageMixin {
|
||||||
@ModifyVariable(at = @At("HEAD"), method = "setInstance", argsOnly = true)
|
@Inject(at = @At("HEAD"), method = "setInstance")
|
||||||
private static Language languageSetInstance(Language language) {
|
private static void languageSetInstance(Language language, CallbackInfo ci) {
|
||||||
if (language instanceof TranslationStorage t) {
|
if (language instanceof TranslationStorage t) {
|
||||||
TranslationStorageAccessor ta = (TranslationStorageAccessor) t;
|
TranslationStorageAccessor ta = (TranslationStorageAccessor) t;
|
||||||
ta.setTranslations(Translater.getMap(ta.getTranslations()));
|
ta.setTranslations(Translater.getMap(ta.getTranslations()));
|
||||||
Translater.LOGGER.info("Set translater backend 2");
|
Translater.LOGGER.info("Set translater backend");
|
||||||
} else Translater.LOGGER.error("Unsupported language configured: {}", language);
|
}
|
||||||
return language;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyArg(
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Language$1;<init>(Ljava/util/Map;)V"),
|
|
||||||
method = "create()Lnet/minecraft/util/Language;",
|
|
||||||
index = 0
|
|
||||||
)
|
|
||||||
private static Map<String, String> postCreate(Map<String, String> par1) {
|
|
||||||
Translater.LOGGER.info("Set translater backend 1");
|
|
||||||
return Translater.getMap(par1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.gitlab.jfronny.translater.mixin;
|
package io.gitlab.jfronny.translater.mixin;
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.LibJf;
|
import io.gitlab.jfronny.libjf.LibJf;
|
||||||
import io.gitlab.jfronny.translater.Cfg;
|
import io.gitlab.jfronny.translater.Translater;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||||
@ -28,9 +28,9 @@ public class Plugin implements IMixinConfigPlugin {
|
|||||||
|| Objects.equals(mixinClassName, TranslationStorageAccessor.class.getName()))
|
|| Objects.equals(mixinClassName, TranslationStorageAccessor.class.getName()))
|
||||||
return true;
|
return true;
|
||||||
else if (Objects.equals(mixinClassName, MinecraftClientAccessor.class.getName()))
|
else if (Objects.equals(mixinClassName, MinecraftClientAccessor.class.getName()))
|
||||||
return Cfg.progressGui;
|
return Translater.progressUIEnabled();
|
||||||
else if (Objects.equals(mixinClassName, SplashScreenMixin.class.getName()))
|
else if (Objects.equals(mixinClassName, SplashScreenMixin.class.getName()))
|
||||||
return Cfg.progressGui;
|
return Translater.progressUIEnabled();
|
||||||
else
|
else
|
||||||
throw new IllegalStateException("Unrecognized mixin! This should never happen");
|
throw new IllegalStateException("Unrecognized mixin! This should never happen");
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Mixin(SplashOverlay.class)
|
@Mixin(SplashOverlay.class)
|
||||||
public abstract class SplashScreenMixin extends Overlay {
|
public abstract class SplashScreenMixin extends Overlay {
|
||||||
@Shadow @Final private MinecraftClient client;
|
@Shadow @Final private MinecraftClient client;
|
||||||
|
|
||||||
@Unique private TextRenderer translater$textRenderer;
|
private TextRenderer translater$textRenderer;
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "renderProgressBar")
|
@Inject(at = @At("RETURN"), method = "renderProgressBar")
|
||||||
private void renderTranslationProgress(DrawContext context, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) {
|
private void renderTranslationProgress(DrawContext context, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) {
|
||||||
@ -35,7 +34,7 @@ public abstract class SplashScreenMixin extends Overlay {
|
|||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
public void setup(CallbackInfo ci) throws IOException {
|
public void setup(CallbackInfo ci) throws IOException {
|
||||||
final FontStorage fontStorage = new FontStorage(client.getTextureManager(), Identifier.ofVanilla("loading"));
|
final FontStorage fontStorage = new FontStorage(client.getTextureManager(), new Identifier("loading"));
|
||||||
Font font = JsonOps.INSTANCE.getMap(JsonParser.parseString("""
|
Font font = JsonOps.INSTANCE.getMap(JsonParser.parseString("""
|
||||||
{
|
{
|
||||||
"type": "bitmap",
|
"type": "bitmap",
|
||||||
@ -61,9 +60,10 @@ public abstract class SplashScreenMixin extends Overlay {
|
|||||||
]
|
]
|
||||||
}""").getAsJsonObject())
|
}""").getAsJsonObject())
|
||||||
.flatMap(ml -> FontType.BITMAP.getLoaderCodec().decode(JsonOps.INSTANCE, ml))
|
.flatMap(ml -> FontType.BITMAP.getLoaderCodec().decode(JsonOps.INSTANCE, ml))
|
||||||
.map(fl -> fl.build().left().orElseThrow()).getOrThrow()
|
.map(fl -> fl.build().left().orElseThrow()).get()
|
||||||
|
.left().orElseThrow()
|
||||||
.load(client.getResourceManager());
|
.load(client.getResourceManager());
|
||||||
fontStorage.setFonts(Collections.singletonList(new Font.FontFilterPair(font, FontFilterType.FilterMap.NO_FILTER)), Set.of());
|
fontStorage.setFonts(Collections.singletonList(font));
|
||||||
translater$textRenderer = new TextRenderer(id -> fontStorage, false);
|
translater$textRenderer = new TextRenderer(id -> fontStorage, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
package io.gitlab.jfronny.translater.transformer;
|
package io.gitlab.jfronny.translater.transformer;
|
||||||
|
|
||||||
import io.gitlab.jfronny.commons.concurrent.AsyncRequestState;
|
|
||||||
import io.gitlab.jfronny.libjf.config.api.v2.ConfigHolder;
|
import io.gitlab.jfronny.libjf.config.api.v2.ConfigHolder;
|
||||||
import io.gitlab.jfronny.translater.Cfg;
|
import io.gitlab.jfronny.translater.Cfg;
|
||||||
import io.gitlab.jfronny.translater.Translater;
|
import io.gitlab.jfronny.translater.Translater;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class CachingTransformer implements Transformer {
|
public class CachingTransformer implements Transformer {
|
||||||
private static final Path CACHE_FILE = FabricLoader.getInstance().getConfigDir().resolve(Translater.MOD_ID + ".cache");
|
private static final Path CACHE_FILE = FabricLoader.getInstance().getConfigDir().resolve(Translater.MOD_ID + ".cache");
|
||||||
private final @Nullable Properties defaultCache;
|
|
||||||
private final Properties cache = new Properties();
|
private final Properties cache = new Properties();
|
||||||
private final Transformer transformer;
|
private final Transformer transformer;
|
||||||
|
|
||||||
@ -26,47 +21,18 @@ public class CachingTransformer implements Transformer {
|
|||||||
return null;
|
return null;
|
||||||
//Transform and cache if not present
|
//Transform and cache if not present
|
||||||
if (!cache.containsKey(str)) {
|
if (!cache.containsKey(str)) {
|
||||||
if (defaultCache != null && defaultCache.containsKey(str)) return (String) defaultCache.get(str);
|
|
||||||
String transformed = transformer.transform(str);
|
String transformed = transformer.transform(str);
|
||||||
if (transformed == null) {
|
if (transformed == null) {
|
||||||
// The transformer failed
|
// The transformer failed
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
cache.put(str, transformed);
|
cache.put(str, transformed);
|
||||||
scheduleSave();
|
save();
|
||||||
}
|
}
|
||||||
//Return cached result
|
//Return cached result
|
||||||
return (String) cache.get(str);
|
return (String) cache.get(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformMultiple(Stream<? extends String> strings, ResultConsumer results) {
|
|
||||||
AtomicInteger count = new AtomicInteger(0);
|
|
||||||
transformer.transformMultiple(strings.filter(s -> {
|
|
||||||
String translation = (String) cache.get(s);
|
|
||||||
if (translation != null) {
|
|
||||||
results.accept(s, translation);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (defaultCache != null) {
|
|
||||||
translation = (String) defaultCache.get(s);
|
|
||||||
if (translation != null) {
|
|
||||||
results.accept(s, translation);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}), (str, translation) -> {
|
|
||||||
cache.put(str, translation);
|
|
||||||
results.accept(str, translation);
|
|
||||||
if (count.incrementAndGet() == 50) {
|
|
||||||
count.addAndGet(-50);
|
|
||||||
scheduleSave();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (count.get() > 0) scheduleSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CachingTransformer(Transformer baseTransformer) {
|
public CachingTransformer(Transformer baseTransformer) {
|
||||||
transformer = baseTransformer;
|
transformer = baseTransformer;
|
||||||
if (Cfg.forceRegenerate) {
|
if (Cfg.forceRegenerate) {
|
||||||
@ -81,37 +47,32 @@ public class CachingTransformer implements Transformer {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Translater.LOGGER.error("Could not load translater cache", e);
|
Translater.LOGGER.error("Could not load translater cache", e);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
//Save default cache if parameters are default
|
||||||
//Save default cache if parameters are default
|
if (!Cfg.breakFully && Cfg.rounds == 5) {
|
||||||
if (Cfg.useDefaultCache && !Cfg.breakFully && Cfg.rounds == 5 && "en".equals(Cfg.targetLanguage) && !Cfg.forceRegenerate) {
|
Translater.LOGGER.info("Initializing default cache");
|
||||||
Translater.LOGGER.info("Initializing default cache");
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
InputStream inS = classLoader.getResourceAsStream("namecache.ini");
|
||||||
Properties p = new Properties();
|
if (inS != null) {
|
||||||
try (InputStream inS = classLoader.getResourceAsStream("namecache.ini")) {
|
try {
|
||||||
if (inS == null) p = null;
|
cache.load(inS);
|
||||||
else p.load(inS);
|
inS.close();
|
||||||
} catch (IOException e) {
|
save();
|
||||||
p = null;
|
} catch (IOException e) {
|
||||||
Translater.LOGGER.error("Could not initialize default translater cache", e);
|
Translater.LOGGER.error("Could not initialize default translater cache");
|
||||||
}
|
}
|
||||||
defaultCache = p;
|
|
||||||
} else defaultCache = null;
|
|
||||||
scheduleSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final AsyncRequestState state = new AsyncRequestState();
|
|
||||||
private void scheduleSave() {
|
|
||||||
if (state.request().shouldStart()) {
|
|
||||||
do {
|
|
||||||
if (!cache.isEmpty()) {
|
|
||||||
try (OutputStream outS = Files.newOutputStream(CACHE_FILE)) {
|
|
||||||
cache.store(outS, "---Lang---");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Translater.LOGGER.error("Could not save translater cache");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (state.emitFinished().shouldContinue());
|
}
|
||||||
|
}
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save() {
|
||||||
|
try (OutputStream outS = Files.newOutputStream(CACHE_FILE)) {
|
||||||
|
cache.store(outS, "---Lang---");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Translater.LOGGER.error("Could not save translater cache");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package io.gitlab.jfronny.translater.transformer;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class FailTransformer implements Transformer {
|
|
||||||
@Override
|
|
||||||
public String transform(String str) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformMultiple(Stream<? extends String> strings, ResultConsumer results) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +1,5 @@
|
|||||||
package io.gitlab.jfronny.translater.transformer;
|
package io.gitlab.jfronny.translater.transformer;
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public interface Transformer {
|
public interface Transformer {
|
||||||
String transform(String str);
|
String transform(String str);
|
||||||
void transformMultiple(Stream<? extends String> strings, ResultConsumer results);
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface ResultConsumer {
|
|
||||||
void accept(String str, String translation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
package io.gitlab.jfronny.translater.transformer;
|
package io.gitlab.jfronny.translater.transformer;
|
||||||
|
|
||||||
import io.gitlab.jfronny.translater.Cfg;
|
|
||||||
import io.gitlab.jfronny.translater.RenderScheduler;
|
|
||||||
import io.gitlab.jfronny.translater.Translater;
|
import io.gitlab.jfronny.translater.Translater;
|
||||||
|
import io.gitlab.jfronny.translater.mixin.MinecraftClientAccessor;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class TransformingMap implements Map<String, String> {
|
public class TransformingMap implements Map<String, String> {
|
||||||
private final Transformer transformer;
|
private final Transformer transformer;
|
||||||
private final RenderScheduler renderScheduler = new RenderScheduler();
|
|
||||||
private Map<String, String> backer = null;
|
private Map<String, String> backer = null;
|
||||||
public boolean initializing = false;
|
public boolean initializing = false;
|
||||||
private AtomicInteger initProgress = null;
|
private String initProgress = null;
|
||||||
private int maxProgress = 0;
|
|
||||||
|
|
||||||
public TransformingMap(Transformer t) {
|
public TransformingMap(Transformer t) {
|
||||||
transformer = t;
|
transformer = t;
|
||||||
@ -26,28 +23,24 @@ public class TransformingMap implements Map<String, String> {
|
|||||||
this.backer = backer;
|
this.backer = backer;
|
||||||
Collection<String> strings = backer.values();
|
Collection<String> strings = backer.values();
|
||||||
initializing = true;
|
initializing = true;
|
||||||
generateTranslations(strings);
|
final int max = strings.size();
|
||||||
|
int i = 0;
|
||||||
|
for (String value : strings) {
|
||||||
|
initProgress = "Transforming " + i++ + "/" + max;
|
||||||
|
if (Translater.progressLogsEnabled())
|
||||||
|
Translater.LOGGER.info(initProgress);
|
||||||
|
if (Translater.progressUIEnabled() && i % 10 == 0)
|
||||||
|
((MinecraftClientAccessor) MinecraftClient.getInstance()).invokeRender(false);
|
||||||
|
initProgress = null;
|
||||||
|
transformer.transform(value);
|
||||||
|
}
|
||||||
initializing = false;
|
initializing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateTranslations(Collection<? extends String> strings) {
|
|
||||||
maxProgress = strings.size();
|
|
||||||
initProgress = new AtomicInteger();
|
|
||||||
transformer.transformMultiple(strings.parallelStream(), (str, translation) -> {
|
|
||||||
int i = initProgress.incrementAndGet();
|
|
||||||
if (i % 10 == 0 || Cfg.detailedProgress) {
|
|
||||||
if (Cfg.progressConsole) Translater.LOGGER.info(getInitProgress());
|
|
||||||
if (Cfg.progressGui && i % 10 == 0) renderScheduler.scheduleRender();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
renderScheduler.deschedule();
|
|
||||||
initProgress = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInitProgress() {
|
public String getInitProgress() {
|
||||||
if (initProgress == null || !initializing) throw new IllegalStateException("Tried to get init progress while not initializing");
|
if (initProgress == null || !initializing) throw new IllegalStateException("Tried to get init progress while not initializing");
|
||||||
return "Transforming %d/%d".formatted(initProgress.get(), maxProgress);
|
return initProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,7 +65,8 @@ public class TransformingMap implements Map<String, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(Object o) {
|
public String get(Object o) {
|
||||||
if (o instanceof String s && s.startsWith("translater.")) return backer.get(s);
|
if (o instanceof String && ((String)o).startsWith("translater."))
|
||||||
|
return backer.get(o);
|
||||||
return transformer.transform(backer.get(o));
|
return transformer.transform(backer.get(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +83,9 @@ public class TransformingMap implements Map<String, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putAll(Map<? extends String, ? extends String> map) {
|
public void putAll(Map<? extends String, ? extends String> map) {
|
||||||
generateTranslations(map.values());
|
for (String value : map.values()) {
|
||||||
|
transformer.transform(value);
|
||||||
|
}
|
||||||
backer.putAll(map);
|
backer.putAll(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,11 +101,11 @@ public class TransformingMap implements Map<String, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> values() {
|
public Collection<String> values() {
|
||||||
return backer.values(); // This does not support updates, but I don't care
|
return backer.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Entry<String, String>> entrySet() {
|
public Set<Entry<String, String>> entrySet() {
|
||||||
return backer.entrySet(); // This does not support updates, but I don't care
|
return backer.entrySet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,10 @@ import io.gitlab.jfronny.translater.Cfg;
|
|||||||
import io.gitlab.jfronny.translater.Translater;
|
import io.gitlab.jfronny.translater.Translater;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.Random;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static java.util.function.Function.identity;
|
|
||||||
|
|
||||||
public class TranslatingTransformer<T extends Language> implements Transformer {
|
public class TranslatingTransformer<T extends Language> implements Transformer {
|
||||||
public TranslatingTransformer(TranslateService<T> ts) {
|
public TranslatingTransformer(TranslateService<T> ts) {
|
||||||
@ -34,72 +31,56 @@ public class TranslatingTransformer<T extends Language> implements Transformer {
|
|||||||
@Override
|
@Override
|
||||||
public String transform(String str) {
|
public String transform(String str) {
|
||||||
try {
|
try {
|
||||||
return tryTransform(str);
|
if (str.contains("%")) {
|
||||||
} catch (Exception e) {
|
StringBuilder res = new StringBuilder();
|
||||||
Translater.LOGGER.warn("Failed to transform: \"{}\" ({} characters)! Please report this bug with the mod containing the lang file! ({})", str, str.length(), e.getLocalizedMessage());
|
boolean f = true;
|
||||||
|
for (String s : str.split("%")) {
|
||||||
|
if (!f) {
|
||||||
|
res.append("%");
|
||||||
|
if (s.length() > 0)
|
||||||
|
res.append(s.charAt(0)).append(transform(s.substring(1)).replace("%", ""));
|
||||||
|
} else
|
||||||
|
res.append(transform(s));
|
||||||
|
f = false;
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
} else if (str.contains("$")) {
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
boolean f = true;
|
||||||
|
for (String s : str.split("\\$")) {
|
||||||
|
if (!f) {
|
||||||
|
res.append("$").append(s.charAt(0)).append(transform(s.substring(1)).replace("$", ""));
|
||||||
|
} else
|
||||||
|
res.append(transform(s));
|
||||||
|
f = false;
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
} else if (str.contains("§")) {
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
boolean f = true;
|
||||||
|
for (String s : str.split("§")) {
|
||||||
|
if (!f) {
|
||||||
|
res.append("§").append(s.charAt(0)).append(transform(s.substring(1)).replace("§", ""));
|
||||||
|
} else
|
||||||
|
res.append(transform(s));
|
||||||
|
f = false;
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
} else {
|
||||||
|
return translateMultiple(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Translater.LOGGER.warn("Failed to transform: \"" + str + "\" (" + str.length() + " characters)");
|
||||||
|
Translater.LOGGER.warn("Please report this bug with the mod containing the lang file");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String tryTransform(String str) throws TranslateException {
|
|
||||||
if (str.contains("%")) {
|
|
||||||
StringBuilder res = new StringBuilder();
|
|
||||||
boolean f = true;
|
|
||||||
for (String s : str.split("%")) {
|
|
||||||
if (!f) {
|
|
||||||
res.append("%");
|
|
||||||
if (!s.isEmpty()) {
|
|
||||||
appendTransformed(res.append(s.charAt(0)), s.substring(1), x -> x.replace("%", ""));
|
|
||||||
}
|
|
||||||
} else appendTransformed(res, s, identity());
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
return res.toString();
|
|
||||||
} else if (str.contains("$")) {
|
|
||||||
StringBuilder res = new StringBuilder();
|
|
||||||
boolean f = true;
|
|
||||||
for (String s : str.split("\\$")) {
|
|
||||||
if (f) appendTransformed(res, s, identity());
|
|
||||||
else appendTransformed(res.append("$").append(s.charAt(0)), s.substring(1), x -> x.replace("$", ""));
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
return res.toString();
|
|
||||||
} else if (str.contains("§")) {
|
|
||||||
StringBuilder res = new StringBuilder();
|
|
||||||
boolean f = true;
|
|
||||||
for (String s : str.split("§")) {
|
|
||||||
if (f) appendTransformed(res, s, identity());
|
|
||||||
else appendTransformed(res.append("§").append(s.charAt(0)), s.substring(1), x -> x.replace("§", ""));
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
return res.toString();
|
|
||||||
} else {
|
|
||||||
return translateMultiple(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendTransformed(StringBuilder sb, String transformable, Function<String, String> fix) throws TranslateException {
|
|
||||||
if (transformable.isEmpty()) return;
|
|
||||||
sb.append(fix.apply(tryTransform(transformable)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformMultiple(Stream<? extends String> strings, ResultConsumer results) {
|
|
||||||
strings.flatMap(s -> {
|
|
||||||
try {
|
|
||||||
return Stream.of(new Translation(s, tryTransform(s)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
return Stream.empty();
|
|
||||||
}
|
|
||||||
}).forEach(t -> results.accept(t.from, t.to));
|
|
||||||
}
|
|
||||||
|
|
||||||
private record Translation(String from, String to) {}
|
|
||||||
|
|
||||||
private String translateMultiple(String str) throws TranslateException {
|
private String translateMultiple(String str) throws TranslateException {
|
||||||
Matcher m = SURROUNDING_SPACE_PATTERN.matcher(str);
|
Matcher m = SURROUNDING_SPACE_PATTERN.matcher(str);
|
||||||
if (!m.find()) {
|
if (!m.find()) {
|
||||||
if (Cfg.detailedProgress) Translater.LOGGER.info("Skipping translation of \"{}\"", str);
|
Translater.LOGGER.info("Skipping translation of \"" + str + "\"");
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -115,11 +96,10 @@ public class TranslatingTransformer<T extends Language> implements Transformer {
|
|||||||
}
|
}
|
||||||
currentState = ts.translate(currentState, currentLang, startLang == languageAuto ? languageEnglish : startLang); // Translate to starting language
|
currentState = ts.translate(currentState, currentLang, startLang == languageAuto ? languageEnglish : startLang); // Translate to starting language
|
||||||
currentState = m.group(1) + currentState + m.group(3); // Add back surrounding white space
|
currentState = m.group(1) + currentState + m.group(3); // Add back surrounding white space
|
||||||
if (Cfg.detailedProgress) Translater.LOGGER.info("Transformed: \"{}\" to: \"{}\"", str, currentState);
|
Translater.LOGGER.info("Transformed: \"" + str + "\" to: \"" + currentState + "\"");
|
||||||
return currentState;
|
return currentState;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String s = m.group(2);
|
Translater.LOGGER.warn("Failed to break: \"" + m.group(2) + "\" (" + m.group(2).length() + " characters). Is your API key valid?");
|
||||||
Translater.LOGGER.warn("Failed to break: \"{}\" ({} characters). Is your API key valid? ({})", s, s.length(), e.getLocalizedMessage());
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,12 @@
|
|||||||
"translater.jfconfig.breakFully.tooltip": "Whether to fully break the texts content by translating from the wrong language (enable for complete breaking)",
|
"translater.jfconfig.breakFully.tooltip": "Whether to fully break the texts content by translating from the wrong language (enable for complete breaking)",
|
||||||
"translater.jfconfig.targetLanguage": "Target Language",
|
"translater.jfconfig.targetLanguage": "Target Language",
|
||||||
"translater.jfconfig.targetLanguage.tooltip": "The language to translate to - Leave empty for auto-detection (might break text even more)",
|
"translater.jfconfig.targetLanguage.tooltip": "The language to translate to - Leave empty for auto-detection (might break text even more)",
|
||||||
"translater.jfconfig.progressGui": "Progress GUI",
|
"translater.jfconfig.renderProgress": "Progress Renderer",
|
||||||
"translater.jfconfig.progressGui.tooltip": "Significantly slows down the loading time but gives an in-game visual of the progress",
|
"translater.jfconfig.renderProgress.tooltip": "Significantly slows down the loading time but gives a visual of the progress. Values: Full, Console, None",
|
||||||
"translater.jfconfig.progressConsole": "Progress Console",
|
|
||||||
"translater.jfconfig.progressConsole.tooltip": "Slightly slows down the loading time but logs the progress",
|
|
||||||
"translater.jfconfig.detailedProgress": "Detailed Progress",
|
|
||||||
"translater.jfconfig.renderProgress.tooltip": "Significantly slows down the loading time but provides information about individual translations",
|
|
||||||
"translater.jfconfig.forceRegenerate": "Force Regenerate",
|
"translater.jfconfig.forceRegenerate": "Force Regenerate",
|
||||||
"translater.jfconfig.forceRegenerate.tooltip": "Use this if something is broken. This initiates the regeneration of the cache",
|
"translater.jfconfig.forceRegenerate.tooltip": "Use this if something is broken. This initiates the regeneration of the cache",
|
||||||
"translater.jfconfig.useDefaultCache": "Use default Cache",
|
"translater.jfconfig.enum.ProgressMode.Full": "Full",
|
||||||
"translater.jfconfig.useDefaultCache.tooltip": "Use pre-generated translations shipped with the mod if the config permits to save time"
|
"translater.jfconfig.enum.ProgressMode.Gui": "Gui",
|
||||||
|
"translater.jfconfig.enum.ProgressMode.Console": "Console",
|
||||||
|
"translater.jfconfig.enum.ProgressMode.None": "None"
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user