Skip to content

Commit e100b1a

Browse files
committed
Fixed cconfig (commands in general) and refactored Minimap
1 parent 911b425 commit e100b1a

10 files changed

Lines changed: 727 additions & 541 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ This has now been implemented by upstream. They have unified both End City Ships
145145
### Improved ESP
146146
Configurable ESP settings allowing for custom colors, fill and transparency.
147147

148-
Example: ```/sm:config BlockHighlightESP set outlineColor #ff0000 outlineAlpha 0.5 fillEnabled true fillColor #00ff00 fillAlpha 0.35```
148+
Example: ```/sm:config ESP BlockHighlightESP set outlineColor #ff0000 outlineAlpha 0.5 fillEnabled true fillColor #00ff00 fillAlpha 0.35```
149149

150150
![ESP](https://i.imgur.com/LaHAJnI.png)
151151

@@ -164,7 +164,7 @@ I also added the ability to import waypoints from [Wurst7-CevAPI](https://github
164164
![Map](https://i.imgur.com/1qDgQw7.png)
165165

166166
### Highlight Timeout Setting
167-
Can now change the default 5 minute render timeout with ```/sm:config EspTimeoutMinutes```
167+
Can now change the default 5 minute render timeout with ```/sm:config ESP Timeout```
168168

169169
### Loot Table Browser
170170

src/main/java/dev/xpple/seedmapper/command/commands/EspConfigCommand.java

Lines changed: 33 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import com.google.common.collect.ImmutableMap;
44
import com.mojang.brigadier.Command;
55
import com.mojang.brigadier.CommandDispatcher;
6+
import com.mojang.brigadier.arguments.DoubleArgumentType;
67
import com.mojang.brigadier.arguments.StringArgumentType;
8+
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
79
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
8-
import com.mojang.brigadier.arguments.DoubleArgumentType;
910
import com.mojang.brigadier.context.CommandContext;
1011
import com.mojang.brigadier.exceptions.CommandSyntaxException;
1112
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
@@ -17,9 +18,7 @@
1718
import dev.xpple.seedmapper.config.Configs;
1819
import dev.xpple.seedmapper.render.RenderManager;
1920
import dev.xpple.seedmapper.render.esp.EspStyle;
20-
import dev.xpple.seedmapper.seedmap.SeedMapScreen;
2121
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
22-
import net.minecraft.client.Minecraft;
2322
import net.minecraft.commands.SharedSuggestionProvider;
2423
import net.minecraft.network.chat.Component;
2524

@@ -48,48 +47,49 @@ private EspConfigCommand() {
4847
private static final SimpleCommandExceptionType INVALID_COLOR = new SimpleCommandExceptionType(Component.literal("Invalid color. Use hex, e.g. #RRGGBB or #AARRGGBB."));
4948
private static final DynamicCommandExceptionType UNKNOWN_PROPERTY = new DynamicCommandExceptionType(value -> Component.literal("Unknown ESP property \"" + value + "\"."));
5049
private static final DynamicCommandExceptionType UNKNOWN_TARGET = new DynamicCommandExceptionType(value -> Component.literal("Unknown ESP target \"" + value + "\"."));
51-
private static final SimpleCommandExceptionType MAP_SIZE_UNAVAILABLE = new SimpleCommandExceptionType(Component.literal("Unable to determine seed map size. Make sure the game window is open."));
50+
private static final double DEFAULT_ESP_TIMEOUT_MINUTES = 5.0D;
5251
private static final List<String> PROPERTY_SUGGESTIONS = Arrays.stream(EspProperty.values())
5352
.map(EspProperty::displayName)
5453
.toList();
55-
private static final double MIN_ZOOM_BLOCKS = 128.0D;
56-
private static final double MAX_ZOOM_BLOCKS = 100_000.0D;
5754

5855
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
5956
CommandNode<FabricClientCommandSource> cconfigRoot = dispatcher.getRoot().getChild("cconfig");
6057
if (cconfigRoot == null) {
61-
// If the BetterConfig client command isn't present, register a direct sm:config fallback
58+
// BetterConfig client command not present: register direct fallback.
6259
registerDirectSmConfig(dispatcher);
6360
return;
6461
}
62+
6563
CommandNode<FabricClientCommandSource> modRoot = cconfigRoot.getChild(SeedMapper.MOD_ID);
6664
if (modRoot == null) {
67-
// fallback to direct registration if mod-specific cconfig node missing
65+
// Mod-specific cconfig node missing: register direct fallback.
6866
registerDirectSmConfig(dispatcher);
6967
return;
7068
}
7169

72-
// Use a single target argument that accepts any case but suggests TitleCase names
73-
com.mojang.brigadier.builder.RequiredArgumentBuilder<FabricClientCommandSource, String> targetArgNode = argument("target", StringArgumentType.word())
74-
.suggests(EspConfigCommand::suggestTargets);
75-
targetArgNode.then(literal("get")
76-
.executes(ctx -> executeGet(ctx, getTargetArgument(ctx, "target"), null))
77-
.then(argument("property", StringArgumentType.word())
78-
.suggests(EspConfigCommand::suggestProperties)
79-
.executes(ctx -> executeGet(ctx, getTargetArgument(ctx, "target"), getPropertyArgument(ctx, "property")))));
80-
targetArgNode.then(literal("set")
81-
.then(argument("pairs", StringArgumentType.greedyString())
82-
.executes(ctx -> executeSet(ctx, getTargetArgument(ctx, "target")))));
83-
targetArgNode.then(literal("reset")
84-
.executes(ctx -> executeReset(ctx, getTargetArgument(ctx, "target"))));
85-
modRoot.addChild(targetArgNode.build());
86-
modRoot.addChild(buildZoomLiteral("Zoom").build());
70+
modRoot.addChild(buildEspLiteral("ESP").build());
71+
ZoomConfigCommand.register(modRoot);
8772
}
8873

8974
private static void registerDirectSmConfig(CommandDispatcher<FabricClientCommandSource> dispatcher) {
9075
LiteralArgumentBuilder<FabricClientCommandSource> smRoot = literal("sm:config");
91-
// single target argument for sm:config that suggests TitleCase but accepts any case when typed
92-
com.mojang.brigadier.builder.RequiredArgumentBuilder<FabricClientCommandSource, String> targetArgNode = argument("target", StringArgumentType.word())
76+
smRoot.then(buildEspLiteral("ESP"));
77+
ZoomConfigCommand.register(smRoot);
78+
dispatcher.register(smRoot);
79+
}
80+
81+
private static LiteralArgumentBuilder<FabricClientCommandSource> buildEspLiteral(String literalName) {
82+
LiteralArgumentBuilder<FabricClientCommandSource> espLiteral = literal(literalName);
83+
espLiteral.then(literal("Timeout")
84+
.then(literal("get")
85+
.executes(EspConfigCommand::executeTimeoutGet))
86+
.then(literal("set")
87+
.then(argument("minutes", DoubleArgumentType.doubleArg(0.0))
88+
.executes(ctx -> executeTimeoutSet(ctx, DoubleArgumentType.getDouble(ctx, "minutes")))))
89+
.then(literal("reset")
90+
.executes(ctx -> executeTimeoutSet(ctx, DEFAULT_ESP_TIMEOUT_MINUTES))));
91+
92+
RequiredArgumentBuilder<FabricClientCommandSource, String> targetArgNode = argument("target", StringArgumentType.word())
9393
.suggests(EspConfigCommand::suggestTargets);
9494
targetArgNode.then(literal("get")
9595
.executes(ctx -> executeGet(ctx, getTargetArgument(ctx, "target"), null))
@@ -101,95 +101,24 @@ private static void registerDirectSmConfig(CommandDispatcher<FabricClientCommand
101101
.executes(ctx -> executeSet(ctx, getTargetArgument(ctx, "target")))));
102102
targetArgNode.then(literal("reset")
103103
.executes(ctx -> executeReset(ctx, getTargetArgument(ctx, "target"))));
104-
smRoot.then(targetArgNode);
105-
smRoot.then(buildZoomLiteral("Zoom"));
106-
// esptimeout top-level alias
107-
smRoot.then(literal("esptimeout")
108-
.executes(ctx -> {
109-
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
110-
source.sendFeedback(Component.literal("EspTimeoutMinutes = " + Configs.EspTimeoutMinutes));
111-
return 1;
112-
})
113-
.then(argument("minutes", DoubleArgumentType.doubleArg(0.0))
114-
.executes(ctx -> {
115-
double minutes = DoubleArgumentType.getDouble(ctx, "minutes");
116-
Configs.EspTimeoutMinutes = minutes;
117-
Configs.save();
118-
RenderManager.setHighlightTimeout(Configs.EspTimeoutMinutes);
119-
CustomClientCommandSource.of(ctx.getSource()).sendFeedback(Component.literal("Updated EspTimeoutMinutes = " + minutes));
120-
return 1;
121-
})));
122-
dispatcher.register(smRoot);
104+
espLiteral.then(targetArgNode);
105+
return espLiteral;
123106
}
124107

125-
private static LiteralArgumentBuilder<FabricClientCommandSource> buildZoomLiteral(String literalName) {
126-
LiteralArgumentBuilder<FabricClientCommandSource> zoom = literal(literalName);
127-
zoom.then(literal("get")
128-
.executes(EspConfigCommand::executeZoomGet));
129-
zoom.then(literal("set")
130-
.then(argument("blocks", DoubleArgumentType.doubleArg(MIN_ZOOM_BLOCKS, MAX_ZOOM_BLOCKS))
131-
.executes(ctx -> executeZoomSet(ctx, DoubleArgumentType.getDouble(ctx, "blocks")))));
132-
zoom.then(literal("default")
133-
.executes(EspConfigCommand::executeZoomDefault));
134-
return zoom;
135-
}
136-
137-
private static int executeZoomGet(CommandContext<FabricClientCommandSource> ctx) throws CommandSyntaxException {
108+
private static int executeTimeoutGet(CommandContext<FabricClientCommandSource> ctx) {
138109
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
139-
double minPixels = Math.max(SeedMapScreen.MIN_PIXELS_PER_BIOME, Configs.SeedMapMinPixelsPerBiome);
140-
double blocks = computeBlocksForMinPixels(minPixels);
141-
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, minPixels)));
110+
source.sendFeedback(Component.literal("ESP.timeout = " + Configs.EspTimeoutMinutes));
142111
return Command.SINGLE_SUCCESS;
143112
}
144113

145-
private static int executeZoomSet(CommandContext<FabricClientCommandSource> ctx, double requestedBlocks) throws CommandSyntaxException {
146-
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
147-
double minPixels = convertBlocksToMinPixels(requestedBlocks);
148-
double clamped = Math.clamp(minPixels, SeedMapScreen.MIN_PIXELS_PER_BIOME, SeedMapScreen.MAX_PIXELS_PER_BIOME);
149-
Configs.SeedMapMinPixelsPerBiome = clamped;
150-
Configs.PixelsPerBiome = Math.max(Configs.PixelsPerBiome, clamped);
114+
private static int executeTimeoutSet(CommandContext<FabricClientCommandSource> ctx, double minutes) {
115+
Configs.EspTimeoutMinutes = minutes;
151116
Configs.save();
152-
double blocks = computeBlocksForMinPixels(clamped);
153-
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out updated to ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, clamped)));
117+
RenderManager.setHighlightTimeout(Configs.EspTimeoutMinutes);
118+
CustomClientCommandSource.of(ctx.getSource()).sendFeedback(Component.literal("Updated ESP.timeout = " + minutes));
154119
return Command.SINGLE_SUCCESS;
155120
}
156121

