Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large translations update: Part 1 #965

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,20 @@ loom {
accessWidenerPath = file("src/main/resources/wurst.accesswidener")
}

task localesGenerate(dependsOn: compileJava) {
description = "Generate JSON translation files (locales)"
doLast {
javaexec {
classpath = sourceSets.main.runtimeClasspath
mainClass = "net.wurstclient.LocalesGenerator"
jvmArgs = ["-Dfile.encoding=UTF-8"]
}
}
}

processResources {
dependsOn("localesGenerate")

inputs.property "version", project.version

filesMatching("fabric.mod.json") {
Expand Down
151 changes: 151 additions & 0 deletions src/main/java/net/wurstclient/LocalesGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package net.wurstclient;

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

import com.google.gson.*;

import net.wurstclient.util.json.JsonException;
import net.wurstclient.util.json.JsonUtils;

public final class LocalesGenerator
{
public static final class Settings
{
public static final String DEFAULT_UNTRANSLATED_VALUE =
"WURST_UNTRANSLATED_STRING";
public static final String DEFAULT_LC = "en_us";
public static final List<String> SUPPORTED_LCS =
Arrays.asList("cs_cz", "de_de", "fr_fr", "it_it", "ja_jp", "ko_kr",
"pl_pl", "ro_ro", "ru_ru", "uk_ua", "zh_cn", "zh_hk", "zh_tw");
}

private static final Path DEFAULT_LC_PATH =
Paths.get(System.getProperty("user.dir"), "src", "main", "resources",
"assets", "wurst", "lang");
private static final File DEFAULT_LC_FILE = new File(DEFAULT_LC_PATH
.resolve(Settings.DEFAULT_LC + ".json").toAbsolutePath().toString());

private static void writeLinesToFile(File f, List<String> l)
throws IOException
{
try(FileWriter fw = new FileWriter(f, false))
{
fw.write(String.join("\n", l));
}
}

public static void main(String[] args) throws IOException, JsonException
{
if(!DEFAULT_LC_FILE.isFile())
throw new FileNotFoundException(DEFAULT_LC_FILE.getAbsolutePath());

ArrayList<Integer> blankLines = new ArrayList<>();
Scanner sc = new Scanner(DEFAULT_LC_FILE);
for(int l = 0; sc.hasNextLine(); l++)
if(sc.nextLine().isBlank())
blankLines.add(l);

JsonObject defaultJson =
JsonUtils.parseFile(DEFAULT_LC_FILE.toPath()).getAsJsonObject();

for(String lc : Settings.SUPPORTED_LCS)
{
File f = new File(DEFAULT_LC_PATH.resolve(lc + ".json")
.toAbsolutePath().toString());
JsonObject defaultJsonCopy = defaultJson.deepCopy();

if(!f.isFile())
{
defaultJsonCopy.keySet().forEach(k -> defaultJsonCopy
.addProperty(k, Settings.DEFAULT_UNTRANSLATED_VALUE));

String prettyJson = new GsonBuilder().setPrettyPrinting()
.disableHtmlEscaping().create().toJson(defaultJsonCopy);
List<String> lines =
new ArrayList<>(prettyJson.lines().toList());
blankLines.forEach(blank -> lines.add(blank, ""));

writeLinesToFile(f, lines);

System.out.printf(
"%s.json: new locale file was created with default values set to %s%n",
lc, Settings.DEFAULT_UNTRANSLATED_VALUE);
}else
{
JsonObject parsedJson =
JsonUtils.parseFile(f.toPath()).getAsJsonObject();
JsonObject filledJson = new JsonObject();

ArrayList<String> defaultKeySet =
new ArrayList<>(defaultJsonCopy.keySet().stream().toList());
ArrayList<String> keySet =
new ArrayList<>(parsedJson.keySet().stream().toList());

ArrayList<String> missingKeys =
defaultKeySet.stream().filter(k -> !keySet.contains(k))
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<String> unknownKeys =
keySet.stream().filter(k -> !defaultKeySet.contains(k))
.collect(Collectors.toCollection(ArrayList::new));

boolean missingKeysStatus = false, unknownKeysStatus = false;

if(!missingKeys.isEmpty())
{
missingKeysStatus = true;
missingKeys.forEach(k -> parsedJson.addProperty(k,
Settings.DEFAULT_UNTRANSLATED_VALUE));
}

defaultKeySet.forEach(k -> filledJson.addProperty(k,
parsedJson.asMap().get(k).getAsString()));

if(!unknownKeys.isEmpty())
{
unknownKeysStatus = true;
unknownKeys.forEach(k -> filledJson.addProperty(k,
parsedJson.asMap().get(k).getAsString()));
}

String prettyJson = new GsonBuilder().setPrettyPrinting()
.disableHtmlEscaping().create().toJson(filledJson);
List<String> lines =
new ArrayList<>(prettyJson.lines().toList());

ArrayList<Integer> finalBlankLines =
new ArrayList<>(blankLines);

if(!unknownKeys.isEmpty())
{
// "-1" means the last line before line with closing curved
// bracket, i.e. latest JSON key-value pair
int unknownValuesSeparatorIndex = lines.size()
+ blankLines.size() - unknownKeys.size() - 1;
for(int i = 0; i < 3; i++)
finalBlankLines.add(unknownValuesSeparatorIndex + i);
}

finalBlankLines.forEach(lineIndex -> lines.add(lineIndex, ""));

writeLinesToFile(f, lines);

System.out.printf(
"%s.json: missing keys: %b, unknown keys: %b%n", lc,
missingKeysStatus, unknownKeysStatus);
if(missingKeysStatus)
System.out.printf(
"\tmissing keys (were added to locale file with default values set to %s): %n\t\t%s%n",
Settings.DEFAULT_UNTRANSLATED_VALUE,
String.join(String.format("%n\t\t"), missingKeys));
if(unknownKeysStatus)
System.out.printf(
"\tunknown keys (were added to the end of locale file): %n\t\t%s%n",
String.join(String.format("%n\t\t"), unknownKeys));
}
}
}
}
28 changes: 24 additions & 4 deletions src/main/java/net/wurstclient/WurstClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void initialize()
Path encFolder = Encryption.chooseEncryptionFolder();
altManager = new AltManager(altsFile, encFolder);

zoomKey = new KeyBinding("key.wurst.zoom", InputUtil.Type.KEYSYM,
zoomKey = new KeyBinding("wurst.key.zoom", InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_V, KeyBinding.MISC_CATEGORY);
KeyBindingHelper.registerKeyBinding(zoomKey);

Expand Down Expand Up @@ -185,20 +185,40 @@ public String translate(String key, Object... args)
try
{
return String.format(string, args);

}catch(IllegalFormatException e)
{
return key;
}
}

// This extra check is necessary because I18n.translate() doesn't
// This extra check is necessary because `I18n.translate()` doesn't
// always return the key when the translation is missing. If the key
// contains a '%', it will return "Format Error: key" instead.
// But after implementing `LocalesGenerator`, which will be run every
// build for filling missing values with `DEFAULT_UNTRANSLATED_VALUE` in
// all locales depending on `DEFAULT_LOCALE` file, this will probably
// never be `true`.
if(!I18n.hasTranslation(key))
return key;

return I18n.translate(key, args);
String translated = I18n.translate(key, args);

if(!translated
.equals(LocalesGenerator.Settings.DEFAULT_UNTRANSLATED_VALUE))
return translated;

if(!otfs.translationsOtf.getFallbackToEnglish().isChecked())
return key;

String string = ILanguageManager.getEnglish().get(key);

try
{
return String.format(string, args);
}catch(IllegalFormatException e)
{
return key;
}
}

public WurstAnalytics getAnalytics()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ public void init()
if(folderException != null && shouldAsk)
{
Text title = Text.literal(
wurst.translate("gui.wurst.altmanager.folder_error.title"));
wurst.translate("wurst.altmanager.gui.folder_error.title"));
Text message = Text.literal(wurst.translate(
"gui.wurst.altmanager.folder_error.message", folderException));
"wurst.altmanager.gui.folder_error.message", folderException));
Text buttonText = Text.translatable("gui.done");

