From f09aeadc6e758c2cbc9d91910c0cada2ad8f0ad5 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sat, 24 Aug 2024 16:31:38 +0200 Subject: [PATCH] Allow management of whitelisted URLs and hosts through Mod Menu --- build.gradle | 12 +++ .../client/ModMenuConfig.java | 13 +++ .../client/ResourcePackPrivacyClient.java | 9 +++ .../screen/ManageListScreen.java | 28 +++++++ .../ResourcePackPrivacyConfigScreen.java | 55 +++++++++++++ .../screen/elements/ManageListWidget.java | 81 +++++++++++++++++++ .../resourcepackprivacy/lang/en_us.json | 6 +- src/main/resources/fabric.mod.json | 3 + 8 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/shiewk/resourcepackprivacy/client/ModMenuConfig.java create mode 100644 src/main/java/de/shiewk/resourcepackprivacy/screen/ManageListScreen.java create mode 100644 src/main/java/de/shiewk/resourcepackprivacy/screen/ResourcePackPrivacyConfigScreen.java create mode 100644 src/main/java/de/shiewk/resourcepackprivacy/screen/elements/ManageListWidget.java diff --git a/build.gradle b/build.gradle index 39f8bdd..3cb8018 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,17 @@ repositories { // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + filter { + includeGroup "maven.modrinth" + } + } } dependencies { @@ -27,6 +38,7 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modImplementation "maven.modrinth:modmenu:11.0.1" } processResources { diff --git a/src/main/java/de/shiewk/resourcepackprivacy/client/ModMenuConfig.java b/src/main/java/de/shiewk/resourcepackprivacy/client/ModMenuConfig.java new file mode 100644 index 0000000..7d00393 --- /dev/null +++ b/src/main/java/de/shiewk/resourcepackprivacy/client/ModMenuConfig.java @@ -0,0 +1,13 @@ +package de.shiewk.resourcepackprivacy.client; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import de.shiewk.resourcepackprivacy.screen.ResourcePackPrivacyConfigScreen; + +public class ModMenuConfig implements ModMenuApi { + + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return ResourcePackPrivacyConfigScreen::new; + } +} diff --git a/src/main/java/de/shiewk/resourcepackprivacy/client/ResourcePackPrivacyClient.java b/src/main/java/de/shiewk/resourcepackprivacy/client/ResourcePackPrivacyClient.java index 104c608..9d0bdbe 100644 --- a/src/main/java/de/shiewk/resourcepackprivacy/client/ResourcePackPrivacyClient.java +++ b/src/main/java/de/shiewk/resourcepackprivacy/client/ResourcePackPrivacyClient.java @@ -17,6 +17,7 @@ import net.minecraft.client.MinecraftClient; import java.io.*; import java.net.URL; +import java.util.List; public class ResourcePackPrivacyClient implements ClientModInitializer { @@ -102,6 +103,14 @@ public class ResourcePackPrivacyClient implements ClientModInitializer { } } + public static List getWhitelistedURLs() { + return whitelistedURLs; + } + + public static List getWhitelistedHosts() { + return whitelistedHosts; + } + @Override public void onInitializeClient() { whitelistFile = new File(MinecraftClient.getInstance().runDirectory.getPath() + "/resourcepackprivacy.json"); diff --git a/src/main/java/de/shiewk/resourcepackprivacy/screen/ManageListScreen.java b/src/main/java/de/shiewk/resourcepackprivacy/screen/ManageListScreen.java new file mode 100644 index 0000000..6a0b935 --- /dev/null +++ b/src/main/java/de/shiewk/resourcepackprivacy/screen/ManageListScreen.java @@ -0,0 +1,28 @@ +package de.shiewk.resourcepackprivacy.screen; + +import de.shiewk.resourcepackprivacy.screen.elements.ManageListWidget; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; + +import java.util.List; + +public class ManageListScreen extends Screen { + private final Screen parent; + private final List list; + public ManageListScreen(Text title, Screen parent, List list) { + super(title); + this.parent = parent; + this.list = list; + } + + @Override + public void close() { + assert client != null; + client.setScreen(parent); + } + + @Override + protected void init() { + addDrawableChild(new ManageListWidget(textRenderer, 0, 0, width-8, height, title, list)); + } +} diff --git a/src/main/java/de/shiewk/resourcepackprivacy/screen/ResourcePackPrivacyConfigScreen.java b/src/main/java/de/shiewk/resourcepackprivacy/screen/ResourcePackPrivacyConfigScreen.java new file mode 100644 index 0000000..51c4620 --- /dev/null +++ b/src/main/java/de/shiewk/resourcepackprivacy/screen/ResourcePackPrivacyConfigScreen.java @@ -0,0 +1,55 @@ +package de.shiewk.resourcepackprivacy.screen; + +import de.shiewk.resourcepackprivacy.client.ResourcePackPrivacyClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.GridWidget; +import net.minecraft.client.gui.widget.SimplePositioningWidget; +import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.text.Text; + +public class ResourcePackPrivacyConfigScreen extends Screen { + private final Screen parent; + private static final int buttonWidth = 192; + public ResourcePackPrivacyConfigScreen(Screen parent) { + super(Text.translatable("gui.resourcepackprivacy.config")); + this.parent = parent; + } + + @Override + public void close() { + assert client != null; + client.setScreen(parent); + } + + @Override + protected void init() { + { + final TextWidget tw = new TextWidget(Text.translatable("resourcepackprivacy.settings"), textRenderer); + tw.setPosition(width / 2 - tw.getWidth() / 2, 10); + addDrawableChild(tw); + } + { + final GridWidget gw = new GridWidget(); + gw.getMainPositioner().margin(4, 4, 4, 0); + final GridWidget.Adder adder = gw.createAdder(2); + adder.add(createButton(Text.translatable("resourcepackprivacy.settings.whitelistedURLs"), btn -> { + btn.active = false; + assert client != null; + client.setScreen(new ManageListScreen<>(Text.translatable("resourcepackprivacy.settings.whitelistedURLs"), this, ResourcePackPrivacyClient.getWhitelistedURLs())); + })); + adder.add(createButton(Text.translatable("resourcepackprivacy.settings.whitelistedHosts"), btn -> { + btn.active = false; + assert client != null; + client.setScreen(new ManageListScreen<>(Text.translatable("resourcepackprivacy.settings.whitelistedHosts"), this, ResourcePackPrivacyClient.getWhitelistedHosts())); + })); + gw.refreshPositions(); + SimplePositioningWidget.setPos(gw, 0, 0, this.width, this.height, 0.5F, 0.5f); + gw.forEachChild(this::addDrawableChild); + } + } + + private ButtonWidget createButton(Text m, ButtonWidget.PressAction action){ + return new ButtonWidget.Builder(m, action).width(buttonWidth).build(); + } +} diff --git a/src/main/java/de/shiewk/resourcepackprivacy/screen/elements/ManageListWidget.java b/src/main/java/de/shiewk/resourcepackprivacy/screen/elements/ManageListWidget.java new file mode 100644 index 0000000..c817a81 --- /dev/null +++ b/src/main/java/de/shiewk/resourcepackprivacy/screen/elements/ManageListWidget.java @@ -0,0 +1,81 @@ +package de.shiewk.resourcepackprivacy.screen.elements; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.ScrollableWidget; +import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.text.Text; + +import java.util.ArrayList; +import java.util.List; + +public class ManageListWidget extends ScrollableWidget { + private final List list; + private final List elements = new ArrayList<>(); + public ManageListWidget(TextRenderer renderer, int i, int j, int k, int l, Text text, List list) { + super(i, j, k, l, text); + this.list = list; + refreshElements(renderer); + } + + private void refreshElements(TextRenderer renderer){ + elements.clear(); + int yp = 0; + for (T t : new ObjectArrayList<>(list)) { + yp += 4; + final TextWidget tw = new TextWidget(Text.literal(t.toString()), renderer); + tw.setHeight(20); + tw.setPosition((width - 28) / 2 - (tw.getWidth() / 2), yp); + elements.add(tw); + elements.add(new ButtonWidget.Builder(Text.literal("x"), btn -> { + btn.active = false; + list.remove(t); + refreshElements(renderer); + }).width(20).position(width - 24, yp).build()); + yp += 20; + } + } + + @Override + protected int getContentsHeight() { + return list.size() * 24; + } + + @Override + protected double getDeltaYPerScroll() { + return 10; + } + + @Override + protected void renderContents(DrawContext context, int mouseX, int mouseY, float delta) { + mouseY += (int) getScrollY(); + for (ClickableWidget element : elements) { + element.render(context, mouseX, mouseY, delta); + } + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + mouseY += getScrollY(); + for (ClickableWidget element : elements) { + if (element.isMouseOver(mouseX, mouseY)){ + return element.mouseClicked(mouseX, mouseY, button); + } + } + return false; + } + + @Override + protected void drawBox(DrawContext context, int x, int y, int width, int height) { + + } +} diff --git a/src/main/resources/assets/resourcepackprivacy/lang/en_us.json b/src/main/resources/assets/resourcepackprivacy/lang/en_us.json index 047f7e6..2c7fb6b 100644 --- a/src/main/resources/assets/resourcepackprivacy/lang/en_us.json +++ b/src/main/resources/assets/resourcepackprivacy/lang/en_us.json @@ -9,5 +9,9 @@ "gui.resourcepackprivacy.alwaysHost": "Always accept packs from %s", "gui.resourcepackprivacy.viewURL": "View download URL", "gui.resourcepackprivacy.viewURLs": "View download URLs", - "gui.resourcepackprivacy.downloading": "Downloading server resource pack from %s" + "gui.resourcepackprivacy.downloading": "Downloading server resource pack from %s", + "gui.resourcepackprivacy.config": "Config", + "resourcepackprivacy.settings": "ResourcePackPrivacy Settings", + "resourcepackprivacy.settings.whitelistedURLs": "Manage allowed URLs", + "resourcepackprivacy.settings.whitelistedHosts": "Manage allowed pack hosts" } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4680eb0..f3a7f40 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -15,6 +15,9 @@ ], "main": [ "de.shiewk.resourcepackprivacy.ResourcePackPrivacy" + ], + "modmenu": [ + "de.shiewk.resourcepackprivacy.client.ModMenuConfig" ] }, "mixins": [