From 7288daa5a24389244d13b15cee49fea4e5879e13 Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Wed, 13 Aug 2025 20:56:20 +0200 Subject: [PATCH 1/7] Migrate to SimpleWaypoints --- build.gradle | 1 + gradle.properties | 1 + .../clientcommands/ClientCommands.java | 55 ++- .../command/WaypointCommand.java | 428 ------------------ .../assets/clientcommands/lang/en_us.json | 9 - .../assets/clientcommands/lang/zh_cn.json | 9 - src/main/resources/clientcommands.aw | 4 - .../test/WaypointLoadingTest.java | 58 --- 8 files changed, 55 insertions(+), 510 deletions(-) delete mode 100644 src/main/java/net/earthcomputer/clientcommands/command/WaypointCommand.java delete mode 100644 src/test/java/net/earthcomputer/clientcommands/test/WaypointLoadingTest.java diff --git a/build.gradle b/build.gradle index dad92e19..2d2fd4a8 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,7 @@ dependencies { include modImplementation("dev.xpple:clientarguments:${project.clientarguments_version}") include modImplementation("dev.xpple:betterconfig-fabric:${project.betterconfig_version}") + include modImplementation("dev.xpple:simplewaypoints:${project.simplewaypoints_version}") includedLibrary "com.seedfinding:mc_feature:${project.seedfinding_feature_version}" includedLibrary "com.seedfinding:mc_biome:${project.seedfinding_biome_version}" diff --git a/gradle.properties b/gradle.properties index 60b38803..7c5ce394 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,6 +24,7 @@ org.gradle.jvmargs=-Xmx2G fabric_version=0.129.0+1.21.8 clientarguments_version=1.11.3 betterconfig_version=2.4.0 + simplewaypoints_version=1.0.0-alpha.1 seedfinding_core_version=1.210.0 seedfinding_biome_version=1.171.1 seedfinding_feature_version=1.171.10 diff --git a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java index 47a1ed1c..f4ed2a0c 100644 --- a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java +++ b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java @@ -7,6 +7,7 @@ import com.mojang.logging.LogUtils; import dev.xpple.betterconfig.api.BetterConfigAPI; import dev.xpple.betterconfig.api.ModConfigBuilder; +import dev.xpple.simplewaypoints.SimpleWaypoints; import net.earthcomputer.clientcommands.command.*; import net.earthcomputer.clientcommands.event.ClientConnectionEvents; import net.earthcomputer.clientcommands.features.CommandExecutionCustomPayload; @@ -25,11 +26,14 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.Minecraft; import net.minecraft.commands.CommandBuildContext; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; import org.slf4j.Logger; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.Calendar; import java.util.HashSet; import java.util.Set; @@ -63,6 +67,8 @@ public void onInitializeClient() { LOGGER.error("Failed to create config dir", e); } + migrateWaypoints(); + new ModConfigBuilder<>("clientcommands", Configs.class).build(); ClientConnectionEvents.DISCONNECT.register(() -> { if (!Relogger.isRelogging) { @@ -82,7 +88,53 @@ public void onInitializeClient() { FishingCracker.registerEvents(); PlayerRandCracker.registerEvents(); ServerBrandManager.registerEvents(); - WaypointCommand.registerEvents(); + } + + private static void migrateWaypoints() { + Path clientcommandsWaypointsPath = CONFIG_DIR.resolve("waypoints.dat"); + if (!Files.isRegularFile(clientcommandsWaypointsPath)) { + return; // nothing to migrate, or migration already done + } + LOGGER.info("clientcommands' waypoints.dat file detected, will be migrated to SimpleWaypoints"); + Path clientcommandsOldWaypointsPath = CONFIG_DIR.resolve("waypoints.dat_old"); + boolean deleteOld; + try { + Files.copy(clientcommandsWaypointsPath, clientcommandsOldWaypointsPath, StandardCopyOption.REPLACE_EXISTING); + deleteOld = true; + } catch (IOException e) { + LOGGER.error("Could not back up waypoints.dat file", e); + deleteOld = false; + } + Path simplewaypointsWaypointsPath = SimpleWaypoints.MOD_CONFIG_PATH.resolve("waypoints.dat"); + if (Files.isRegularFile(simplewaypointsWaypointsPath)) { + LOGGER.info("SimpleWaypoints' waypoints.dat file already exists, clientcommands' waypoints.dat file will be merged"); + try { + CompoundTag clientcommandsCompoundTag = NbtIo.read(clientcommandsWaypointsPath); + CompoundTag simplewaypointsCompoundTag = NbtIo.read(simplewaypointsWaypointsPath); + if (clientcommandsCompoundTag == null || simplewaypointsCompoundTag == null) { + throw new IOException("Could not parse clientcommands' or SimpleWaypoints' waypoint.dat file"); + } + simplewaypointsCompoundTag.merge(clientcommandsCompoundTag); + NbtIo.write(simplewaypointsCompoundTag, simplewaypointsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not merge waypoints.dat file", e); + } + } else { + LOGGER.info("SimpleWaypoints' waypoints.dat does not exist yet, clientcommands' waypoints.dat file will be copied"); + try { + Files.copy(clientcommandsWaypointsPath, simplewaypointsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not migrate waypoints.dat file", e); + } + } + if (deleteOld) { + LOGGER.info("clientcommands's waypoint.dat will be deleted, waypoints.dat_old is kept"); + try { + Files.delete(clientcommandsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not delete waypoints.dat file during migration", e); + } + } } private static void setupScrambleWindowTitle() { @@ -186,7 +238,6 @@ public static void registerCommands(CommandDispatcher UsageTreeCommand.register(dispatcher); UuidCommand.register(dispatcher); VarCommand.register(dispatcher); - WaypointCommand.register(dispatcher); WeatherCommand.register(dispatcher); WhisperEncryptedCommand.register(dispatcher); WikiCommand.register(dispatcher); diff --git a/src/main/java/net/earthcomputer/clientcommands/command/WaypointCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/WaypointCommand.java deleted file mode 100644 index 50415b2d..00000000 --- a/src/main/java/net/earthcomputer/clientcommands/command/WaypointCommand.java +++ /dev/null @@ -1,428 +0,0 @@ -package net.earthcomputer.clientcommands.command; - -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import com.mojang.logging.LogUtils; -import com.mojang.serialization.Dynamic; -import net.earthcomputer.clientcommands.ClientCommands; -import net.earthcomputer.clientcommands.event.MoreWorldRenderEvents; -import net.earthcomputer.clientcommands.render.RenderQueue; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry; -import net.minecraft.ChatFormatting; -import net.minecraft.SharedConstants; -import net.minecraft.Util; -import net.minecraft.client.Camera; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.multiplayer.ClientChunkCache; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.ShapeRenderer; -import net.minecraft.commands.SharedSuggestionProvider; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.ClickEvent; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentUtils; -import net.minecraft.network.chat.HoverEvent; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.VisibleForTesting; -import org.joml.Vector2d; -import org.slf4j.Logger; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static com.mojang.brigadier.arguments.BoolArgumentType.*; -import static com.mojang.brigadier.arguments.StringArgumentType.*; -import static dev.xpple.clientarguments.arguments.CBlockPosArgument.*; -import static dev.xpple.clientarguments.arguments.CDimensionArgument.*; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; - -public class WaypointCommand { - private static final ResourceLocation HUD_LAYER_ID = ResourceLocation.fromNamespaceAndPath("clientcommands", "waypoints"); - - private static final Map> waypoints = new HashMap<>(); - - private static final Logger LOGGER = LogUtils.getLogger(); - - private static final SimpleCommandExceptionType SAVE_FAILED_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cwaypoint.saveFailed")); - private static final DynamicCommandExceptionType ALREADY_EXISTS_EXCEPTION = new DynamicCommandExceptionType(name -> Component.translatable("commands.cwaypoint.alreadyExists", name)); - private static final DynamicCommandExceptionType NOT_FOUND_EXCEPTION = new DynamicCommandExceptionType(name -> Component.translatable("commands.cwaypoint.notFound", name)); - - static { - try { - loadFile(); - } catch (Exception e) { - LOGGER.error("Could not load waypoints file, hence /cwaypoint will not work!", e); - } - } - - public static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("cwaypoint") - .then(literal("add") - .then(argument("name", word()) - .then(argument("pos", blockPos()) - .executes(ctx -> add(ctx.getSource(), getString(ctx, "name"), getBlockPos(ctx, "pos"))) - .then(argument("dimension", dimension()) - .executes(ctx -> add(ctx.getSource(), getString(ctx, "name"), getBlockPos(ctx, "pos"), getDimension(ctx, "dimension"))))))) - .then(literal("remove") - .then(argument("name", word()) - .suggests((ctx, builder) -> { - Map worldWaypoints = waypoints.get(getWorldIdentifier(ctx.getSource().getClient())); - return SharedSuggestionProvider.suggest(worldWaypoints != null ? worldWaypoints.keySet() : Collections.emptySet(), builder); - }) - .executes(ctx -> remove(ctx.getSource(), getString(ctx, "name"))))) - .then(literal("edit") - .then(argument("name", word()) - .suggests((ctx, builder) -> { - Map worldWaypoints = waypoints.get(getWorldIdentifier(ctx.getSource().getClient())); - return SharedSuggestionProvider.suggest(worldWaypoints != null ? worldWaypoints.keySet() : Collections.emptySet(), builder); - }) - .then(argument("pos", blockPos()) - .executes(ctx -> edit(ctx.getSource(), getString(ctx, "name"), getBlockPos(ctx, "pos"))) - .then(argument("dimension", dimension()) - .executes(ctx -> edit(ctx.getSource(), getString(ctx, "name"), getBlockPos(ctx, "pos"), getDimension(ctx, "dimension"))))))) - .then(literal("list") - .executes(ctx -> list(ctx.getSource())) - .then(argument("current", bool()) - .executes(ctx -> list(ctx.getSource(), getBool(ctx, "current")))))); - } - - private static String getWorldIdentifier(Minecraft minecraft) { - String worldIdentifier; - if (minecraft.hasSingleplayerServer()) { - // the level id remains the same even after the level is renamed - worldIdentifier = minecraft.getSingleplayerServer().storageSource.getLevelId(); - } else { - worldIdentifier = minecraft.getConnection().getConnection().getRemoteAddress().toString(); - } - return worldIdentifier; - } - - private static int add(FabricClientCommandSource source, String name, BlockPos pos) throws CommandSyntaxException { - return add(source, name, pos, source.getWorld().dimension()); - } - - private static int add(FabricClientCommandSource source, String name, BlockPos pos, ResourceKey dimension) throws CommandSyntaxException { - String worldIdentifier = getWorldIdentifier(source.getClient()); - - Map worldWaypoints = waypoints.computeIfAbsent(worldIdentifier, key -> new HashMap<>()); - - if (worldWaypoints.putIfAbsent(name, new WaypointLocation(dimension, pos)) != null) { - throw ALREADY_EXISTS_EXCEPTION.create(name); - } - - saveFile(); - source.sendFeedback(Component.translatable("commands.cwaypoint.add.success", name, formatCoordinates(pos), dimension.location())); - return Command.SINGLE_SUCCESS; - } - - private static int remove(FabricClientCommandSource source, String name) throws CommandSyntaxException { - String worldIdentifier = getWorldIdentifier(source.getClient()); - - Map worldWaypoints = waypoints.get(worldIdentifier); - - if (worldWaypoints == null) { - throw NOT_FOUND_EXCEPTION.create(name); - } - - if (worldWaypoints.remove(name) == null) { - throw NOT_FOUND_EXCEPTION.create(name); - } - - saveFile(); - source.sendFeedback(Component.translatable("commands.cwaypoint.remove.success", name)); - return Command.SINGLE_SUCCESS; - } - - private static int edit(FabricClientCommandSource source, String name, BlockPos pos) throws CommandSyntaxException { - return edit(source, name, pos, source.getWorld().dimension()); - } - - private static int edit(FabricClientCommandSource source, String name, BlockPos pos, ResourceKey dimension) throws CommandSyntaxException { - String worldIdentifier = getWorldIdentifier(source.getClient()); - - Map worldWaypoints = waypoints.get(worldIdentifier); - - if (worldWaypoints == null) { - throw NOT_FOUND_EXCEPTION.create(name); - } - - if (worldWaypoints.computeIfPresent(name, (key, value) -> new WaypointLocation(dimension, pos)) == null) { - throw NOT_FOUND_EXCEPTION.create(name); - } - - saveFile(); - source.sendFeedback(Component.translatable("commands.cwaypoint.edit.success", name, formatCoordinates(pos), dimension.location())); - return Command.SINGLE_SUCCESS; - } - - private static int list(FabricClientCommandSource source) { - return list(source, false); - } - - private static int list(FabricClientCommandSource source, boolean current) { - if (current) { - String worldIdentifier = getWorldIdentifier(source.getClient()); - - Map worldWaypoints = waypoints.get(worldIdentifier); - - if (worldWaypoints == null || worldWaypoints.isEmpty()) { - source.sendFeedback(Component.translatable("commands.cwaypoint.list.empty")); - return 0; - } - - worldWaypoints.forEach((name, waypoint) -> source.sendFeedback(Component.translatable("commands.cwaypoint.list", name, formatCoordinates(waypoint.location()), waypoint.dimension().location()))); - return worldWaypoints.size(); - } - - if (waypoints.isEmpty()) { - source.sendFeedback(Component.translatable("commands.cwaypoint.list.empty")); - return 0; - } - - int[] count = {0}; - waypoints.forEach((worldIdentifier, worldWaypoints) -> { - if (worldWaypoints.isEmpty()) { - return; - } - - count[0] += worldWaypoints.size(); - - source.sendFeedback(Component.literal(worldIdentifier).append(":")); - worldWaypoints.forEach((name, waypoint) -> source.sendFeedback(Component.translatable("commands.cwaypoint.list", name, formatCoordinates(waypoint.location()), waypoint.dimension().location()))); - }); - return count[0]; - } - - private static void saveFile() throws CommandSyntaxException { - try { - CompoundTag rootTag = new CompoundTag(); - rootTag.putInt("DataVersion", SharedConstants.getCurrentVersion().dataVersion().version()); - CompoundTag compoundTag = new CompoundTag(); - waypoints.forEach((worldIdentifier, worldWaypoints) -> compoundTag.put(worldIdentifier, worldWaypoints.entrySet().stream() - .collect(CompoundTag::new, (result, entry) -> { - CompoundTag waypoint = new CompoundTag(); - waypoint.store("pos", BlockPos.CODEC, entry.getValue().location()); - String dimension = entry.getValue().dimension().location().toString(); - waypoint.putString("Dimension", dimension); - result.put(entry.getKey(), waypoint); - }, CompoundTag::merge))); - rootTag.put("Waypoints", compoundTag); - Path newFile = Files.createTempFile(ClientCommands.CONFIG_DIR, "waypoints", ".dat"); - NbtIo.write(rootTag, newFile); - Path backupFile = ClientCommands.CONFIG_DIR.resolve("waypoints.dat_old"); - Path currentFile = ClientCommands.CONFIG_DIR.resolve("waypoints.dat"); - Util.safeReplaceFile(currentFile, newFile, backupFile); - } catch (IOException e) { - throw SAVE_FAILED_EXCEPTION.create(); - } - } - - private static void loadFile() throws Exception { - waypoints.clear(); - CompoundTag rootTag = NbtIo.read(ClientCommands.CONFIG_DIR.resolve("waypoints.dat")); - if (rootTag == null) { - return; - } - waypoints.putAll(deserializeWaypoints(rootTag)); - } - - @VisibleForTesting - public static Map> deserializeWaypoints(CompoundTag rootTag) { - Map> waypoints = new HashMap<>(); - - CompoundTag compoundTag = rootTag.getCompoundOrEmpty("Waypoints"); - compoundTag.keySet().forEach(worldIdentifier -> { - CompoundTag worldWaypoints = compoundTag.getCompoundOrEmpty(worldIdentifier); - waypoints.put(worldIdentifier, worldWaypoints.keySet().stream() - .collect(Collectors.toMap(Function.identity(), name -> { - CompoundTag waypoint = worldWaypoints.getCompoundOrEmpty(name); - BlockPos pos = waypoint.read("pos", BlockPos.CODEC).orElseThrow(); - ResourceKey dimension = Level.RESOURCE_KEY_CODEC.parse(new Dynamic<>(NbtOps.INSTANCE, waypoint.get("Dimension"))).resultOrPartial(LOGGER::error).orElseThrow(); - return new WaypointLocation(dimension, pos); - }))); - }); - - return waypoints; - } - - private static Component formatCoordinates(BlockPos waypoint) { - return ComponentUtils.wrapInSquareBrackets(Component.literal(waypoint.toShortString())).withStyle(style -> style - .withColor(ChatFormatting.GREEN) - .withClickEvent(new ClickEvent.CopyToClipboard(waypoint.getX() + " " + waypoint.getY() + " " + waypoint.getZ())) - .withHoverEvent(new HoverEvent.ShowText(Component.translatable("chat.copy.click"))) - ); - } - - public static void registerEvents() { - HudElementRegistry.addLast(HUD_LAYER_ID, WaypointCommand::renderWaypointLabels); - MoreWorldRenderEvents.END_MAIN_PASS.register(WaypointCommand::renderWaypointBoxes); - } - - private static void renderWaypointLabels(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { - String worldIdentifier = getWorldIdentifier(Minecraft.getInstance()); - Map waypoints = WaypointCommand.waypoints.get(worldIdentifier); - if (waypoints == null) { - return; - } - - Minecraft minecraft = Minecraft.getInstance(); - GameRenderer gameRenderer = minecraft.gameRenderer; - Camera camera = gameRenderer.getMainCamera(); - Entity cameraEntity = camera.getEntity(); - float partialTicks = deltaTracker.getGameTimeDeltaPartialTick(true); - double verticalFovRad = Math.toRadians(gameRenderer.getFov(camera, partialTicks, false)); - Window window = minecraft.getWindow(); - double aspectRatio = (double) window.getGuiScaledWidth() / window.getGuiScaledHeight(); - double horizontalFovRad = 2 * Math.atan(Math.tan(verticalFovRad / 2) * aspectRatio); - - Vec3 viewVector3 = cameraEntity.getViewVector(1.0f); - Vector2d viewVector = new Vector2d(viewVector3.x, viewVector3.z); - Vector2d position = new Vector2d(cameraEntity.getEyePosition().x, cameraEntity.getEyePosition().z); - - List xPositions = new ArrayList<>(); - waypoints.forEach((waypointName, waypoint) -> { - if (!waypoint.dimension().location().equals(minecraft.level.dimension().location())) { - return; - } - - double distanceSquared = waypoint.location().distToCenterSqr(cameraEntity.position()); - long distance = Math.round(Math.sqrt(distanceSquared)); - Component label = ComponentUtils.wrapInSquareBrackets(Component.literal(waypointName + ' ' + distance).withStyle(ChatFormatting.YELLOW)); - - Vector2d waypointLocation = new Vector2d(waypoint.location().getX(), waypoint.location().getZ()); - double angleRad = viewVector.angle(waypointLocation.sub(position, new Vector2d())); - boolean right = angleRad > 0; - angleRad = Math.abs(angleRad); - - int x; - if (angleRad > horizontalFovRad / 2) { - int width = minecraft.font.width(label); - x = right ? guiGraphics.guiWidth() - width / 2 : width / 2; - } else { - // V is the view vector - // A is the leftmost visible direction - // B is the rightmost visible direction - // M is the intersection of the position -> waypoint line with AB - double mv = Math.tan(angleRad) * GameRenderer.PROJECTION_Z_NEAR; - double av = Math.tan(horizontalFovRad / 2) * GameRenderer.PROJECTION_Z_NEAR; - double ab = 2 * av; - double am = right ? mv + av : ab - (mv + av); - double perc = am / ab; - x = (int) (perc * guiGraphics.guiWidth()); - } - xPositions.add(new WaypointLabelLocation(label, x)); - }); - - xPositions.sort(Comparator.comparingInt(WaypointLabelLocation::location)); - - List> positions = new ArrayList<>(); - positions.add(xPositions); - - for (int line = 0; line < positions.size(); line++) { - List waypointLabelLocations = positions.get(line); - int i = 0; - while (i < waypointLabelLocations.size() - 1) { - WaypointLabelLocation left = waypointLabelLocations.get(i); - WaypointLabelLocation right = waypointLabelLocations.get(i + 1); - int leftX = left.location(); - int rightX = right.location(); - int leftWidth = minecraft.font.width(left.label()); - int rightWidth = minecraft.font.width(right.label()); - if (leftWidth / 2 + rightWidth / 2 > rightX - leftX) { - if (line + 1 == positions.size()) { - positions.add(new ArrayList<>()); - } - List nextLevel = positions.get(line + 1); - WaypointLabelLocation removed = waypointLabelLocations.remove(i + 1); - nextLevel.add(removed); - } else { - i++; - } - } - } - - for (int line = 0; line < positions.size(); line++) { - List w = positions.get(line); - for (WaypointLabelLocation waypoint : w) { - guiGraphics.drawCenteredString(minecraft.font, waypoint.label(), waypoint.location(), 1 + line * minecraft.font.lineHeight, 0xFFFFFFFF); - } - } - } - - private static void renderWaypointBoxes(WorldRenderContext context) { - String worldIdentifier = getWorldIdentifier(Minecraft.getInstance()); - Map waypoints = WaypointCommand.waypoints.get(worldIdentifier); - if (waypoints == null) { - return; - } - - ClientChunkCache chunkSource = context.world().getChunkSource(); - waypoints.forEach((waypointName, waypoint) -> { - if (!waypoint.dimension().location().equals(context.world().dimension().location())) { - return; - } - - BlockPos waypointLocation = waypoint.location(); - if (!chunkSource.hasChunk(waypointLocation.getX() >> 4, waypointLocation.getZ() >> 4)) { - return; - } - - Vec3 cameraPosition = context.camera().getPosition(); - float distance = (float) waypointLocation.distToCenterSqr(cameraPosition); - distance = (float) Math.sqrt(distance) / 6; - - PoseStack stack = context.matrixStack(); - stack.pushPose(); - stack.translate(cameraPosition.scale(-1)); - - AABB box = new AABB(waypointLocation); - ShapeRenderer.renderLineBox(stack, context.consumers().getBuffer(RenderQueue.LINES_NO_DEPTH_LAYER), box, 1, 1, 1, 1); - - stack.translate(waypointLocation.getCenter().add(new Vec3(0, 1, 0))); - stack.mulPose(context.camera().rotation()); - stack.scale(0.025f * distance, -0.025f * distance, 0.025f * distance); - - Font font = Minecraft.getInstance().font; - int width = font.width(waypointName) / 2; - int backgroundColour = (int) (Minecraft.getInstance().options.getBackgroundOpacity(0.25f) * 255.0f) << 24; - font.drawInBatch(waypointName, -width, 0, 0xFFFFFFFF, false, stack.last().pose(), context.consumers(), Font.DisplayMode.SEE_THROUGH, backgroundColour, LightTexture.FULL_SKY); - - stack.popPose(); - }); - } - - @VisibleForTesting - public record WaypointLocation(ResourceKey dimension, BlockPos location) { - } - - record WaypointLabelLocation(Component label, int location) { - } -} diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index c3b29cdb..bf836e5f 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -301,15 +301,6 @@ "commands.cvar.remove.success": "Successfully removed variable \"%s\"", "commands.cvar.saveFile.failed": "Could not save variables file", - "commands.cwaypoint.add.success": "Waypoint \"%s\" at %s in %s successfully added", - "commands.cwaypoint.alreadyExists": "A waypoint with the name \"%s\" already exists", - "commands.cwaypoint.edit.success": "Waypoint \"%s\" has successfully been changed to %s in %s", - "commands.cwaypoint.list": "- \"%s\" at %s in %s", - "commands.cwaypoint.list.empty": "No available waypoints", - "commands.cwaypoint.notFound": "No waypoint with the name \"%s\" could be found", - "commands.cwaypoint.remove.success": "Waypoint \"%s\" successfully removed", - "commands.cwaypoint.saveFailed": "Could not save waypoints file", - "commands.cwe.playerNotFound": "Player not found", "commands.cweather.reset": "Stopped overriding weather", diff --git a/src/main/resources/assets/clientcommands/lang/zh_cn.json b/src/main/resources/assets/clientcommands/lang/zh_cn.json index 12005cdf..d73e14f0 100644 --- a/src/main/resources/assets/clientcommands/lang/zh_cn.json +++ b/src/main/resources/assets/clientcommands/lang/zh_cn.json @@ -301,15 +301,6 @@ "commands.cvar.remove.success": "成功删除变量“%s”", "commands.cvar.saveFile.failed": "无法保存变量文件", - "commands.cwaypoint.add.success": "成功添加导航点“%s”位于%s在%s", - "commands.cwaypoint.alreadyExists": "名称为“%s”的导航点已经存在", - "commands.cwaypoint.edit.success": "导航点“%s”已成功修改到%s在%s", - "commands.cwaypoint.list": "- “%s”位于%s在%s", - "commands.cwaypoint.list.empty": "没有可用的导航点", - "commands.cwaypoint.notFound": "找不到名称为“%s”的导航点", - "commands.cwaypoint.remove.success": "导航点“%s”已被移除", - "commands.cwaypoint.saveFailed": "无法保存导航点文件", - "commands.cwe.playerNotFound": "未找到玩家", "commands.cweather.reset": "停止天气覆盖", diff --git a/src/main/resources/clientcommands.aw b/src/main/resources/clientcommands.aw index 6f90b18f..04168320 100644 --- a/src/main/resources/clientcommands.aw +++ b/src/main/resources/clientcommands.aw @@ -44,10 +44,6 @@ accessible method net/minecraft/client/Screenshot getFile (Ljava/io/File;)Ljava/ # cpermissionlevel accessible method net/minecraft/client/player/LocalPlayer getPermissionLevel ()I -# cwaypoint -accessible field net/minecraft/server/MinecraftServer storageSource Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess; -accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F - # Game Options accessible field net/minecraft/client/OptionInstance value Ljava/lang/Object; diff --git a/src/test/java/net/earthcomputer/clientcommands/test/WaypointLoadingTest.java b/src/test/java/net/earthcomputer/clientcommands/test/WaypointLoadingTest.java deleted file mode 100644 index f6522609..00000000 --- a/src/test/java/net/earthcomputer/clientcommands/test/WaypointLoadingTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.earthcomputer.clientcommands.test; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.earthcomputer.clientcommands.command.WaypointCommand; -import net.minecraft.SharedConstants; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.TagParser; -import net.minecraft.server.Bootstrap; -import net.minecraft.world.level.Level; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public final class WaypointLoadingTest { - @BeforeAll - public static void setup() { - SharedConstants.tryDetectVersion(); - Bootstrap.bootStrap(); - } - - private static CompoundTag parseSnbt(String snbt) { - try { - return TagParser.parseCompoundAsArgument(new StringReader(snbt)); - } catch (CommandSyntaxException e) { - throw new AssertionError(e); - } - } - - @Test - public void testWaypointLoading() { - CompoundTag waypointTag = parseSnbt(""" - { - DataVersion: 4189, - Waypoints: { - foo: { - testWaypoint: { - pos: [I; 1, 2, 3], - Dimension: "minecraft:overworld" - } - } - } - } - """); - - var waypoints = WaypointCommand.deserializeWaypoints(waypointTag); - assertEquals(1, waypoints.size()); - assertTrue(waypoints.containsKey("foo")); - var worldWaypoints = waypoints.get("foo"); - assertEquals(1, worldWaypoints.size()); - assertTrue(worldWaypoints.containsKey("testWaypoint")); - var waypoint = worldWaypoints.get("testWaypoint"); - assertEquals(new BlockPos(1, 2, 3), waypoint.location()); - assertEquals(Level.OVERWORLD, waypoint.dimension()); - } -} From 814c7f627fee6e386e2db0ac8f86f8c1e8139606 Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Wed, 13 Aug 2025 21:16:08 +0200 Subject: [PATCH 2/7] Restore /cwaypoint command --- gradle.properties | 2 +- .../simplewaypoints/WaypointCommandMixin.java | 21 +++++++++++++++++++ src/main/resources/mixins.clientcommands.json | 3 ++- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java diff --git a/gradle.properties b/gradle.properties index 7c5ce394..4ce98e7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ org.gradle.jvmargs=-Xmx2G fabric_version=0.129.0+1.21.8 clientarguments_version=1.11.3 betterconfig_version=2.4.0 - simplewaypoints_version=1.0.0-alpha.1 + simplewaypoints_version=1.0.0-alpha.2 seedfinding_core_version=1.210.0 seedfinding_biome_version=1.171.1 seedfinding_feature_version=1.171.10 diff --git a/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java b/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java new file mode 100644 index 00000000..61b5e9d6 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java @@ -0,0 +1,21 @@ +package net.earthcomputer.clientcommands.mixin.simplewaypoints; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.tree.CommandNode; +import dev.xpple.simplewaypoints.commands.WaypointCommand; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; + +@Mixin(WaypointCommand.class) +public class WaypointCommandMixin { + @Inject(method = "register", at = @At("TAIL"), remap = false) + private static void registerWaypointCommandAlias(CommandDispatcher dispatcher, CallbackInfo ci) { + CommandNode configRoot = dispatcher.getRoot().getChild("sw:waypoint"); + dispatcher.register(literal("cwaypoint").redirect(configRoot)); + } +} diff --git a/src/main/resources/mixins.clientcommands.json b/src/main/resources/mixins.clientcommands.json index 8dcd787d..37dbb74a 100644 --- a/src/main/resources/mixins.clientcommands.json +++ b/src/main/resources/mixins.clientcommands.json @@ -54,7 +54,8 @@ "rngevents.droppableinventory.ItemCombinerMenuMixin", "rngevents.droppableinventory.LoomMenuMixin", "rngevents.droppableinventory.MerchantMenuMixin", - "rngevents.droppableinventory.StonecutterMenuMixin" + "rngevents.droppableinventory.StonecutterMenuMixin", + "simplewaypoints.WaypointCommandMixin" ], "injectors": { "defaultRequire": 1 From b2752a506d2d4fcac1421e07e58e2b4ecd504d6b Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Thu, 14 Aug 2025 15:36:15 +0200 Subject: [PATCH 3/7] Implement requested changes --- build.gradle | 1 + gradle.properties | 2 +- .../clientcommands/ClientCommands.java | 58 ++-------------- .../clientcommands/features/Waypoints.java | 67 +++++++++++++++++++ .../simplewaypoints/WaypointCommandMixin.java | 21 ------ src/main/resources/mixins.clientcommands.json | 3 +- 6 files changed, 75 insertions(+), 77 deletions(-) create mode 100644 src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java delete mode 100644 src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java diff --git a/build.gradle b/build.gradle index 2d2fd4a8..825dff56 100644 --- a/build.gradle +++ b/build.gradle @@ -182,6 +182,7 @@ modrinth { dependencies { required.project 'fabric-api' embedded.project 'betterconfig' + embedded.project 'simplewaypoints' } } tasks.modrinth.onlyIf { diff --git a/gradle.properties b/gradle.properties index 4ce98e7a..89f65e63 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ org.gradle.jvmargs=-Xmx2G fabric_version=0.129.0+1.21.8 clientarguments_version=1.11.3 betterconfig_version=2.4.0 - simplewaypoints_version=1.0.0-alpha.2 + simplewaypoints_version=1.0.0-alpha.3 seedfinding_core_version=1.210.0 seedfinding_biome_version=1.171.1 seedfinding_feature_version=1.171.10 diff --git a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java index f4ed2a0c..5fd8593e 100644 --- a/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java +++ b/src/main/java/net/earthcomputer/clientcommands/ClientCommands.java @@ -7,7 +7,7 @@ import com.mojang.logging.LogUtils; import dev.xpple.betterconfig.api.BetterConfigAPI; import dev.xpple.betterconfig.api.ModConfigBuilder; -import dev.xpple.simplewaypoints.SimpleWaypoints; +import dev.xpple.simplewaypoints.api.SimpleWaypointsAPI; import net.earthcomputer.clientcommands.command.*; import net.earthcomputer.clientcommands.event.ClientConnectionEvents; import net.earthcomputer.clientcommands.features.CommandExecutionCustomPayload; @@ -16,6 +16,7 @@ import net.earthcomputer.clientcommands.features.PlayerRandCracker; import net.earthcomputer.clientcommands.features.Relogger; import net.earthcomputer.clientcommands.features.ServerBrandManager; +import net.earthcomputer.clientcommands.features.Waypoints; import net.earthcomputer.clientcommands.render.RenderQueue; import net.earthcomputer.clientcommands.util.MappingsHelper; import net.fabricmc.api.ClientModInitializer; @@ -26,14 +27,11 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.Minecraft; import net.minecraft.commands.CommandBuildContext; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; import org.slf4j.Logger; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.Calendar; import java.util.HashSet; import java.util.Set; @@ -67,8 +65,6 @@ public void onInitializeClient() { LOGGER.error("Failed to create config dir", e); } - migrateWaypoints(); - new ModConfigBuilder<>("clientcommands", Configs.class).build(); ClientConnectionEvents.DISCONNECT.register(() -> { if (!Relogger.isRelogging) { @@ -76,6 +72,9 @@ public void onInitializeClient() { } }); + Waypoints.migrateWaypoints(); + SimpleWaypointsAPI.getInstance().registerCommandAlias("cwaypoint"); + MappingsHelper.load(); // Registration @@ -90,53 +89,6 @@ public void onInitializeClient() { ServerBrandManager.registerEvents(); } - private static void migrateWaypoints() { - Path clientcommandsWaypointsPath = CONFIG_DIR.resolve("waypoints.dat"); - if (!Files.isRegularFile(clientcommandsWaypointsPath)) { - return; // nothing to migrate, or migration already done - } - LOGGER.info("clientcommands' waypoints.dat file detected, will be migrated to SimpleWaypoints"); - Path clientcommandsOldWaypointsPath = CONFIG_DIR.resolve("waypoints.dat_old"); - boolean deleteOld; - try { - Files.copy(clientcommandsWaypointsPath, clientcommandsOldWaypointsPath, StandardCopyOption.REPLACE_EXISTING); - deleteOld = true; - } catch (IOException e) { - LOGGER.error("Could not back up waypoints.dat file", e); - deleteOld = false; - } - Path simplewaypointsWaypointsPath = SimpleWaypoints.MOD_CONFIG_PATH.resolve("waypoints.dat"); - if (Files.isRegularFile(simplewaypointsWaypointsPath)) { - LOGGER.info("SimpleWaypoints' waypoints.dat file already exists, clientcommands' waypoints.dat file will be merged"); - try { - CompoundTag clientcommandsCompoundTag = NbtIo.read(clientcommandsWaypointsPath); - CompoundTag simplewaypointsCompoundTag = NbtIo.read(simplewaypointsWaypointsPath); - if (clientcommandsCompoundTag == null || simplewaypointsCompoundTag == null) { - throw new IOException("Could not parse clientcommands' or SimpleWaypoints' waypoint.dat file"); - } - simplewaypointsCompoundTag.merge(clientcommandsCompoundTag); - NbtIo.write(simplewaypointsCompoundTag, simplewaypointsWaypointsPath); - } catch (IOException e) { - LOGGER.error("Could not merge waypoints.dat file", e); - } - } else { - LOGGER.info("SimpleWaypoints' waypoints.dat does not exist yet, clientcommands' waypoints.dat file will be copied"); - try { - Files.copy(clientcommandsWaypointsPath, simplewaypointsWaypointsPath); - } catch (IOException e) { - LOGGER.error("Could not migrate waypoints.dat file", e); - } - } - if (deleteOld) { - LOGGER.info("clientcommands's waypoint.dat will be deleted, waypoints.dat_old is kept"); - try { - Files.delete(clientcommandsWaypointsPath); - } catch (IOException e) { - LOGGER.error("Could not delete waypoints.dat file during migration", e); - } - } - } - private static void setupScrambleWindowTitle() { // can't set this up during class initializer, because Minecraft.getInstance() is null during automated tests String playerUUID = String.valueOf(Minecraft.getInstance().getUser().getProfileId()); diff --git a/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java b/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java new file mode 100644 index 00000000..f794b016 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java @@ -0,0 +1,67 @@ +package net.earthcomputer.clientcommands.features; + +import com.mojang.logging.LogUtils; +import dev.xpple.simplewaypoints.SimpleWaypoints; +import net.earthcomputer.clientcommands.ClientCommands; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import org.slf4j.Logger; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +public final class Waypoints { + private Waypoints() { + } + + private static final Logger LOGGER = LogUtils.getLogger(); + + public static void migrateWaypoints() { + Path clientcommandsWaypointsPath = ClientCommands.CONFIG_DIR.resolve("waypoints.dat"); + if (!Files.isRegularFile(clientcommandsWaypointsPath)) { + return; // nothing to migrate, or migration already done + } + LOGGER.info("clientcommands' waypoints.dat file detected, will be migrated to SimpleWaypoints"); + Path clientcommandsOldWaypointsPath = ClientCommands.CONFIG_DIR.resolve("waypoints.dat_old"); + boolean deleteOld; + try { + Files.copy(clientcommandsWaypointsPath, clientcommandsOldWaypointsPath, StandardCopyOption.REPLACE_EXISTING); + deleteOld = true; + } catch (IOException e) { + LOGGER.error("Could not back up waypoints.dat file", e); + deleteOld = false; + } + Path simplewaypointsWaypointsPath = SimpleWaypoints.MOD_CONFIG_PATH.resolve("waypoints.dat"); + if (Files.isRegularFile(simplewaypointsWaypointsPath)) { + LOGGER.info("SimpleWaypoints' waypoints.dat file already exists, clientcommands' waypoints.dat file will be merged"); + try { + CompoundTag clientcommandsCompoundTag = NbtIo.read(clientcommandsWaypointsPath); + CompoundTag simplewaypointsCompoundTag = NbtIo.read(simplewaypointsWaypointsPath); + if (clientcommandsCompoundTag == null || simplewaypointsCompoundTag == null) { + throw new IOException("Could not parse clientcommands' or SimpleWaypoints' waypoint.dat file"); + } + simplewaypointsCompoundTag.merge(clientcommandsCompoundTag); + NbtIo.write(simplewaypointsCompoundTag, simplewaypointsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not merge waypoints.dat file", e); + } + } else { + LOGGER.info("SimpleWaypoints' waypoints.dat does not exist yet, clientcommands' waypoints.dat file will be copied"); + try { + Files.copy(clientcommandsWaypointsPath, simplewaypointsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not migrate waypoints.dat file", e); + } + } + if (deleteOld) { + LOGGER.info("clientcommands's waypoint.dat will be deleted, waypoints.dat_old is kept"); + try { + Files.delete(clientcommandsWaypointsPath); + } catch (IOException e) { + LOGGER.error("Could not delete waypoints.dat file during migration", e); + } + } + } +} diff --git a/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java b/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java deleted file mode 100644 index 61b5e9d6..00000000 --- a/src/main/java/net/earthcomputer/clientcommands/mixin/simplewaypoints/WaypointCommandMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.earthcomputer.clientcommands.mixin.simplewaypoints; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.tree.CommandNode; -import dev.xpple.simplewaypoints.commands.WaypointCommand; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; - -@Mixin(WaypointCommand.class) -public class WaypointCommandMixin { - @Inject(method = "register", at = @At("TAIL"), remap = false) - private static void registerWaypointCommandAlias(CommandDispatcher dispatcher, CallbackInfo ci) { - CommandNode configRoot = dispatcher.getRoot().getChild("sw:waypoint"); - dispatcher.register(literal("cwaypoint").redirect(configRoot)); - } -} diff --git a/src/main/resources/mixins.clientcommands.json b/src/main/resources/mixins.clientcommands.json index 37dbb74a..8dcd787d 100644 --- a/src/main/resources/mixins.clientcommands.json +++ b/src/main/resources/mixins.clientcommands.json @@ -54,8 +54,7 @@ "rngevents.droppableinventory.ItemCombinerMenuMixin", "rngevents.droppableinventory.LoomMenuMixin", "rngevents.droppableinventory.MerchantMenuMixin", - "rngevents.droppableinventory.StonecutterMenuMixin", - "simplewaypoints.WaypointCommandMixin" + "rngevents.droppableinventory.StonecutterMenuMixin" ], "injectors": { "defaultRequire": 1 From 489e4cde154e607e8fbe5d9fbc431d0266a2500d Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Thu, 14 Aug 2025 15:39:38 +0200 Subject: [PATCH 4/7] Add SimpleWaypoints to FMJ --- src/main/resources/fabric.mod.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index d1b232e3..b78bff48 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -30,7 +30,8 @@ "fabricloader": ">=0.4.0", "fabric-api": "*", "betterconfig": "*", - "clientarguments": "*" + "clientarguments": "*", + "simplewaypoints": "*" }, "mixins": [ "mixins.clientcommands.json" From 3ca468aa1be868c713e1d1bb576062d68c59b46c Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Thu, 14 Aug 2025 15:48:39 +0200 Subject: [PATCH 5/7] Update dependencies --- gradle.properties | 16 ++++++++-------- gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 45457 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 6 +++--- gradlew.bat | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gradle.properties b/gradle.properties index 89f65e63..fa3ca19a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,12 +7,12 @@ org.gradle.jvmargs=-Xmx2G minecraft_version_dependency=>=1.21.6 <=1.21.8 minecraft_version_list=1.21.6,1.21.7,1.21.8 minecraft_version_list_presentable=1.21.6 - 1.21.8 - loader_version=0.16.14 - loom_version=1.10-SNAPSHOT + loader_version=0.17.2 + loom_version=1.11-SNAPSHOT # check these on https://maven.parchmentmc.org/org/parchmentmc/data/ - parchment_mcversion=1.21.6 - parchment_version=2025.06.29 + parchment_mcversion=1.21.8 + parchment_version=2025.07.20 # Mod Properties mod_version=2.11.3 @@ -21,8 +21,8 @@ org.gradle.jvmargs=-Xmx2G # Dependencies # also check this on https://fabricmc.net/develop/ - fabric_version=0.129.0+1.21.8 - clientarguments_version=1.11.3 + fabric_version=0.131.0+1.21.8 + clientarguments_version=1.11.4 betterconfig_version=2.4.0 simplewaypoints_version=1.0.0-alpha.3 seedfinding_core_version=1.210.0 @@ -32,7 +32,7 @@ org.gradle.jvmargs=-Xmx2G latticg_version=1.07 mapping_io_version=0.7.1 devauth_version=1.2.1 - checkstyle_version=10.26.1 + checkstyle_version=11.0.0 jazzer_junit_version=0.24.0 - junit_version=5.13.2 + junit_version=5.13.4 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9bbc975c742b298b441bfb90dbc124400a3751b9..8bdaf60c75ab801e22807dde59e12a8735a34077 100644 GIT binary patch delta 37253 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 O1weZAmkWQth5iRL@S`^X delta 35492 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 XpD#%!h*(1faI7Gqg* Date: Thu, 14 Aug 2025 17:13:42 +0200 Subject: [PATCH 6/7] Update SimpleWaypoints --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index fa3ca19a..cb6a0861 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ org.gradle.jvmargs=-Xmx2G fabric_version=0.131.0+1.21.8 clientarguments_version=1.11.4 betterconfig_version=2.4.0 - simplewaypoints_version=1.0.0-alpha.3 + simplewaypoints_version=1.0.0-alpha.4 seedfinding_core_version=1.210.0 seedfinding_biome_version=1.171.1 seedfinding_feature_version=1.171.10 From 349eccb4868d1b3210f83f717403ed1815ac72a0 Mon Sep 17 00:00:00 2001 From: Frederik van der Els Date: Sat, 16 Aug 2025 21:34:33 +0200 Subject: [PATCH 7/7] Add some newlines --- .../net/earthcomputer/clientcommands/features/Waypoints.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java b/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java index f794b016..199f5089 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/Waypoints.java @@ -23,6 +23,7 @@ public static void migrateWaypoints() { if (!Files.isRegularFile(clientcommandsWaypointsPath)) { return; // nothing to migrate, or migration already done } + LOGGER.info("clientcommands' waypoints.dat file detected, will be migrated to SimpleWaypoints"); Path clientcommandsOldWaypointsPath = ClientCommands.CONFIG_DIR.resolve("waypoints.dat_old"); boolean deleteOld; @@ -33,6 +34,7 @@ public static void migrateWaypoints() { LOGGER.error("Could not back up waypoints.dat file", e); deleteOld = false; } + Path simplewaypointsWaypointsPath = SimpleWaypoints.MOD_CONFIG_PATH.resolve("waypoints.dat"); if (Files.isRegularFile(simplewaypointsWaypointsPath)) { LOGGER.info("SimpleWaypoints' waypoints.dat file already exists, clientcommands' waypoints.dat file will be merged"); @@ -55,6 +57,7 @@ public static void migrateWaypoints() { LOGGER.error("Could not migrate waypoints.dat file", e); } } + if (deleteOld) { LOGGER.info("clientcommands's waypoint.dat will be deleted, waypoints.dat_old is kept"); try {