// This just sets shouldAsk to false and closes the message.
Expand All @@ -107,9 +107,9 @@ public void init()
}else if(altManager.getList().isEmpty() && shouldAsk)
{
Text title = Text
.literal(wurst.translate("gui.wurst.altmanager.empty.title"));
.literal(wurst.translate("wurst.altmanager.gui.empty.title"));
Text message = Text
.literal(wurst.translate("gui.wurst.altmanager.empty.message"));
.literal(wurst.translate("wurst.altmanager.gui.empty.message"));
BooleanConsumer callback = this::confirmGenerate;

ConfirmScreen screen = new ConfirmScreen(callback, title, message);
Expand Down Expand Up @@ -552,7 +552,7 @@ private void addTooltip(ArrayList<Text> tooltip, String trKey)
{
// translate
String translated = WurstClient.INSTANCE
.translate("description.wurst.altmanager." + trKey);
.translate("wurst.altmanager." + trKey + ".description");

// line-wrap
StringJoiner joiner = new StringJoiner("\n");
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/wurstclient/hack/Hack.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public abstract class Hack extends Feature
public Hack(String name)
{
this.name = Objects.requireNonNull(name);
description = "description.wurst.hack." + name.toLowerCase();
description = "wurst.hack." + name.toLowerCase() + ".description";
addPossibleKeybind(name, "Toggle " + name);
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/wurstclient/hacks/ArrowDmgHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
public final class ArrowDmgHack extends Hack implements StopUsingItemListener
{
private final SliderSetting packets = new SliderSetting("Packets",
"description.wurst.setting.arrowdmg.packets", 200, 2, 7000, 20,
"wurst.hack.arrowdmg.setting.packets.description", 200, 2, 7000, 20,
ValueDisplay.INTEGER);

private final CheckboxSetting yeetTridents =
new CheckboxSetting("Trident yeet mode",
"description.wurst.setting.arrowdmg.trident_yeet_mode", false);
"wurst.hack.arrowdmg.setting.trident_yeet_mode.description", false);

public ArrowDmgHack()
{
Expand Down
32 changes: 17 additions & 15 deletions src/main/java/net/wurstclient/hacks/AutoEatHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,44 +47,46 @@
public final class AutoEatHack extends Hack implements UpdateListener
{
private final SliderSetting targetHunger = new SliderSetting(
"Target hunger", "description.wurst.setting.autoeat.target_hunger", 10,
0, 10, 0.5, ValueDisplay.DECIMAL);
"Target hunger", "wurst.hack.autoeat.setting.target_hunger.description",
10, 0, 10, 0.5, ValueDisplay.DECIMAL);

private final SliderSetting minHunger = new SliderSetting("Min hunger",
"description.wurst.setting.autoeat.min_hunger", 6.5, 0, 10, 0.5,
"wurst.hack.autoeat.setting.min_hunger.description", 6.5, 0, 10, 0.5,
ValueDisplay.DECIMAL);

private final SliderSetting injuredHunger = new SliderSetting(
"Injured hunger", "description.wurst.setting.autoeat.injured_hunger",
10, 0, 10, 0.5, ValueDisplay.DECIMAL);
private final SliderSetting injuredHunger =
new SliderSetting("Injured hunger",
"wurst.hack.autoeat.setting.injured_hunger.description", 10, 0, 10,
0.5, ValueDisplay.DECIMAL);

private final SliderSetting injuryThreshold =
new SliderSetting("Injury threshold",
"description.wurst.setting.autoeat.injury_threshold", 1.5, 0.5, 10,
0.5, ValueDisplay.DECIMAL);
"wurst.hack.autoeat.setting.injury_threshold.description", 1.5, 0.5,
10, 0.5, ValueDisplay.DECIMAL);

private final EnumSetting<TakeItemsFrom> takeItemsFrom = new EnumSetting<>(
"Take items from", "description.wurst.setting.autoeat.take_items_from",
TakeItemsFrom.values(), TakeItemsFrom.HOTBAR);
private final EnumSetting<TakeItemsFrom> takeItemsFrom =
new EnumSetting<>("Take items from",
"wurst.hack.autoeat.setting.take_items_from.description",
TakeItemsFrom.values(), TakeItemsFrom.HOTBAR);

private final CheckboxSetting allowOffhand =
new CheckboxSetting("Allow offhand", true);

private final CheckboxSetting eatWhileWalking =
new CheckboxSetting("Eat while walking",
"description.wurst.setting.autoeat.eat_while_walking", false);
"wurst.hack.autoeat.setting.eat_while_walking.description", false);

private final CheckboxSetting allowHunger =
new CheckboxSetting("Allow hunger effect",
"description.wurst.setting.autoeat.allow_hunger", true);
"wurst.hack.autoeat.setting.allow_hunger.description", true);

private final CheckboxSetting allowPoison =
new CheckboxSetting("Allow poison effect",
"description.wurst.setting.autoeat.allow_poison", false);
"wurst.hack.autoeat.setting.allow_poison.description", false);

