blob: 9ddf9cdaa2f050d24d7952b4cf40648ecbc08bef (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
package de.hysky.skyblocker;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.logging.LogUtils;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Constants;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import org.slf4j.Logger;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* Command helper for disabling every configurable feature.
*/
public class DisableAll {
private static final Logger LOGGER = LogUtils.getLogger();
private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs";
@Init
public static void init() {
ClientCommandRegistrationCallback.EVENT.register(DisableAll::registerCommand);
}
private static final long CONFIRM_TIMEOUT = 30_000L; // 30 seconds
private static long confirmAllowedUntil;
private static void registerCommand(CommandDispatcher<FabricClientCommandSource> dispatcher, net.minecraft.command.CommandRegistryAccess registryAccess) {
dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE)
.then(ClientCommandManager.literal("disableAll")
.executes(DisableAll::confirmMessage)
.then(ClientCommandManager.literal("confirm")
.executes(DisableAll::disableAll)))
);
}
private static int confirmMessage(CommandContext<FabricClientCommandSource> context) {
confirmAllowedUntil = System.currentTimeMillis() + CONFIRM_TIMEOUT;
MutableText confirm = Text.translatable("skyblocker.disableAll.confirmYes")
.styled(style -> style.withClickEvent(new ClickEvent.RunCommand("/" + SkyblockerMod.NAMESPACE + " disableAll confirm")));
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.disableAll.confirm", confirm)));
return Command.SINGLE_SUCCESS;
}
private static int disableAll(CommandContext<FabricClientCommandSource> context) {
if (System.currentTimeMillis() > confirmAllowedUntil) {
context.getSource().sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.disableAll.notPending")));
return Command.SINGLE_SUCCESS;
}
confirmAllowedUntil = 0;
try {
SkyblockerConfigManager.update(config -> {
try {
disableBooleans(config);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.disableAll.success")));
} catch (Exception e) {
LOGGER.error("[Skyblocker DisableAll] Failed to disable all features", e);
context.getSource().sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.disableAll.failed")));
}
return Command.SINGLE_SUCCESS;
}
/**
* Recursively sets all boolean fields within our configuration classes to
* {@code false}. Previously this relied on the {@code SerialEntry} annotation
* from YACL, but the configuration system no longer uses it.
*/
private static void disableBooleans(Object target) throws IllegalAccessException {
for (Field field : target.getClass().getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue;
field.setAccessible(true);
Object value = field.get(target);
Class<?> type = field.getType();
if (type == boolean.class) {
field.setBoolean(target, false);
} else if (type == Boolean.class) {
field.set(target, false);
} else if (value instanceof java.util.Map<?, ?>) {
@SuppressWarnings("unchecked")
java.util.Map<Object, Object> m = (java.util.Map<Object, Object>) value;
for (java.util.Map.Entry<Object, Object> entry : m.entrySet()) {
if (entry.getValue() instanceof Boolean) {
m.put(entry.getKey(), Boolean.FALSE);
}
}
} else if (value != null && isConfigClass(type)) {
disableBooleans(value);
}
}
}
/**
* Returns {@code true} if the given class represents one of our config
* classes. This prevents {@link #disableBooleans(Object)} from touching
* unrelated objects from other mods.
*/
private static boolean isConfigClass(Class<?> clazz) {
return !clazz.isPrimitive()
&& !clazz.isEnum()
&& !clazz.isRecord()
&& !clazz.equals(String.class)
&& !Number.class.isAssignableFrom(clazz)
&& clazz.getPackageName().startsWith(CONFIGS_PACKAGE);
}
}
|