157-
private static int executeZoomDefault(CommandContext<FabricClientCommandSource> ctx) throws CommandSyntaxException {
158-
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
159-
double defaultMin = SeedMapScreen.DEFAULT_MIN_PIXELS_PER_BIOME;
160-
Configs.SeedMapMinPixelsPerBiome = defaultMin;
161-
Configs.PixelsPerBiome = Math.max(Configs.PixelsPerBiome, defaultMin);
162-
Configs.save();
163-
double blocks = computeBlocksForMinPixels(defaultMin);
164-
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out reset to ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, defaultMin)));
165-
return Command.SINGLE_SUCCESS;
166-
}
167-
168-
private static double convertBlocksToMinPixels(double blocks) throws CommandSyntaxException {
169-
int widthPixels = currentSeedMapWidthPixels();
170-
if (widthPixels <= 0) {
171-
throw MAP_SIZE_UNAVAILABLE.create();
172-
}
173-
return (widthPixels * SeedMapScreen.BIOME_SCALE) / blocks;
174-
}
175-
176-
private static double computeBlocksForMinPixels(double minPixelsPerBiome) throws CommandSyntaxException {
177-
int widthPixels = currentSeedMapWidthPixels();
178-
if (widthPixels <= 0) {
179-
throw MAP_SIZE_UNAVAILABLE.create();
180-
}
181-
double safeMin = Math.max(minPixelsPerBiome, SeedMapScreen.MIN_PIXELS_PER_BIOME);
182-
return (widthPixels * SeedMapScreen.BIOME_SCALE) / safeMin;
183-
}
184-
185-
private static int currentSeedMapWidthPixels() {
186-
Minecraft minecraft = Minecraft.getInstance();
187-
if (minecraft == null || minecraft.getWindow() == null) {
188-
return 0;
189-
}
190-
return SeedMapScreen.computeSeedMapWidth(minecraft.getWindow().getGuiScaledWidth());
191-
}
192-
193122
private static int executeGet(CommandContext<FabricClientCommandSource> ctx, EspTarget target, EspProperty property) {
194123
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
195124
EspStyle style = target.style();
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package dev.xpple.seedmapper.command.commands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.arguments.DoubleArgumentType;
5+
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
6+
import com.mojang.brigadier.context.CommandContext;
7+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
8+
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
9+
import com.mojang.brigadier.tree.CommandNode;
10+
import dev.xpple.seedmapper.command.CustomClientCommandSource;
11+
import dev.xpple.seedmapper.config.Configs;
12+
import dev.xpple.seedmapper.seedmap.SeedMapScreen;
13+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
14+
import net.minecraft.client.Minecraft;
15+
import net.minecraft.network.chat.Component;
16+
17+
import java.util.Locale;
18+
19+
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
20+
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
21+
22+
public final class ZoomConfigCommand {
23+
24+
private ZoomConfigCommand() {
25+
}
26+
27+
private static final SimpleCommandExceptionType MAP_SIZE_UNAVAILABLE = new SimpleCommandExceptionType(Component.literal("Unable to determine seed map size. Make sure the game window is open."));
28+
private static final double MIN_ZOOM_BLOCKS = 128.0D;
29+
private static final double MAX_ZOOM_BLOCKS = 100_000.0D;
30+
31+
public static void register(CommandNode<FabricClientCommandSource> root) {
32+
root.addChild(buildZoomLiteral().build());
33+
}
34+
35+
public static void register(LiteralArgumentBuilder<FabricClientCommandSource> root) {
36+
root.then(buildZoomLiteral());
37+
}
38+
39+
private static LiteralArgumentBuilder<FabricClientCommandSource> buildZoomLiteral() {
40+
LiteralArgumentBuilder<FabricClientCommandSource> zoom = literal("Zoom");
41+
zoom.then(literal("get")
42+
.executes(ZoomConfigCommand::executeZoomGet));
43+
zoom.then(literal("set")
44+
.then(argument("blocks", DoubleArgumentType.doubleArg(MIN_ZOOM_BLOCKS, MAX_ZOOM_BLOCKS))
45+
.executes(ctx -> executeZoomSet(ctx, DoubleArgumentType.getDouble(ctx, "blocks")))));
46+
zoom.then(literal("default")
47+
.executes(ZoomConfigCommand::executeZoomDefault));
48+
return zoom;
49+
}
50+
51+
private static int executeZoomGet(CommandContext<FabricClientCommandSource> ctx) throws CommandSyntaxException {
52+
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
53+
double minPixels = Math.max(SeedMapScreen.MIN_PIXELS_PER_BIOME, Configs.SeedMapMinPixelsPerBiome);
54+
double blocks = computeBlocksForMinPixels(minPixels);
55+
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, minPixels)));
56+
return Command.SINGLE_SUCCESS;
57+
}
58+
59+
private static int executeZoomSet(CommandContext<FabricClientCommandSource> ctx, double requestedBlocks) throws CommandSyntaxException {
60+
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
61+
double minPixels = convertBlocksToMinPixels(requestedBlocks);
62+
double clamped = Math.clamp(minPixels, SeedMapScreen.MIN_PIXELS_PER_BIOME, SeedMapScreen.MAX_PIXELS_PER_BIOME);
63+
Configs.SeedMapMinPixelsPerBiome = clamped;
64+
Configs.PixelsPerBiome = Math.max(Configs.PixelsPerBiome, clamped);
65+
Configs.save();
66+
double blocks = computeBlocksForMinPixels(clamped);
67+
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out updated to ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, clamped)));
68+
return Command.SINGLE_SUCCESS;
69+
}
70+
71+
private static int executeZoomDefault(CommandContext<FabricClientCommandSource> ctx) throws CommandSyntaxException {
72+
CustomClientCommandSource source = CustomClientCommandSource.of(ctx.getSource());
73+
double defaultMin = SeedMapScreen.DEFAULT_MIN_PIXELS_PER_BIOME;
74+
Configs.SeedMapMinPixelsPerBiome = defaultMin;
75+
Configs.PixelsPerBiome = Math.max(Configs.PixelsPerBiome, defaultMin);
76+
Configs.save();
77+
double blocks = computeBlocksForMinPixels(defaultMin);
78+
source.sendFeedback(Component.literal(String.format(Locale.ROOT, "Max zoom-out reset to ≈ %,.0f blocks at current GUI scale (min pixels per biome %.4f).", blocks, defaultMin)));
79+
return Command.SINGLE_SUCCESS;
80+
}
81+
82+
private static double convertBlocksToMinPixels(double blocks) throws CommandSyntaxException {
83+
int widthPixels = currentSeedMapWidthPixels();
84+
if (widthPixels <= 0) {
85+
throw MAP_SIZE_UNAVAILABLE.create();
86+
}
87+
return (widthPixels * SeedMapScreen.BIOME_SCALE) / blocks;
88+
}
89+
90+
private static double computeBlocksForMinPixels(double minPixelsPerBiome) throws CommandSyntaxException {
91+
int widthPixels = currentSeedMapWidthPixels();
92+
if (widthPixels <= 0) {
93+
throw MAP_SIZE_UNAVAILABLE.create();
94+
}
95+
double safeMin = Math.max(minPixelsPerBiome, SeedMapScreen.MIN_PIXELS_PER_BIOME);
96+
return (widthPixels * SeedMapScreen.BIOME_SCALE) / safeMin;
97+
}
98+
99+
private static int currentSeedMapWidthPixels() {
100+
Minecraft minecraft = Minecraft.getInstance();
101+
if (minecraft == null || minecraft.getWindow() == null) {
102+
return 0;
103+
}
104+
return SeedMapScreen.computeSeedMapWidth(minecraft.getWindow().getGuiScaledWidth());
105+
}
106+
}

0 commit comments

Comments
 (0)