diff --git a/build.gradle b/build.gradle index 765e25b85..8cc53b003 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.quiltmc.loom" version "1.+" + id "babric-loom" version "1.1.+" id 'java' } @@ -8,14 +8,14 @@ archivesBaseName = project.mod_name version = project.mod_version loom { - clientOnlyMinecraftJar() - //serverOnlyMinecraftJar() + gluedMinecraftJar() noIntermediateMappings() - customMinecraftManifest.set("https://github.com/MartinSVK12/bta-manifest-repo/releases/download/v${project.bta_version}/${project.bta_version}.json") + customMinecraftManifest.set("https://github.com/Turnip-Labs/bta-manifest-repo/releases/download/v${project.bta_version}/${project.bta_version}.json") } repositories { mavenCentral() + maven { url = "https://jitpack.io" } maven { name = 'Babric' url = 'https://maven.glass-launcher.net/babric' @@ -63,17 +63,28 @@ dependencies { mappings loom.layered {} modRuntimeOnly "objects:client:43db9b498cb67058d2e12d394e6507722e71bb45" // https://piston-data.mojang.com/v1/objects/43db9b498cb67058d2e12d394e6507722e71bb45/client.jar - modImplementation("quilt-loader:quilt-loader:${project.loader_version}") + modImplementation "fabric-loader:fabric-loader:${project.loader_version}" + + // Helper library for translations + modImplementation "com.github.Turnip-Labs:bta-halplibe:${project.halplibe_version}" implementation include("org.apache.commons:commons-lang3:3.12.0") implementation include("com.google.guava:guava:28.0-jre") - implementation include(group: 'com.google.code.gson', name: 'gson', version: '2.8.6') + implementation include("com.google.code.gson:gson:2.8.6") modImplementation "org.slf4j:slf4j-api:1.8.0-beta4" modImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:2.16.0" } +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 diff --git a/gradle.properties b/gradle.properties index 21e078ce7..e3c675742 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,11 @@ org.gradle.jvmargs=-Xmx1G # Also makes builds more reliable and less likely to randomly fail. org.gradle.daemon=false -mod_version=2.0.0 +mod_version=2.0.1 mod_group=io.github.turniplabs mod_name=modmenu-bta # yarn_mappings=df0e26c -bta_version=1.7.7.0 -loader_version=0.20.0-beta.3-bta +bta_version=1.7.7.0_02 +loader_version=0.14.19-babric.1-bta +halplibe_version=2.3.0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e148c40ba..1eb293b26 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip diff --git a/src/main/java/io/github/prospector/modmenu/ModMenu.java b/src/main/java/io/github/prospector/modmenu/ModMenu.java index 8faa269d7..b5cb66460 100644 --- a/src/main/java/io/github/prospector/modmenu/ModMenu.java +++ b/src/main/java/io/github/prospector/modmenu/ModMenu.java @@ -10,13 +10,17 @@ import io.github.prospector.modmenu.config.ModMenuConfigManager; import io.github.prospector.modmenu.util.HardcodedUtil; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.metadata.CustomValue; +import net.fabricmc.loader.api.metadata.ModEnvironment; import net.fabricmc.loader.api.metadata.ModMetadata; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.options.GuiOptionsPageGeneral; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.text.NumberFormat; import java.util.*; @@ -24,6 +28,7 @@ public class ModMenu implements ClientModInitializer { public static final String MOD_ID = "modmenu"; + public static final Logger LOGGER = LogManager.getLogger("Mod Menu"); public static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create(); private static final Map LEGACY_CONFIG_SCREEN_TASKS = new HashMap<>(); @@ -34,7 +39,6 @@ public class ModMenu implements ClientModInitializer { public static final Map>> CUSTOM_BADGE_MODS = new HashMap<>(); public static final LinkedListMultimap PARENT_MAP = LinkedListMultimap.create(); private static ImmutableMap> configScreenFactories = ImmutableMap.of(); - private static int libraryCount = 0; public static boolean hasConfigScreenFactory(String modid) { return configScreenFactories.containsKey(modid); @@ -64,20 +68,22 @@ public static void addLibraryMod(String modid) { LIBRARY_MODS.add(modid); } + @SuppressWarnings("RedundantCollectionOperation") @Override public void onInitializeClient() { ModMenuConfigManager.initializeConfig(); ImmutableMap.Builder> factories = ImmutableMap.builder(); - FabricLoader.getInstance().getEntrypoints("modmenu", ModMenuApi.class).forEach(api -> { + FabricLoader.getInstance().getEntrypointContainers("modmenu", ModMenuApi.class).forEach(entrypoint -> { + ModMenuApi api = entrypoint.getEntrypoint(); + ModContainer mod = entrypoint.getProvider(); try { api.getClass().getDeclaredMethod("getConfigScreenFactory"); // Make sure the method is implemented - factories.put(api.getModId(), api.getConfigScreenFactory()); - } catch (NoSuchMethodException ignored) { - } + factories.put(mod.getMetadata().getId(), api.getConfigScreenFactory()); + } catch (NoSuchMethodException ignored) {} api.attachCustomBadges((name, outlineColor, fillColor) -> { Map> map = new HashMap<>(); map.put(name, new AbstractMap.SimpleEntry<>(outlineColor, fillColor)); - CUSTOM_BADGE_MODS.put(api.getModId(), map); + CUSTOM_BADGE_MODS.put(mod.getMetadata().getId(), map); }); }); factories.put("minecraft", (screenBase -> new GuiOptionsPageGeneral(screenBase, ((Minecraft) FabricLoader.getInstance().getGameInstance()).gameSettings))); @@ -87,21 +93,34 @@ public void onInitializeClient() { for (ModContainer mod : mods) { ModMetadata metadata = mod.getMetadata(); String id = metadata.getId(); + // API badges if (metadata.containsCustomValue("modmenu:api") && metadata.getCustomValue("modmenu:api").getAsBoolean()) { addLibraryMod(id); } - if (metadata.containsCustomValue("modmenu:clientsideOnly") && metadata.getCustomValue("modmenu:clientsideOnly").getAsBoolean()) { + + // Client side badges + if (metadata.getEnvironment().equals(ModEnvironment.CLIENT)) { CLIENTSIDE_MODS.add(id); } + if (metadata.containsCustomValue("modmenu:clientsideOnly") && metadata.getCustomValue("modmenu:clientsideOnly").getAsBoolean()) { + LOGGER.warn("Found mod with id \"{}\" using deprecated value \"modmenu:clientsideOnly\"!", metadata.getId()); + if (!(CLIENTSIDE_MODS.contains(id))) CLIENTSIDE_MODS.add(id); + } + + // Deprecated badges if (metadata.containsCustomValue("modmenu:deprecated") && metadata.getCustomValue("modmenu:deprecated").getAsBoolean()) { DEPRECATED_MODS.add(id); } + + // Patchwork (unused) if (metadata.containsCustomValue("patchwork:source") && metadata.getCustomValue("patchwork:source").getAsObject() != null) { CustomValue.CvObject object = metadata.getCustomValue("patchwork:source").getAsObject(); if ("forge".equals(object.get("loader").getAsString())) { PATCHWORK_FORGE_MODS.add(id); } } + + // Parent mods if (metadata.containsCustomValue("modmenu:parent")) { String parentId = metadata.getCustomValue("modmenu:parent").getAsString(); if (parentId != null) { @@ -112,7 +131,6 @@ public void onInitializeClient() { HardcodedUtil.hardcodeModuleMetadata(mod, metadata, id); } } - libraryCount = LIBRARY_MODS.size(); } public static String getFormattedModCount() { diff --git a/src/main/java/io/github/prospector/modmenu/api/ModMenuApi.java b/src/main/java/io/github/prospector/modmenu/api/ModMenuApi.java index 2025f1fe0..6d27bb434 100644 --- a/src/main/java/io/github/prospector/modmenu/api/ModMenuApi.java +++ b/src/main/java/io/github/prospector/modmenu/api/ModMenuApi.java @@ -25,9 +25,12 @@ static void addConfigOverride(String modid, Runnable action) { /** * Used to determine the owner of this API implementation. - * Will be deprecated and removed once Fabric has support - * for providing ownership information about entry points. + * + * @deprecated This method is deprecated as Fabric Loader + * itself provides provider info for entrypoints. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.1.0") String getModId(); /** diff --git a/src/main/java/io/github/prospector/modmenu/config/ModMenuConfig.java b/src/main/java/io/github/prospector/modmenu/config/ModMenuConfig.java index cd0841e8f..128a3df5d 100644 --- a/src/main/java/io/github/prospector/modmenu/config/ModMenuConfig.java +++ b/src/main/java/io/github/prospector/modmenu/config/ModMenuConfig.java @@ -3,6 +3,7 @@ import io.github.prospector.modmenu.util.HardcodedUtil; import net.fabricmc.loader.api.ModContainer; +import net.minecraft.core.lang.I18n; import java.util.Comparator; @@ -29,15 +30,15 @@ public Sorting getSorting() { } public enum Sorting { - ASCENDING(Comparator.comparing(modContainer -> HardcodedUtil.formatFabricModuleName(modContainer.getMetadata().getName())), "A-Z"), - DECENDING(ASCENDING.getComparator().reversed(), "Z-A"); + ASCENDING(Comparator.comparing(modContainer -> HardcodedUtil.formatFabricModuleName(modContainer.getMetadata().getName())), "modmenu.sorting.ascending"), + DECENDING(ASCENDING.getComparator().reversed(), "modmenu.sorting.decending"); final Comparator comparator; - final String name; + final String key; - Sorting(Comparator comparator, String name) { + Sorting(Comparator comparator, String key) { this.comparator = comparator; - this.name = name; + this.key = key; } public Comparator getComparator() { @@ -45,7 +46,7 @@ public Comparator getComparator() { } public String getName() { - return name; + return I18n.getInstance().translateKey(key); } } } diff --git a/src/main/java/io/github/prospector/modmenu/gui/DescriptionListWidget.java b/src/main/java/io/github/prospector/modmenu/gui/DescriptionListWidget.java index 486a2720b..b42ed10d9 100644 --- a/src/main/java/io/github/prospector/modmenu/gui/DescriptionListWidget.java +++ b/src/main/java/io/github/prospector/modmenu/gui/DescriptionListWidget.java @@ -6,6 +6,7 @@ import net.fabricmc.loader.api.metadata.Person; import net.minecraft.client.Minecraft; import net.minecraft.client.render.FontRenderer; +import net.minecraft.core.lang.I18n; import java.util.Collection; @@ -37,6 +38,7 @@ protected int getScrollbarPosition() { @Override public void render(int mouseX, int mouseY, float delta) { + I18n i18n = I18n.getInstance(); ModListEntry selectedEntry = parent.getSelectedEntry(); if (selectedEntry != lastSelected) { lastSelected = selectedEntry; @@ -57,21 +59,21 @@ public void render(int mouseX, int mouseY, float delta) { } if (!authors.isEmpty()) { if (!children().isEmpty()) children().add(new DescriptionEntry("")); - children().add(new DescriptionEntry("Authors:")); + children().add(new DescriptionEntry(i18n.translateKey("modmenu.authors"))); for (Person person : authors) { children().add(new DescriptionEntry(" " + person.getName())); } } if (!contributors.isEmpty()) { if (!children().isEmpty()) children().add(new DescriptionEntry("")); - children().add(new DescriptionEntry("Contributors:")); + children().add(new DescriptionEntry(i18n.translateKey("modmenu.contributors"))); for (Person person : contributors) { children().add(new DescriptionEntry(" " + person.getName())); } } if (!licenses.isEmpty()) { if (!children().isEmpty()) children().add(new DescriptionEntry("")); - children().add(new DescriptionEntry("Licenses:")); + children().add(new DescriptionEntry(i18n.translateKey("modmenu.licenses"))); for (String license : licenses) { children().add(new DescriptionEntry(" " + license)); } diff --git a/src/main/java/io/github/prospector/modmenu/gui/ModListScreen.java b/src/main/java/io/github/prospector/modmenu/gui/ModListScreen.java index 9fb29edff..4e20e0639 100644 --- a/src/main/java/io/github/prospector/modmenu/gui/ModListScreen.java +++ b/src/main/java/io/github/prospector/modmenu/gui/ModListScreen.java @@ -1,6 +1,5 @@ package io.github.prospector.modmenu.gui; - import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.Lists; @@ -18,6 +17,7 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.render.FontRenderer; import net.minecraft.client.render.Tessellator; +import net.minecraft.core.lang.I18n; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.Sys; @@ -66,7 +66,7 @@ public class ModListScreen extends GuiScreen { public ModListScreen(GuiScreen previousGui) { this.parent = previousGui; - this.textTitle = "Mods"; + this.textTitle = I18n.getInstance().translateKey("modmenu.title"); } public void handleInput() { @@ -93,6 +93,7 @@ public void updateScreen() { @Override public void initGui() { + I18n i18n = I18n.getInstance(); Keyboard.enableRepeatEvents(true); FontRenderer font = fontRenderer; paneY = 48; @@ -102,7 +103,7 @@ public void initGui() { int searchBoxWidth = paneWidth - 32 - 22; searchBoxX = paneWidth / 2 - searchBoxWidth / 2 - 22 / 2; String oldText = this.searchBox == null ? "" : this.searchBox.getText(); - this.searchBox = new TextFieldWidget(this.fontRenderer, searchBoxX, 22, searchBoxWidth, 20); // field_6451_g + this.searchBox = new TextFieldWidget(this.fontRenderer, searchBoxX, 22, searchBoxWidth, 20, i18n.translateKey("modmenu.search")); // field_6451_g this.searchBox.setText(oldText); this.modList = new ModListWidget(this.mc, paneWidth, this.height, paneY + 19, this.height - 36, 36, this.searchBox.getText(), this.modList, this); this.modList.setLeftPos(0); @@ -125,7 +126,7 @@ public void render(Minecraft mc, int mouseX, int mouseY) { }; int urlButtonWidths = paneWidth / 2 - 2; int cappedButtonWidth = Math.min(urlButtonWidths, 200); - GuiButton websiteButton = new GuiButton(WEBSITE_BUTTON_ID, rightPaneX + (urlButtonWidths / 2) - (cappedButtonWidth / 2), paneY + 36, Math.min(urlButtonWidths, 200), 20, "Website") { + GuiButton websiteButton = new GuiButton(WEBSITE_BUTTON_ID, rightPaneX + (urlButtonWidths / 2) - (cappedButtonWidth / 2), paneY + 36, Math.min(urlButtonWidths, 200), 20, i18n.translateKey("modmenu.website")) { @Override public void drawButton(Minecraft mc, int var1, int var2) { visible = selected != null; // visible = selected != null @@ -133,7 +134,7 @@ public void drawButton(Minecraft mc, int var1, int var2) { super.drawButton(mc, var1, var2); } }; - GuiButton issuesButton = new GuiButton(ISSUES_BUTTON_ID, rightPaneX + urlButtonWidths + 4 + (urlButtonWidths / 2) - (cappedButtonWidth / 2), paneY + 36, Math.min(urlButtonWidths, 200), 20, "Issues") { + GuiButton issuesButton = new GuiButton(ISSUES_BUTTON_ID, rightPaneX + urlButtonWidths + 4 + (urlButtonWidths / 2) - (cappedButtonWidth / 2), paneY + 36, Math.min(urlButtonWidths, 200), 20, i18n.translateKey("modmenu.issues")) { @Override public void drawButton(Minecraft mc, int var1, int var2) { visible = selected != null; // visible = selected != null @@ -146,17 +147,17 @@ public void drawButton(Minecraft mc, int var1, int var2) { public void render(Minecraft mc, int int_1, int int_2) { super.render(mc, int_1, int_2); if (isHovered(int_1, int_2)) { - setTooltip("Toggle Filter Options"); + setTooltip(i18n.translateKey("modmenu.toggleFilterOptions")); } } }); - String showLibrariesText = ModMenuConfigManager.getConfig().showLibraries() ? "Libraries: Shown" : "Libraries: Hidden"; - String sortingText = "Sort: " + ModMenuConfigManager.getConfig().getSorting().getName(); + String showLibrariesText = i18n.translateKeyAndFormat("modmenu.showLibraries", i18n.translateKey("modmenu.showLibraries." + ModMenuConfigManager.getConfig().showLibraries())); + String sortingText = i18n.translateKeyAndFormat("modmenu.sorting", ModMenuConfigManager.getConfig().getSorting().getName()); int showLibrariesWidth = font.getStringWidth(showLibrariesText) + 20; int sortingWidth = font.getStringWidth(sortingText) + 20; int filtersX; int filtersWidth = showLibrariesWidth + sortingWidth + 2; - if ((filtersWidth + font.getStringWidth("Showing " + NumberFormat.getInstance().format(FabricLoader.getInstance().getAllMods().size()) + "/" + NumberFormat.getInstance().format(FabricLoader.getInstance().getAllMods().size()) + " Mods") + 20) >= searchBoxX + searchBoxWidth + 22) { + if ((filtersWidth + font.getStringWidth(i18n.translateKeyAndFormat("modmenu.showingMods", NumberFormat.getInstance().format(modList.getDisplayedCount()) + "/" + NumberFormat.getInstance().format(FabricLoader.getInstance().getAllMods().size()))) + 20) >= searchBoxX + searchBoxWidth + 22) { filtersX = paneWidth / 2 - filtersWidth / 2; showModCount = false; } else { @@ -167,7 +168,7 @@ public void render(Minecraft mc, int int_1, int int_2) { @Override public void drawButton(Minecraft mc, int mouseX, int mouseY) { visible = enabled = filterOptionsShown; - this.displayString = "Sort: " + ModMenuConfigManager.getConfig().getSorting().getName(); + this.displayString = i18n.translateKeyAndFormat("modmenu.sorting", ModMenuConfigManager.getConfig().getSorting().getName()); super.drawButton(mc, mouseX, mouseY); } }); @@ -175,7 +176,7 @@ public void drawButton(Minecraft mc, int mouseX, int mouseY) { @Override public void drawButton(Minecraft mc, int mouseX, int mouseY) { visible = enabled = filterOptionsShown; - this.displayString = ModMenuConfigManager.getConfig().showLibraries() ? "Libraries: Shown" : "Libraries: Hidden"; + this.displayString = i18n.translateKeyAndFormat("modmenu.showLibraries", i18n.translateKey("modmenu.showLibraries." + ModMenuConfigManager.getConfig().showLibraries())); super.drawButton(mc, mouseX, mouseY); } }); @@ -227,7 +228,7 @@ protected void buttonPressed(GuiButton button) { break; } case MODS_FOLDER_BUTTON_ID: { - File modsFolder = new File(FabricLoader.getInstance().getGameDirectory(), "mods"); + File modsFolder = new File(FabricLoader.getInstance().getGameDir().toFile(), "mods"); try { Sys.openURL(modsFolder.toURI().toURL().toString()); } catch (MalformedURLException e) { @@ -274,6 +275,7 @@ public void mouseMovedOrUp(int mouseX, int mouseY, int mouseButton) { @Override public void drawScreen(int mouseX, int mouseY, float delta) { + I18n i18n = I18n.getInstance(); int mouseDX = Mouse.getEventDX() * this.width / this.mc.resolution.width; // field_6326_c int mouseDY = this.height - Mouse.getEventDY() * this.height / this.mc.resolution.height - 1; // field_6325_d for (int button = 0; button < Mouse.getButtonCount(); button++) { @@ -299,7 +301,8 @@ public void drawScreen(int mouseX, int mouseY, float delta) { this.drawStringCentered(font, this.textTitle, this.modList.getWidth() / 2, 8, 0xffffff); super.drawScreen(mouseX, mouseY, delta); if (showModCount || !filterOptionsShown) { - font.drawString("Showing " + NumberFormat.getInstance().format(modList.getDisplayedCount()) + "/" + NumberFormat.getInstance().format(FabricLoader.getInstance().getAllMods().size()) + " Mods", searchBoxX, 52, 0xFFFFFF); + String showModCountString = i18n.translateKeyAndFormat("modmenu.showingMods", NumberFormat.getInstance().format(modList.getDisplayedCount()) + "/" + NumberFormat.getInstance().format(FabricLoader.getInstance().getAllMods().size())); + font.drawString(showModCountString, searchBoxX, 52, 0xFFFFFF); } if (selectedEntry != null) { ModMetadata metadata = selectedEntry.getMetadata(); @@ -316,7 +319,7 @@ public void drawScreen(int mouseX, int mouseY, float delta) { trimmedName = getString(font, name, trimmedName, maxNameWidth); font.drawString(trimmedName, x + imageOffset, paneY + 1, 0xFFFFFF); if (mouseX > x + imageOffset && mouseY > paneY + 1 && mouseY < paneY + 1 + 9 && mouseX < x + imageOffset + font.getStringWidth(trimmedName)) { - setTooltip("Mod ID: " + metadata.getId()); + setTooltip(i18n.translateKeyAndFormat("modmenu.modIdToolTip", metadata.getId())); } if (init || badgeRenderer == null || badgeRenderer.getMetadata() != metadata) { badgeRenderer = new BadgeRenderer(mc, x + imageOffset + font.getStringWidth(trimmedName) + 2, paneY, width - 28, selectedEntry.container, this); @@ -339,13 +342,12 @@ public void drawScreen(int mouseX, int mouseY, float delta) { } else { authors = names.get(0); } - RenderUtils.INSTANCE.drawWrappedString(font, "By " + authors, x + imageOffset, paneY + 2 + lineSpacing * 2, paneWidth - imageOffset - 4, 1, 0x808080); + RenderUtils.INSTANCE.drawWrappedString(font, i18n.translateKeyAndFormat("modmenu.authorPrefix", authors), x + imageOffset, paneY + 2 + lineSpacing * 2, paneWidth - imageOffset - 4, 1, 0x808080); } if (this.tooltip != null) { this.renderTooltip(Lists.newArrayList(Splitter.on("\n").split(this.tooltip)), mouseX, mouseY); } } - } static String getString(FontRenderer font, String name, String trimmedName, int maxNameWidth) { diff --git a/src/main/java/io/github/prospector/modmenu/gui/TextFieldWidget.java b/src/main/java/io/github/prospector/modmenu/gui/TextFieldWidget.java index 0a09030bf..62251eeb6 100644 --- a/src/main/java/io/github/prospector/modmenu/gui/TextFieldWidget.java +++ b/src/main/java/io/github/prospector/modmenu/gui/TextFieldWidget.java @@ -9,6 +9,7 @@ import net.minecraft.client.render.FontRenderer; import net.minecraft.client.render.Tessellator; import net.minecraft.core.enums.EnumOS; +import org.jetbrains.annotations.Nullable; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; @@ -65,13 +66,20 @@ public class TextFieldWidget extends GuiScreen implements ITextField { */ private Predicate validator = s -> true; - public TextFieldWidget(FontRenderer font, int x, int y, int width, int height) { + private final @Nullable String emptyText; + + public TextFieldWidget(FontRenderer font, int x, int y, int width, int height, String emptyText) { this.font = font; this.x = x; this.y = y; this.width = width; this.height = height; this.handler = new TextFieldEditor(this); + this.emptyText = emptyText; + } + + public TextFieldWidget(FontRenderer font, int x, int y, int width, int height) { + this(font, x, y, width, height, null); } /** @@ -465,6 +473,8 @@ public void drawTextBox() { String s1 = flag ? s.substring(0, j) : s; font.drawStringWithShadow(s1, l, i1, i); j1 += font.getStringWidth(s1) + 1; + } else if (emptyText != null && !this.isFocused) { + font.drawStringWithShadow(emptyText, l, i1, 6250335); } boolean flag2 = cursorPosition < text.length() || text.length() >= getMaxStringLength(); diff --git a/src/main/java/io/github/prospector/modmenu/mixin/LanguageAccessor.java b/src/main/java/io/github/prospector/modmenu/mixin/LanguageAccessor.java new file mode 100644 index 000000000..6ea8a752f --- /dev/null +++ b/src/main/java/io/github/prospector/modmenu/mixin/LanguageAccessor.java @@ -0,0 +1,16 @@ +package io.github.prospector.modmenu.mixin; + +import net.minecraft.core.lang.Language; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Properties; + +@Mixin( + value = Language.class, + remap = false +) +public interface LanguageAccessor { + @Accessor + Properties getEntries(); +} diff --git a/src/main/java/io/github/prospector/modmenu/mixin/MinecraftAccessor.java b/src/main/java/io/github/prospector/modmenu/mixin/MinecraftAccessor.java index 81ca9dba0..fd5e6eb41 100644 --- a/src/main/java/io/github/prospector/modmenu/mixin/MinecraftAccessor.java +++ b/src/main/java/io/github/prospector/modmenu/mixin/MinecraftAccessor.java @@ -10,6 +10,6 @@ public interface MinecraftAccessor { @Invoker("getOs") static EnumOS getOS() { - return EnumOS.windows; + throw new AssertionError("This should never be thrown"); } } diff --git a/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiIngameMenu.java b/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiIngameMenu.java index b0e73842a..9916e3f95 100644 --- a/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiIngameMenu.java +++ b/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiIngameMenu.java @@ -7,6 +7,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiIngameMenu; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.core.lang.I18n; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -16,12 +17,14 @@ public class MixinGuiIngameMenu extends GuiScreen { @SuppressWarnings("unchecked") @Inject(at = @At("RETURN"), method = "initGui") - public void drawMenuButton(CallbackInfo info) { - this.controlList.add(new ModMenuButtonWidget(100, this.width / 2 - 100, this.height / 4 + 72 - 16, 200, 20, "Mods (" + ModMenu.getFormattedModCount() + " loaded)")); + public void modmenu$drawMenuButton(CallbackInfo info) { + I18n i18n = I18n.getInstance(); + String buttonText = i18n.translateKey("modmenu.title") + " " + i18n.translateKeyAndFormat("modmenu.loaded", ModMenu.getFormattedModCount()); + this.controlList.add(new ModMenuButtonWidget(100, this.width / 2 - 100, this.height / 4 + 72 - 16, 200, 20, buttonText)); } @Inject(method = "buttonPressed", at = @At("HEAD")) - private void onActionPerformed(GuiButton button, CallbackInfo ci) { + private void modmenu$onActionPerformed(GuiButton button, CallbackInfo ci) { if (button.id == 100) { mc.displayGuiScreen(new ModListScreen(this)); } diff --git a/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiMainMenu.java b/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiMainMenu.java index 6d5ff59c2..88306f079 100644 --- a/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiMainMenu.java +++ b/src/main/java/io/github/prospector/modmenu/mixin/MixinGuiMainMenu.java @@ -7,6 +7,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.core.lang.I18n; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,19 +18,20 @@ @Mixin(value = GuiMainMenu.class, remap = false) public class MixinGuiMainMenu extends GuiScreen { @Inject(at = @At("RETURN"), method = "initGui") - public void drawMenuButton(CallbackInfo info) { + public void modmenu$drawMenuButton(CallbackInfo info) { + I18n i18n = I18n.getInstance(); GuiButton texturePackButton = this.controlList.get(2); - texturePackButton.displayString = new Random().nextInt(1000) == 0 ? "Twin Peaks" : "Texture Packs"; + texturePackButton.displayString = new Random().nextInt(1000) == 0 ? "Twin Peaks" : i18n.translateKey("menu.mods"); int newWidth = ((GuiButtonAccessor) texturePackButton).getWidth() / 2 - 1; ((GuiButtonAccessor) texturePackButton).setWidth(newWidth); - this.controlList.add(new ModMenuButtonWidget(100, this.width / 2 + 2, texturePackButton.yPosition, newWidth, 20, "Mods (" + ModMenu.getFormattedModCount() + " loaded)")); + String buttonText = i18n.translateKey("modmenu.title") + " " + i18n.translateKeyAndFormat("modmenu.loaded", ModMenu.getFormattedModCount()); + this.controlList.add(new ModMenuButtonWidget(100, this.width / 2 + 2, texturePackButton.yPosition, newWidth, 20, buttonText)); } @Inject(method = "buttonPressed", at = @At("HEAD")) - private void onActionPerformed(GuiButton button, CallbackInfo ci) { + private void modmenu$onActionPerformed(GuiButton button, CallbackInfo ci) { if (button.id == 100) { mc.displayGuiScreen(new ModListScreen(this)); } } - } diff --git a/src/main/java/io/github/prospector/modmenu/mixin/MixinI18n.java b/src/main/java/io/github/prospector/modmenu/mixin/MixinI18n.java new file mode 100644 index 000000000..72dcbbf2c --- /dev/null +++ b/src/main/java/io/github/prospector/modmenu/mixin/MixinI18n.java @@ -0,0 +1,42 @@ +package io.github.prospector.modmenu.mixin; + +import net.minecraft.core.lang.I18n; +import net.minecraft.core.lang.Language; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Properties; + +@Mixin(value = I18n.class, remap = false) +public class MixinI18n { + @Shadow private Language currentLanguage; + + @Shadow + public static InputStream getResourceAsStream(String path) { + throw new AssertionError(); + } + + @Inject( + method = "reload(Ljava/lang/String;Z)V", + at = @At("TAIL") + ) + private void modmenu$addLangEntries(String languageCode, boolean save, CallbackInfo ci) { + Properties entries = ((LanguageAccessor) currentLanguage).getEntries(); + String lang = "/lang/modmenu/" + currentLanguage.getId() + ".json"; + try (InputStream stream = getResourceAsStream(lang)) { + if (stream != null) { + InputStreamReader r = new InputStreamReader(stream, StandardCharsets.UTF_8); + entries.load(r); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/io/github/prospector/modmenu/mixin/MixinTexturePacks.java b/src/main/java/io/github/prospector/modmenu/mixin/MixinTexturePacks.java index b5c25ae25..d4a0d15f1 100644 --- a/src/main/java/io/github/prospector/modmenu/mixin/MixinTexturePacks.java +++ b/src/main/java/io/github/prospector/modmenu/mixin/MixinTexturePacks.java @@ -14,7 +14,7 @@ @Mixin(value = {TexturePackBase.class, TexturePackCustom.class}, remap = false) public class MixinTexturePacks { @Inject(method = "getResourceAsStream", at = @At(value = "INVOKE", target = "Ljava/lang/Class;getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;", remap = false), cancellable = true) - private void onGetResource(String resource, CallbackInfoReturnable ci) { + private void modmenu$onGetResource(String resource, CallbackInfoReturnable ci) { InputStream in = ModMenu.class.getClassLoader().getResourceAsStream(resource); if (in != null) ci.setReturnValue(in); diff --git a/src/main/java/io/github/prospector/modmenu/mixin/ModMenuMixinConfigPlugin.java b/src/main/java/io/github/prospector/modmenu/mixin/ModMenuMixinConfigPlugin.java new file mode 100644 index 000000000..cdae7711b --- /dev/null +++ b/src/main/java/io/github/prospector/modmenu/mixin/ModMenuMixinConfigPlugin.java @@ -0,0 +1,42 @@ +package io.github.prospector.modmenu.mixin; + +import net.fabricmc.loader.api.FabricLoader; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Set; + +public class ModMenuMixinConfigPlugin implements IMixinConfigPlugin { + @Override + public void onLoad(String mixinPackage) {} + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + // Only applies when Halplibe is not present + if (mixinClassName.equals("io.github.prospector.modmenu.mixin.MixinI18n")) { + return !(FabricLoader.getInstance().isModLoaded("halplibe")); + } + return true; + } + + @Override + public void acceptTargets(Set myTargets, Set otherTargets) {} + + @Override + public List getMixins() { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} +} diff --git a/src/main/java/io/github/prospector/modmenu/util/BadgeRenderer.java b/src/main/java/io/github/prospector/modmenu/util/BadgeRenderer.java index f65b7f6b8..a97660469 100644 --- a/src/main/java/io/github/prospector/modmenu/util/BadgeRenderer.java +++ b/src/main/java/io/github/prospector/modmenu/util/BadgeRenderer.java @@ -6,6 +6,7 @@ import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.metadata.ModMetadata; import net.minecraft.client.Minecraft; +import net.minecraft.core.lang.I18n; import java.util.Calendar; import java.util.Map; @@ -28,22 +29,23 @@ public BadgeRenderer(Minecraft client, int startX, int startY, int endX, ModCont } public void draw(int mouseX, int mouseY) { + I18n i18n = I18n.getInstance(); this.badgeX = startX; this.badgeY = startY; if (ModMenu.LIBRARY_MODS.contains(metadata.getId())) { - drawBadge("Library", 0x8810d098, 0x88046146, mouseX, mouseY); + drawBadge(i18n.translateKey("modmenu.library"), 0x8810d098, 0x88046146, mouseX, mouseY); } if (ModMenu.CLIENTSIDE_MODS.contains(metadata.getId())) { - drawBadge("Client", 0x884383E3, 0x880E4699, mouseX, mouseY); + drawBadge(i18n.translateKey("modmenu.clientsideOnly"), 0x884383E3, 0x880E4699, mouseX, mouseY); } if (ModMenu.DEPRECATED_MODS.contains(metadata.getId())) { - drawBadge("Deprecated", 0xFF841426, 0xFF530C17, mouseX, mouseY); + drawBadge(i18n.translateKey("modmenu.deprecated"), 0xFF841426, 0xFF530C17, mouseX, mouseY); } if (ModMenu.PATCHWORK_FORGE_MODS.contains(metadata.getId())) { - drawBadge("Forge", 0x887C89A3, 0x88202C43, mouseX, mouseY); + drawBadge(i18n.translateKey("modmenu.forge"), 0x887C89A3, 0x88202C43, mouseX, mouseY); } if (metadata.getId().equals("minecraft")) { - drawBadge("Minecraft", 0x88BCBCBC, 0x88535353, mouseX, mouseY); + drawBadge(i18n.translateKey("modmenu.minecraft"), 0x88BCBCBC, 0x88535353, mouseX, mouseY); } if (ModMenu.CUSTOM_BADGE_MODS.containsKey(metadata.getId())) { Map> map = ModMenu.CUSTOM_BADGE_MODS.get(metadata.getId()); diff --git a/src/main/java/io/github/prospector/modmenu/util/ButtonUtil.java b/src/main/java/io/github/prospector/modmenu/util/ButtonUtil.java index 08ba81b3f..9c08743c6 100644 --- a/src/main/java/io/github/prospector/modmenu/util/ButtonUtil.java +++ b/src/main/java/io/github/prospector/modmenu/util/ButtonUtil.java @@ -4,7 +4,7 @@ import io.github.prospector.modmenu.mixin.GuiButtonAccessor; import net.minecraft.client.gui.GuiButton; -public class ButtonUtil { +public final class ButtonUtil { public static GuiButton createButton(int buttonId, int x, int y, int width, int height, String text) { GuiButton button = new GuiButton(buttonId, x, y, text); GuiButtonAccessor accessor = (GuiButtonAccessor) button; diff --git a/src/main/java/io/github/prospector/modmenu/util/HardcodedUtil.java b/src/main/java/io/github/prospector/modmenu/util/HardcodedUtil.java index f36e9e6cb..94b509d61 100644 --- a/src/main/java/io/github/prospector/modmenu/util/HardcodedUtil.java +++ b/src/main/java/io/github/prospector/modmenu/util/HardcodedUtil.java @@ -10,7 +10,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class HardcodedUtil { +public final class HardcodedUtil { private static final Pattern FABRIC_PATTERN = Pattern.compile("^fabric-.*(-v\\d+)$"); private static final Set FABRIC_MODS = new HashSet<>(); private static final HashMap HARDCODED_DESCRIPTIONS = new HashMap<>(); diff --git a/src/main/java/io/github/prospector/modmenu/util/ModListSearch.java b/src/main/java/io/github/prospector/modmenu/util/ModListSearch.java index 718112ffd..a21e9e567 100644 --- a/src/main/java/io/github/prospector/modmenu/util/ModListSearch.java +++ b/src/main/java/io/github/prospector/modmenu/util/ModListSearch.java @@ -12,7 +12,7 @@ import java.util.Objects; import java.util.stream.Collectors; -public class ModListSearch { +public final class ModListSearch { public static boolean validSearchQuery(String query) { return query != null && !query.isEmpty(); diff --git a/src/main/java/io/github/prospector/modmenu/util/RenderUtils.java b/src/main/java/io/github/prospector/modmenu/util/RenderUtils.java index a4edf7c56..ed8c30001 100644 --- a/src/main/java/io/github/prospector/modmenu/util/RenderUtils.java +++ b/src/main/java/io/github/prospector/modmenu/util/RenderUtils.java @@ -11,7 +11,7 @@ import java.util.List; @Environment(EnvType.CLIENT) -public class RenderUtils extends GuiScreen { +public final class RenderUtils extends GuiScreen { public static final RenderUtils INSTANCE = new RenderUtils(); private RenderUtils() {} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e129fa7a0..47d7a6cd5 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "modmenu", "name": "Mod Menu", - "version": "$version", + "version": "${version}", "environment": "client", "license": "MIT", "icon": "assets/modmenu/icon.png", @@ -55,8 +55,5 @@ "description": "Adds a mod menu to view the list of mods you have installed.", "mixins": [ "mixins.modmenu.json" - ], - "custom": { - "modmenu:clientsideOnly": true - } + ] } diff --git a/src/main/resources/lang/modmenu/bg_BG.lang b/src/main/resources/lang/modmenu/bg_BG.lang new file mode 100644 index 000000000..5d9223e3d --- /dev/null +++ b/src/main/resources/lang/modmenu/bg_BG.lang @@ -0,0 +1,10 @@ +modmenu.title=Модификации +modmenu.loaded=(%s заредени) +modmenu.config=Редактирай конфигурация +modmenu.modsFolder=Отвори папка с модификации +modmenu.configsFolder=Отвори папка с конфигурации +modmenu.configure=Конфигурирай... +modmenu.modIdToolTip=ID на модификацията: %s +modmenu.website=Уебсайт +modmenu.issues=Проблеми +modmenu.authorPrefix=От %s diff --git a/src/main/resources/lang/modmenu/de_DE.lang b/src/main/resources/lang/modmenu/de_DE.lang new file mode 100644 index 000000000..792d6ab1f --- /dev/null +++ b/src/main/resources/lang/modmenu/de_DE.lang @@ -0,0 +1,6 @@ +modmenu.title=Mods +modmenu.loaded=(%s geladen) +modmenu.config=Ändere Konfiguration +modmenu.modsFolder=Öffne Mods-Ordner +modmenu.configsFolder=Öffne Konfigurationen-Ordner +modmenu.configure=Konfiguriere... diff --git a/src/main/resources/lang/modmenu/en_US.lang b/src/main/resources/lang/modmenu/en_US.lang new file mode 100644 index 000000000..9431fa471 --- /dev/null +++ b/src/main/resources/lang/modmenu/en_US.lang @@ -0,0 +1,29 @@ +modmenu.title=Mods +modmenu.loaded=(%s Loaded) +modmenu.config=Edit Config +modmenu.modsFolder=Open Mods Folder +modmenu.configsFolder=Open Configs Folder +modmenu.configure=Configure... +modmenu.modIdToolTip=Mod ID: %s +modmenu.website=Website +modmenu.issues=Issues +modmenu.authorPrefix=By %s +modmenu.authors=Authors: +modmenu.contributors=Contributors: +modmenu.licenses=Licenses: +modmenu.search=Search for mods +modmenu.clientsideOnly=Client +modmenu.library=Library +modmenu.deprecated=Deprecated +modmenu.toggleFilterOptions=Toggle Filter Options +modmenu.showLibraries=Libraries: %s +modmenu.showLibraries.true=Shown +modmenu.showLibraries.false=Hidden +modmenu.showingMods=Showing %s Mods +modmenu.sorting=Sort: %s +modmenu.sorting.ascending=A-Z +modmenu.sorting.decending=Z-A +modmenu.minecraft=Minecraft +modmenu.forge=Forge +modmenu.default.mc.desc.normal=The base game. +modmenu.default.mc.desc.based=The based game. diff --git a/src/main/resources/lang/modmenu/et_EE.lang b/src/main/resources/lang/modmenu/et_EE.lang new file mode 100644 index 000000000..a0ec5e32b --- /dev/null +++ b/src/main/resources/lang/modmenu/et_EE.lang @@ -0,0 +1,21 @@ +modmenu.title=Modid +modmenu.loaded=(%s laaditud) +modmenu.config=Muuda seadistust +modmenu.modsFolder=Ava modide kaust +modmenu.configsFolder=Ava seadistuste kaust +modmenu.configure=Seadista... +modmenu.modIdToolTip=Modi ID: %s +modmenu.website=Veebileht +modmenu.issues=Veahaldus +modmenu.authorPrefix=Autorilt %s +modmenu.search=Otsi mode +modmenu.clientsideOnly=Klient +modmenu.library=Teek +modmenu.toggleFilterOptions=Lülita filtreerimisvalikuid +modmenu.showLibraries=Teegid: %s +modmenu.showLibraries.true=kuvatud +modmenu.showLibraries.false=peidetud +modmenu.showingMods=Kuvan %s modi +modmenu.sorting=Jrk: %s +modmenu.sorting.ascending=A-Z +modmenu.sorting.decending=Z-A diff --git a/src/main/resources/lang/modmenu/fi_FI.lang b/src/main/resources/lang/modmenu/fi_FI.lang new file mode 100644 index 000000000..cafdd49c2 --- /dev/null +++ b/src/main/resources/lang/modmenu/fi_FI.lang @@ -0,0 +1,11 @@ +modmenu.title=Modit +modmenu.loaded=(%s ladattu) +modmenu.config=Muuta asetuksia +modmenu.modsFolder=Avaa modikansio +modmenu.configsFolder=Avaa asetuskansio +modmenu.configure=Asetukset... +modmenu.modIdToolTip=Modi-ID: %s +modmenu.website=Kotisivu +modmenu.issues=Ongelmat +modmenu.authorPrefix=Tehnyt %s +modmenu.search=Etsi modeja diff --git a/src/main/resources/lang/modmenu/fr_FR.lang b/src/main/resources/lang/modmenu/fr_FR.lang new file mode 100644 index 000000000..a5b075b89 --- /dev/null +++ b/src/main/resources/lang/modmenu/fr_FR.lang @@ -0,0 +1,18 @@ +modmenu.title=Mods +modmenu.loaded=(%s chargés) +modmenu.config=Modifier la config +modmenu.modsFolder=Ouvrir le dossier des mods +modmenu.configsFolder=Ouvrir le dossier des configs +modmenu.configure=Configurer... +modmenu.modIdToolTip=ID du mod : %s +modmenu.website=Site web +modmenu.issues=Problèmes +modmenu.authorPrefix=Par %s +modmenu.search=Rechercher des mods +modmenu.clientsideOnly=Client +modmenu.library=Librairie +modmenu.toggleFilterOptions=Basculer options de filtre +modmenu.showLibraries=Librairies : %s +modmenu.showLibraries.true=montrées +modmenu.showLibraries.false=cachées +modmenu.showingMods=%s mods affichés diff --git a/src/main/resources/lang/modmenu/ja_JP.lang b/src/main/resources/lang/modmenu/ja_JP.lang new file mode 100644 index 000000000..ff363170d --- /dev/null +++ b/src/main/resources/lang/modmenu/ja_JP.lang @@ -0,0 +1,22 @@ +modmenu.title=Mods +modmenu.loaded=(%s個 読込済み) +modmenu.config=設定の編集 +modmenu.modsFolder=modsフォルダーを開く +modmenu.configsFolder=configフォルダーを開く +modmenu.configure=設定… +modmenu.modIdToolTip=Mod ID: %s +modmenu.website=ウェブサイト +modmenu.issues=バグを報告 +modmenu.authorPrefix=制作: %s +modmenu.search=Modを検索 +modmenu.clientsideOnly=クライアント +modmenu.library=前提mod +modmenu.toggleFilterOptions=フィルター設定の切り替え +modmenu.showLibraries=前提mod: %s +modmenu.showLibraries.true=表示 +modmenu.showLibraries.false=非表示 +modmenu.showingMods=%s個のmodを表示中 +modmenu.sorting=表示順: %s +modmenu.sorting.ascending=昇順(A-Z) +modmenu.sorting.decending=降順(Z-A) +modmenu.minecraft=Minecraft diff --git a/src/main/resources/lang/modmenu/pt_BR.lang b/src/main/resources/lang/modmenu/pt_BR.lang new file mode 100644 index 000000000..8d187bc74 --- /dev/null +++ b/src/main/resources/lang/modmenu/pt_BR.lang @@ -0,0 +1,10 @@ +modmenu.title=Mods +modmenu.loaded=(%s Carregados) +modmenu.config=Editar Config +modmenu.modsFolder=Abrir pasta de mods +modmenu.configsFolder=Abrir pasta de Config +modmenu.configure=Configuração... +modmenu.modIdToolTip=Mod ID: %s +modmenu.website=Website +modmenu.issues=Problemas +modmenu.authorPrefix=Por %s diff --git a/src/main/resources/lang/modmenu/ru_RU.lang b/src/main/resources/lang/modmenu/ru_RU.lang new file mode 100644 index 000000000..fbb6a3936 --- /dev/null +++ b/src/main/resources/lang/modmenu/ru_RU.lang @@ -0,0 +1,23 @@ +modmenu.title=Моды +modmenu.loaded=(загружено: %s) +modmenu.config=Изменить настройки +modmenu.modsFolder=Открыть папку модов +modmenu.configsFolder=Открыть папку настроек +modmenu.configure=Настроить... +modmenu.modIdToolTip=ID мода: %s +modmenu.website=Сайт +modmenu.issues=Проблемы/Вопросы +modmenu.authorPrefix=От %s +modmenu.search=Поиск модов +modmenu.clientsideOnly=Клиент +modmenu.library=Библиотека +modmenu.toggleFilterOptions=Переключить параметры фильтра +modmenu.showLibraries=Библиотеки: %s +modmenu.showLibraries.true=Показано +modmenu.showLibraries.false=Скрыто +modmenu.showingMods=Показано модов: %s +modmenu.sorting=Сортировка: %s +modmenu.sorting.ascending=A-Z +modmenu.sorting.decending=Z-A +modmenu.minecraft=Minecraft +modmenu.forge=Forge diff --git a/src/main/resources/lang/modmenu/zh_CN.lang b/src/main/resources/lang/modmenu/zh_CN.lang new file mode 100644 index 000000000..073712a27 --- /dev/null +++ b/src/main/resources/lang/modmenu/zh_CN.lang @@ -0,0 +1,19 @@ +modmenu.title=模组 +modmenu.loaded=(已载入%s个) +modmenu.config=编辑配置 +modmenu.modsFolder=开启模组文件夹 +modmenu.configsFolder=开启配置文件夹 +modmenu.configure=配置... +modmenu.modIdToolTip=模组 ID: %s +modmenu.website=网站 +modmenu.issues=反馈 +modmenu.authorPrefix=作者: %s +modmenu.search=搜索模组 +modmenu.clientsideOnly=客户端 +modmenu.library=运行库 +modmenu.toggleFilterOptions=切换过滤选项 +modmenu.showLibraries=运行库: %s +modmenu.showLibraries.true=显示 +modmenu.showLibraries.false=隐藏 +modmenu.showingMods=显示 %s 个模组 +modmenu.sorting=排序方式: %s diff --git a/src/main/resources/lang/modmenu/zh_TW.lang b/src/main/resources/lang/modmenu/zh_TW.lang new file mode 100644 index 000000000..70fdd6edd --- /dev/null +++ b/src/main/resources/lang/modmenu/zh_TW.lang @@ -0,0 +1,17 @@ +modmenu.title=模組 +modmenu.loaded=(已載入%s個) +modmenu.config=編輯設置 +modmenu.modsFolder=開啟模組資料夾 +modmenu.configsFolder=開啟設置資料夾 +modmenu.configure=設置... +modmenu.modIdToolTip=模組 ID: %s +modmenu.website=網站 +modmenu.issues=反饋 +modmenu.authorPrefix=作者: %s +modmenu.search=搜索模组 +modmenu.clientsideOnly=玩家端 +modmenu.toggleFilterOptions=切換過濾選項 +modmenu.showLibraries.true=顯示 +modmenu.showLibraries.false=隱藏 +modmenu.showingMods=隱藏 %s 個模組 +modmenu.sorting=排序方式: %s diff --git a/src/main/resources/mixins.modmenu.json b/src/main/resources/mixins.modmenu.json index befd54a21..8e8298ddf 100644 --- a/src/main/resources/mixins.modmenu.json +++ b/src/main/resources/mixins.modmenu.json @@ -2,13 +2,16 @@ "required": true, "package": "io.github.prospector.modmenu.mixin", "compatibilityLevel": "JAVA_8", + "plugin": "io.github.prospector.modmenu.mixin.ModMenuMixinConfigPlugin", "client": [ "MixinGuiIngameMenu", "MixinGuiMainMenu", "MixinTexturePacks", "GuiButtonAccessor", "MinecraftAccessor", - "TextFieldEditorAccessor" + "LanguageAccessor", + "TextFieldEditorAccessor", + "MixinI18n" ], "injectors": { "defaultRequire": 1