aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <roman.graef@gmail.com>2023-01-31 10:19:39 +0100
committerGitHub <noreply@github.com>2023-01-31 10:19:39 +0100
commit291860435d5487562b122aaddbe57c178a8734de (patch)
tree3f3974a581390c22ebadc00c7774605629557440
parent4465c640cb5fa9a69c0b8c38f63aba6f571a4e8d (diff)
downloadNotEnoughUpdates-291860435d5487562b122aaddbe57c178a8734de.tar.gz
NotEnoughUpdates-291860435d5487562b122aaddbe57c178a8734de.tar.bz2
NotEnoughUpdates-291860435d5487562b122aaddbe57c178a8734de.zip
Add EnforcedConfigValues: Allow disabling options via the repo (#535)
* Add EnforcedConfigValues: Allow disabling options via the repo * EnforcedConfigValues: Allow filtering for mod version * nitpicking
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java75
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt123
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt85
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt33
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.pngbin0 -> 898 bytes
8 files changed, 324 insertions, 2 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
index 9964b739..1855a2b5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
@@ -47,7 +47,7 @@ public class SettingsCommand extends ClientCommandBase {
NotEnoughUpdates.INSTANCE.openGui =
new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config, StringUtils.join(args, " ")));
} else {
- NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(NEUConfigEditor.editor);
+ NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config));
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
index c3969e35..9edad918 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
@@ -27,7 +27,7 @@ import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.GlStateManager;
public abstract class GuiOptionEditor {
- protected final ConfigProcessor.ProcessedOption option;
+ public final ConfigProcessor.ProcessedOption option;
private static final int HEIGHT = 45;
public GuiOptionEditor(ConfigProcessor.ProcessedOption option) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
index 9a75ec19..62b9b8e2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java
@@ -45,6 +45,7 @@ import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorFSR;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorKeybind;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorSlider;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorText;
+import io.github.moulberry.notenoughupdates.miscfeatures.EnforcedConfigValues;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
@@ -133,6 +134,7 @@ public class ConfigProcessor {
boolean optionPresent = optionField.isAnnotationPresent(ConfigOption.class);
if (optionPresent) {
+ String optionPath = categoryField.getName() + "." + optionField.getName();
ConfigOption optionAnnotation = optionField.getAnnotation(ConfigOption.class);
ProcessedOption option = new ProcessedOption(
optionAnnotation.name(),
@@ -231,6 +233,10 @@ public class ConfigProcessor {
//System.err.printf("Failed to load config option %s. Could not find suitable editor.\n", optionField.getName());
continue;
}
+ if (EnforcedConfigValues.INSTANCE.isBlockedFromEditing(optionPath)) {
+ editor = new GuiOptionEditorBlocked(editor);
+ }
+
option.editor = editor;
cat.options.put(optionField.getName(), option);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java
new file mode 100644
index 00000000..8415cf72
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.core.config.struct;
+
+import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditor;
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
+import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils;
+import lombok.var;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.ResourceLocation;
+
+public class GuiOptionEditorBlocked extends GuiOptionEditor {
+ public static final ResourceLocation blockedTexture = new ResourceLocation(
+ "notenoughupdates:textures/gui/config_blocked.png");
+ private final GuiOptionEditor base;
+
+ public GuiOptionEditorBlocked(GuiOptionEditor base) {
+ super(base.option);
+ this.base = base;
+ }
+
+ @Override
+ public void render(int x, int y, int width) {
+ // No super. We delegate and overlay ourselves instead.
+ base.render(x, y, width);
+
+ var mc = Minecraft.getMinecraft();
+
+ // Depress original option
+ Gui.drawRect(x, y, x + width, y + getHeight(), 0x80000000);
+
+ GlStateManager.color(1, 1, 1, 1);
+ mc.getTextureManager().bindTexture(blockedTexture);
+
+ float iconWidth = getHeight() * 96F / 64;
+ RenderUtils.drawTexturedRect(x, y, iconWidth, getHeight());
+
+ TextRenderUtils.drawStringScaledMaxWidth(
+ "This option is currently not available.",
+ mc.fontRendererObj,
+ x + iconWidth,y + getHeight() / 2F - mc.fontRendererObj.FONT_HEIGHT / 2F,
+ true, (int) (width - iconWidth), 0xFFFF4444
+ );
+ GlStateManager.color(1, 1, 1, 1);
+ }
+
+ @Override
+ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) {
+ return false;
+ }
+
+ @Override
+ public boolean keyboardInput() {
+ return false;
+ }
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
new file mode 100644
index 00000000..7351a4a0
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures
+
+import com.google.gson.JsonElement
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
+import io.github.moulberry.notenoughupdates.util.NotificationHandler
+import io.github.moulberry.notenoughupdates.util.Shimmy
+import io.github.moulberry.notenoughupdates.util.Utils
+import io.github.moulberry.notenoughupdates.util.kotlin.fromJson
+import net.minecraft.client.Minecraft
+import net.minecraftforge.client.event.GuiOpenEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+
+@NEUAutoSubscribe
+object EnforcedConfigValues {
+
+ class EnforcedValue {
+ // lateinit var because we use gson (instead of kotlinx.serialization which can handle data classes)
+ lateinit var path: String
+ lateinit var value: JsonElement
+ }
+
+ class EnforcedValueData {
+ var enforcedValues: List<EnforcedValue> = listOf()
+ var notificationPSA: List<String>? = null
+ var chatPSA: List<String>? = null
+ lateinit var affectedVersions: List<Int>
+ }
+
+
+ var enforcedValues: List<EnforcedValueData> = listOf()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val fixedValues = event.repositoryRoot.resolve("enforced_values")
+ enforcedValues = if (fixedValues.exists()) {
+ fixedValues.listFiles()
+ .filter {
+ it != null && it.isFile && it.canRead()
+ }
+ .map {
+ NotEnoughUpdates.INSTANCE.manager.gson.fromJson<EnforcedValueData>(it.readText())
+ }.filter {
+ NotEnoughUpdates.VERSION_ID in it.affectedVersions
+ }
+ } else {
+ listOf()
+ }
+ if (!event.isFirstLoad)
+ sendPSAs()
+ }
+
+ @SubscribeEvent
+ fun onGuiClose(event: GuiOpenEvent) {
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ var hasSentPSAsOnce = false
+
+ @SubscribeEvent
+ fun onTick(tickEvent: TickEvent.ClientTickEvent) {
+ if (hasSentPSAsOnce || Minecraft.getMinecraft().thePlayer == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock) return
+ hasSentPSAsOnce = true
+ sendPSAs()
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ fun sendPSAs() {
+ val notification = enforcedValues.flatMap { it.notificationPSA ?: emptyList() }
+ if (notification.isNotEmpty()) {
+ NotificationHandler.displayNotification(notification, true)
+ }
+ val chat = enforcedValues.flatMap { it.chatPSA ?: emptyList() }
+ if (chat.isNotEmpty()) {
+ for (line in chat) {
+ Utils.addChatMessage(line)
+ }
+ }
+ }
+
+
+ fun enforceOntoConfig(config: Any) {
+ for (enforcedValue in enforcedValues.flatMap { it.enforcedValues }) {
+ val shimmy = Shimmy.makeShimmy(config, enforcedValue.path.split("."))
+ if (shimmy == null) {
+ println("Could not create shimmy for path ${enforcedValue.path}")
+ continue
+ }
+ val currentValue = shimmy.getJson()
+ if (currentValue != enforcedValue.value) {
+ println("Resetting ${enforcedValue.path} to ${enforcedValue.value} from $currentValue")
+ shimmy.setJson(enforcedValue.value)
+ }
+ }
+ }
+
+ fun isBlockedFromEditing(optionPath: String): Boolean {
+ return enforcedValues.flatMap { it.enforcedValues }.any { it.path == optionPath }
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
new file mode 100644
index 00000000..37cdd3ac
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util
+
+import com.google.gson.Gson
+import com.google.gson.JsonElement
+import java.lang.reflect.Field
+
+class Shimmy private constructor(
+ val source: Any,
+ val field: Field,
+) {
+ companion object {
+ val gson = Gson()
+ private fun shimmy(source: Any?, fieldName: String): Any? {
+ if (source == null) return null
+ return try {
+ val declaredField = source.javaClass.getDeclaredField(fieldName)
+ declaredField.isAccessible = true
+ declaredField.get(source)
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ @JvmStatic
+ fun makeShimmy(source: Any?, path: List<String>): Shimmy? {
+ if (path.isEmpty())
+ return null
+ var source = source
+ for (part in path.dropLast(1)) {
+ source = shimmy(source, part)
+ }
+ if (source == null) return null
+ val lastName = path.last()
+ return try {
+ val field = source.javaClass.getDeclaredField(lastName)
+ field.isAccessible = true
+ Shimmy(
+ source,
+ field,
+ )
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ }
+
+ val clazz: Class<*> = field.type
+ fun get(): Any? {
+ return field.get(source)
+ }
+
+ fun set(value: Any?) {
+ field.set(source, value)
+ }
+
+ fun getJson(): JsonElement {
+ return gson.toJsonTree(get())
+ }
+
+ fun setJson(element: JsonElement) {
+ set(gson.fromJson(element, clazz))
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
new file mode 100644
index 00000000..00c3d729
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util.kotlin
+
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import java.lang.reflect.Type
+
+
+inline fun <reified T : Any> typeToken(): Type {
+ return (object : TypeToken<T>() {}).type
+}
+
+inline fun <reified T : Any> Gson.fromJson(string: String): T {
+ return fromJson(string, typeToken<T>())
+}
diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png b/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png
new file mode 100644
index 00000000..eb60da5f
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png
Binary files differ