Skip to content

Commit

Permalink
Merge branch 'master' into 1.21.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander01998 committed Dec 29, 2024
2 parents bf455b4 + 12ee764 commit da7c696
Show file tree
Hide file tree
Showing 19 changed files with 485 additions and 7 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/check_translations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Check Translations

on:
push:
branches-ignore:
- "dependabot/**"
tags-ignore:
- "**"
paths:
- "src/main/resources/assets/wurst/translations/**.json"
- "src/main/resources/intentionally_untranslated.json"
pull_request:
paths:
- "src/main/resources/assets/wurst/translations/**.json"
- "src/main/resources/intentionally_untranslated.json"
workflow_dispatch:

jobs:
check_translations:
runs-on: ubuntu-latest
steps:

- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Run check_translations.py
run: python scripts/check_translations.py
1 change: 1 addition & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
else
echo "Failed to upload $filename" >> $GITHUB_STEP_SUMMARY
echo "Imgur upload response for $filename: $response"
fi
fi
done
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ remappedSrc/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

desktop.ini
# python
*.pyc

desktop.ini
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ jar {
from("LICENSE") {
rename {"${it}_${base.archivesName.get()}"}
}

exclude("intentionally_untranslated.json")
}

spotless {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ loader_version=0.16.9
fabric_version=0.110.0+1.21.1

# Mod Properties
mod_version = v7.46.5-MC1.21.1
mod_version = v7.46.6-MC1.21.1
maven_group = net.wurstclient
archives_base_name = Wurst-Client

Expand Down
154 changes: 154 additions & 0 deletions scripts/check_translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import util
from pathlib import Path

translations_dir = Path("src") / "main" / "resources" / "assets" / "wurst" / "translations"


def show_translation_stats(en_us: dict, translations: dict):
"""Render a table of the current translation progress for each language."""
util.add_github_summary("| Language | Translated | % |")
util.add_github_summary("| --- | --- | --- |")
util.add_github_summary(f"| en_us | {len(en_us)} | 100.00% |")
for lang, data in translations.items():
util.add_github_summary(f"| {lang} | {len(data)} | {len(data) / len(en_us) * 100:.2f}% |")
util.add_github_summary("")


def check_extra_keys(en_us: dict, translations: dict):
"""Check if any translation files contain keys that don't exist in the original."""
extra_keys_found = False
for lang, data in translations.items():
extra_keys = set(data.keys()) - set(en_us.keys())
if extra_keys:
extra_keys_found = True
util.add_github_summary(
f"⚠ {lang}.json contains translations that don't exist in en_us.json ({len(extra_keys)} found):"
)
for key in extra_keys:
util.add_github_summary(f"- {key}")
if extra_keys_found:
raise Exception("Found extra keys in one or more translation files, see summary")
util.add_github_summary("✅ No extra keys found")


def check_untranslated_strings(en_us: dict, translations: dict):
"""Check if any translation files contain untranslated strings."""
untranslated_strings_found = False
intentionally_untranslated = util.read_json_file(
Path("src") / "main" / "resources" / "intentionally_untranslated.json"
)

for lang, data in translations.items():
untranslated_strings = set()
for key, value in data.items():
if value == en_us[key]:
if lang in intentionally_untranslated and key in intentionally_untranslated[lang]:
continue
untranslated_strings.add(key)
if untranslated_strings:
untranslated_strings_found = True
util.add_github_summary(
f"⚠ {lang}.json contains strings that are identical to en_us.json ({len(untranslated_strings)} found):"
)
for key in untranslated_strings:
util.add_github_summary(f"- {key}: {en_us[key]}")
util.add_github_summary(
"\nIf this is intentional, add the affected key(s) to intentionally_untranslated.json:"
)
util.add_github_summary("```json")
util.add_github_summary(f' "{lang}": [')
for key in untranslated_strings:
util.add_github_summary(f' "{key}"')
util.add_github_summary(" ]")
util.add_github_summary("```")

if untranslated_strings_found:
raise Exception("Found untranslated strings in one or more translation files, see summary")
util.add_github_summary("✅ No accidentally untranslated strings found")


def check_order_of_strings(en_us: dict, translations: dict):
"""Check if the strings in each translation file are in the same order as in en_us.json."""
for lang, data in translations.items():
en_us_keys_present_in_translation = [key for key in en_us.keys() if key in data.keys()]
translation_keys_present_in_en_us = [key for key in data.keys() if key in en_us.keys()]
if en_us_keys_present_in_translation != translation_keys_present_in_en_us:
raise Exception(f"⚠ The order of strings in {lang}.json is different from en_us.json")
util.add_github_summary("✅ The order of strings in each translation file matches en_us.json")


def check_known_issues(en_us: dict, translations: dict):
"""Check if any translation files contain known issues."""
issues_found = False

# Typos
known_typos = {
"Anchoraura": "AnchorAura",
"Autobuild": "AutoBuild",
"Clickaura": "ClickAura",
"KillAura": "Killaura",
"LegitNuker": "Nuker",
"LegitKillaura": "KillauraLegit",
"Nofall": "NoFall",
"Triggerbot": "TriggerBot",
}
for lang, data in translations.items():
for key, value in data.items():
for typo, correct in known_typos.items():
if typo in value:
issues_found = True
util.add_github_summary(
f"⚠ In {lang}.json string {key}, the word '{correct}' is incorrectly translated as '{typo}':"
)
util.add_github_summary("```json")
util.add_github_summary(f' "{key}": "{value}"')
util.add_github_summary("```")

# Difficult strings
for lang, data in translations.items():
# Boatfly
boatfly_key = "description.wurst.hack.boatfly"
if boatfly_key in data and "shift" in data[boatfly_key].lower():
issues_found = True
util.add_github_summary(
f"⚠ In {lang}.json, the translation for {boatfly_key} incorrectly suggests using the shift (sneak) key instead of ctrl (sprint) to descend"
)
# Radar
radar_key = "description.wurst.hack.radar"
if radar_key in data and (
"§cred§r" in data[radar_key]
# Not checking orange because it appears in the French translation
or "§agreen§r" in data[radar_key]
or "§7gray§r" in data[radar_key]
):
issues_found = True
util.add_github_summary(
f"⚠ In {lang}.json, the translation for {radar_key} contains untranslated colors:"
)
util.add_github_summary("```json")
util.add_github_summary(f' "{radar_key}": "{data[radar_key]}"')
util.add_github_summary("```")

if issues_found:
raise Exception("Found known issues in one or more translation files, see summary")
util.add_github_summary("✅ No known issues found in any translation files")


def main():
en_us = util.read_json_file(translations_dir / "en_us.json")
translations = {}
for path in sorted(translations_dir.rglob("*.json"), key=lambda x: x.name):
if path.is_file() and path.name != "en_us.json":
lang = path.name.removesuffix(".json")
data = util.read_json_file(path)
translations[lang] = data

show_translation_stats(en_us, translations)
check_extra_keys(en_us, translations)
check_untranslated_strings(en_us, translations)
check_order_of_strings(en_us, translations)
check_known_issues(en_us, translations)


if __name__ == "__main__":
main()
17 changes: 17 additions & 0 deletions scripts/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import json
import os
from pathlib import Path


def read_json_file(path: Path) -> dict:
"""Read a JSON data file."""
return json.loads(path.read_text(encoding="utf-8"))


def add_github_summary(summary: str):
"""Add a line to the GitHub Actions summary for the current step."""
if "GITHUB_STEP_SUMMARY" not in os.environ:
print(summary)
return
with open(os.environ["GITHUB_STEP_SUMMARY"], "a") as summary_file:
print(summary, file=summary_file)
2 changes: 1 addition & 1 deletion src/main/java/net/wurstclient/WurstClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public enum WurstClient
public static MinecraftClient MC;
public static IMinecraftClient IMC;

public static final String VERSION = "7.46.5";
public static final String VERSION = "7.46.6";
public static final String MC_VERSION = "1.21.1";

private WurstAnalytics analytics;
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/net/wurstclient/test/AutoMineHackTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.test;

import static net.wurstclient.test.WurstClientTestHelper.*;

import net.minecraft.block.Blocks;

public enum AutoMineHackTest
{
;

public static void testAutoMineHack()
{
System.out.println("Testing AutoMine hack");
runChatCommand("gamemode survival");

// Break a dirt block in survival mode
runChatCommand("setblock ~ ~1 ~2 minecraft:dirt");
waitForBlock(0, 1, 2, Blocks.DIRT);
runWurstCommand("t AutoMine on");
waitForBlock(0, 1, 2, Blocks.AIR);
takeScreenshot("automine_survival");

// Clean up
runWurstCommand("t AutoMine off");
runChatCommand("gamemode creative");
runChatCommand("kill @e[type=item]");
runChatCommand("clear");
clearChat();
}
}
2 changes: 2 additions & 0 deletions src/main/java/net/wurstclient/test/CopyItemCmdTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public static void testCopyItemCmd()
{
System.out.println("Testing .copyitem command");
setPerspective(Perspective.THIRD_PERSON_FRONT);
runChatCommand("clear");
clearChat();

// Put on a golden helmet
// CURSED: The /item replace command doesn't work properly in 1.21.1
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/net/wurstclient/test/FreecamHackTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.test;

import static net.wurstclient.test.WurstClientTestHelper.*;

import java.time.Duration;

import net.wurstclient.mixinterface.IKeyBinding;

public enum FreecamHackTest
{
;

public static void testFreecamHack()
{
System.out.println("Testing Freecam hack");

// Enable Freecam with default settings
runWurstCommand("setcheckbox Freecam tracer off");
runWurstCommand("t Freecam on");
takeScreenshot("freecam_default", Duration.ofMillis(100));
clearChat();

// Press shift to fly down a bit
submitAndWait(
mc -> IKeyBinding.get(mc.options.sneakKey).simulatePress(true));
waitForWorldTicks(5);
submitAndWait(
mc -> IKeyBinding.get(mc.options.sneakKey).simulatePress(false));
takeScreenshot("freecam_down", Duration.ofMillis(300));
clearChat();

// Tracer
runWurstCommand("setcheckbox Freecam tracer on");
takeScreenshot("freecam_tracer", Duration.ofMillis(100));
clearChat();

// Clean up
runWurstCommand("setcheckbox Freecam tracer off");
runWurstCommand("t Freecam off");
waitForWorldTicks(5);
clearChat();
}
}
1 change: 1 addition & 0 deletions src/main/java/net/wurstclient/test/NoFallHackTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private static void assertPlayerHealth(Predicate<Float> healthCheck)
float health = submitAndGet(mc -> mc.player.getHealth());
if(!healthCheck.test(health))
throw new RuntimeException("Player's health is wrong: " + health);

System.out.println("Player's health is correct: " + health);
}
}
42 changes: 42 additions & 0 deletions src/main/java/net/wurstclient/test/PistonTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.test;

import static net.wurstclient.test.WurstClientTestHelper.*;

import net.minecraft.block.Blocks;

public enum PistonTest
{
;

public static void testPistonDoesntCrash()
{
System.out.println(
"Testing that a piston can extend and retract without crashing the game");

// Place a redstone block and piston
runChatCommand("setblock ~ ~1 ~2 minecraft:piston[facing=up]");
waitForBlock(0, 1, 2, Blocks.PISTON);
runChatCommand("setblock ~ ~ ~2 minecraft:redstone_block");
waitForBlock(0, 0, 2, Blocks.REDSTONE_BLOCK);
takeScreenshot("piston_extending");
waitForWorldTicks(3);

// Destroy the redstone block
runChatCommand("setblock ~ ~ ~2 minecraft:air");
waitForBlock(0, 0, 2, Blocks.AIR);
takeScreenshot("piston_retracting");
waitForWorldTicks(3);

// Clean up
runChatCommand("setblock ~ ~1 ~2 minecraft:air");
waitForBlock(0, 1, 2, Blocks.AIR);
clearChat();
}
}
Loading

0 comments on commit da7c696

Please sign in to comment.