private final CheckboxSetting allowChorus =
new CheckboxSetting("Allow chorus fruit",
"description.wurst.setting.autoeat.allow_chorus", false);
"wurst.hack.autoeat.setting.allow_chorus.description", false);

private int oldSlot = -1;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/wurstclient/hacks/InvWalkHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public final class InvWalkHack extends Hack implements UpdateListener
{
private final CheckboxSetting allowClickGUI =
new CheckboxSetting("Allow ClickGUI",
"description.wurst.setting.invwalk.allow_clickgui", true);
"wurst.hack.invwalk.setting.allow_clickgui.description", true);

private final CheckboxSetting allowOther =
new CheckboxSetting("Allow other screens",
"description.wurst.setting.invwalk.allow_other", true);
"wurst.hack.invwalk.setting.allow_other.description", true);

private final CheckboxSetting allowSneak =
new CheckboxSetting("Allow sneak key", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ public void onOnServerMetadata(ServerMetadataS2CPacket packet,

// Add an honest warning toast on unsafe servers
MutableText title = Text.literal(ChatUtils.WURST_PREFIX
+ wurst.translate("toast.wurst.nochatreports.unsafe_server.title"));
+ wurst.translate("wurst.nochatreports.toast.unsafe_server.title"));
MutableText message = Text.literal(
wurst.translate("toast.wurst.nochatreports.unsafe_server.message"));
wurst.translate("wurst.nochatreports.toast.unsafe_server.message"));

SystemToast systemToast = SystemToast.create(client,
SystemToast.Type.UNSECURE_SERVER_WARNING, title, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private int dontAddZoomEntry(ControlsListWidget instance,
.getContent() instanceof TranslatableTextContent trContent))
return original.call(instance, entry);

if(!"key.wurst.zoom".equals(trContent.getKey()))
if(!"wurst.key.zoom".equals(trContent.getKey()))
return original.call(instance, entry);

return 0;
Expand Down
Loading
Loading