Merge Dev to master and UPDATE to v1.5#8
Conversation
…d manage method. Add all new command to whitelist
…d manage method. Add all new command to whitelist
…te waypoint operation.
…agement - Introduced new classes for handling visibility actions and command support for both warp and home functionalities. - Separated mutation actions for warp and home commands into distinct classes for better organization. - Enhanced visibility handling by implementing a generic VisibilityCommandSupport class. - Updated existing warp and home commands to utilize the new structure, improving code readability and maintainability. - Added silent visibility update options for both warp and home commands. - Refactored command execution logic to streamline player interactions and feedback.
There was a problem hiding this comment.
Pull request overview
This PR updates the mod to v1.5 and merges in a large refactor that expands Xaero integration (visibility + deletion/teleport flows), adds “previous teleport” backtracking, and introduces new storage/config migration + autosave behavior.
Changes:
- Added per-player and global Xaero waypoint visibility management for warps/homes (including delete-to-hide behavior and new
/mapwarp,/maphome,/gwarpmapcommands). - Added
/back tpsupport by recording the player’s pre-teleport location and integrating Xaero death-waypoint teleport into/back death. - Refactored commands into dedicated packages/services, and introduced storage/config migration utilities plus periodic autosaving.
Reviewed changes
Copilot reviewed 79 out of 83 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/resources/teleportcommandsfabric.mixins.json | Registers new Xaero delete-related mixins |
| src/main/resources/assets/teleport_commands_fabric/lang/zh_cn.json | Adds new v1.5 translation keys |
| src/main/resources/assets/teleport_commands_fabric/lang/en_us.json | Adds new v1.5 translation keys |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/xaero/XaeroSyncServer.java | Filters synced entries based on visibility + per-player hidden warps |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/utils/WorldResolver.java | Simplifies dimension id resolution |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/utils/TranslationHelper.java | Adds fallback-on-missing-language + placeholder bounds safety |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/utils/TeleportSafety.java | Removes old TeleportSafety from utils |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/utils/CommandHelper.java | Adds shared command-argument quoting helper |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/TeleportCooldownManager.java | Switches cooldown keys to UUID + adds cleanup |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/StorageMigratorUtil.java | New storage migration helper (v3 schema updates) |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/StorageManager.java | Adds dirty tracking + periodic autosave + async IO |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/StorageClass.java | Extracts storage model + adds player cache + cleanup logic |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/PreviousTeleportLocationStorage.java | Stores pre-teleport location per player |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/LogoutCacheManager.java | Schedules delayed cache cleanup after logout |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/DeathLocationStorage.java | Makes death location storage concurrent + modernizes updates |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/ConfigMigratorUtil.java | New config migration helper |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/ConfigManager.java | Adds atomic temp-write saves + async IO path |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/storage/ConfigClass.java | Extracts config model + adds storage autosave settings |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/TpaService.java | Extracts TPA request logic into service |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/TeleportService.java | Moves teleport service to services + records previous location |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/TeleportSafety.java | Reintroduces TeleportSafety under services package |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/RtpService.java | Extracts RTP tick/search implementation into service |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/NamedLocationTeleportService.java | Centralizes named-location teleport helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/services/LocationResolver.java | Centralizes name normalization + lookup by name/UUID |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/client/WaypointTeleportMixin.java | Routes Xaero waypoint teleport to mod commands (+ death → back) |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/client/WaypointDeleteMixin.java | Converts Xaero minimap deletes into silent hide commands |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/client/MapWaypointDeleteMixin.java | Converts Xaero world map deletes into silent hide commands |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/client/GuiMapMixin.java | Limits right-click teleport interception to tagged waypoints |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/client/ClientPlayNetworkHandlerMixin.java | Expands trusted-command allowlist for new commands |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/ServerStartMixin.java | Formatting-only change |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/PlayerDeathMixin.java | Formatting-only change |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/mixin/CommandsMixin.java | Formatting-only change |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/common/PreviousTeleportLocation.java | Adds model for pre-teleport location |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/common/Player.java | Adds default-home UUID + per-player hidden warp UUIDs |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/common/NamedLocation.java | Adds UUID + Xaero visibility flag + ensures UUID |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/common/DeathLocation.java | Comment cleanup only |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/worldspawn/worldspawn.java | Refactors worldspawn command into package |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/worldspawn/WorldSpawnMessages.java | Extracts worldspawn messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/worldspawn.java | Removes old worldspawn command implementation |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/warp.java | Refactors warp commands + adds visibility/admin map list |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpVisibilityActions.java | Implements per-player/global warp visibility updates |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpTeleportActions.java | Refactors warp teleport behavior |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpSuggestionProvider.java | Moves suggestion provider into warp package |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpMutationActions.java | Refactors warp create/delete/rename |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpMessages.java | Extracts warp messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpFormatter.java | Adds clickable warp list + map toggle UI |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpCommandSupport.java | Shared warp printing + resolving helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp/WarpAdminFormatter.java | Adds admin global visibility list formatter |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/warp.java | Removes old warp command implementation |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/tpa/tpa.java | Refactors tpa commands to use TpaService |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/tpa/TpaSuggestionProvider.java | Refactors suggestion provider for new request model |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/tpa/TpaMessages.java | Extracts tpa messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/tpa.java | Removes old tpa command implementation |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/rtp/rtp.java | Refactors rtp commands to use RtpService |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/rtp/RtpMessages.java | Extracts rtp messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/home.java | Refactors home commands + adds map visibility toggles |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeVisibilityActions.java | Implements home Xaero visibility toggles |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeTeleportActions.java | Refactors home teleport behavior |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeSuggestionProvider.java | Moves suggestion provider into home package |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeMutationActions.java | Refactors home create/delete/rename/default |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeMessages.java | Extracts home messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeFormatter.java | Adds clickable homes list + map toggle UI |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/home/HomeCommandSupport.java | Shared home printing + resolving helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/common/VisibilityCommandSupport.java | Shared visibility toggle orchestration |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/back/back.java | Refactors /back + adds /back tp mode |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/back/BackMessages.java | Extracts back messaging helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/back/BackCommandSupport.java | Shared safe-teleport + prompt logic for back |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/back.java | Removes old back command implementation |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/admin/AdminStatusFormatter.java | Simplifies status listing + refresh divider |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/admin/AdminModuleRegistry.java | Adds module list/entries helpers |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/admin/AdminMessages.java | Switches admin save to async ConfigSaver |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/admin/AdminHelpFormatter.java | Builds module list dynamically |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/commands/admin/AdminCommands.java | Adds storage config node + status refresh behavior |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/client/XaeroWaypointCommandHelper.java | Generates hide commands from Xaero waypoint context |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/client/XaeroCompat.java | Tracks current set names + refactors waypoint creation |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/TeleportCommands.java | Adds autosave tick + shutdown save + logout cache hooks |
| src/main/java/org/AndrewElizabeth/teleportcommandsfabric/Constants.java | Bumps version to 1.5 + storage schema to v3 |
| gradle.properties | Bumps mod_version to 1.5 |
| TODO.md | Updates roadmap items |
| CHANGELOG.md | Adds v1.5 unreleased notes |
| .gitignore | Formatting-only change |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ServerPlayConnectionEvents.DISCONNECT.register((handler, s) -> { | ||
| UUID playerUuid = handler.player.getUUID(); | ||
| LogoutCacheManager.scheduleCleanup(playerUuid); | ||
| }); | ||
|
|
||
| ServerPlayConnectionEvents.JOIN.register((handler, sender, s) -> { | ||
| UUID playerUuid = handler.player.getUUID(); | ||
| LogoutCacheManager.cancelCleanup(playerUuid); | ||
| }); |
There was a problem hiding this comment.
ServerPlayConnectionEvents.DISCONNECT/JOIN handlers are registered inside initializeMod() with no guard. Since initializeMod() is invoked from a MinecraftServer#runServer mixin, this can register duplicate handlers if a server is started more than once in the same JVM (e.g., opening multiple singleplayer worlds), causing cleanup to schedule/cancel multiple times per event. Consider registering these once in onInitialize() or add a static boolean guard.
| private static void ConfigMigrator() throws Exception { | ||
| try (BufferedReader reader = Files.newBufferedReader(CONFIG_FILE, StandardCharsets.UTF_8)) { | ||
| jsonObject = GSON.fromJson(reader, JsonObject.class); | ||
| } | ||
| if (jsonObject == null) { | ||
| jsonObject = new JsonObject(); | ||
| } | ||
|
|
||
| int version = jsonObject.has("version") ? jsonObject.get("version").getAsInt() : 0; | ||
|
|
||
| if (version < defaultVersion) { | ||
| Constants.LOGGER.warn("Config file is v{}, migrating to v{}!", version, defaultVersion); | ||
|
|
||
| // Rename legacy "wild" section to "rtp" if needed. | ||
| if (jsonObject.has("wild") && !jsonObject.has("rtp")) { | ||
| jsonObject.add("rtp", jsonObject.get("wild")); | ||
| jsonObject.remove("wild"); | ||
| JsonObject jsonObject = com.google.gson.JsonParser.parseReader(reader).getAsJsonObject(); | ||
| int version = jsonObject.has("version") ? jsonObject.get("version").getAsInt() : 0; | ||
| if (version < defaultVersion) { | ||
| ConfigMigratorUtil.ConfigMigrator(CONFIG_FILE, GSON, defaultVersion); | ||
| } | ||
|
|
||
| normalizeXaeroSetNames(jsonObject); | ||
|
|
||
| // Always bump to the latest supported schema version after migrations. | ||
| jsonObject.addProperty("version", defaultVersion); | ||
|
|
||
| // Save the config | ||
| byte[] json = GSON.toJson(jsonObject).getBytes(StandardCharsets.UTF_8); | ||
| Files.write(CONFIG_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, | ||
| StandardOpenOption.CREATE); | ||
|
|
||
| Constants.LOGGER.info("Config file migrated to v{} successfully!", defaultVersion); | ||
| } else if (version > defaultVersion) { | ||
| String message = String.format( | ||
| "Teleport Commands: The config file's version is newer than the supported version, found v%s, expected <= v%s.\n" | ||
| + | ||
| "If you intentionally backported then you can attempt to downgrade the config file located at this location: \"%s\".\n", | ||
| version, defaultVersion, CONFIG_FILE.toAbsolutePath()); | ||
|
|
||
| throw new IllegalStateException(message); | ||
| } | ||
| } | ||
|
|
||
| private static void normalizeXaeroSetNames(JsonObject root) { | ||
| if (!root.has("xaero") || !root.get("xaero").isJsonObject()) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
ConfigMigrator() uses JsonParser.parseReader(reader).getAsJsonObject() without handling malformed JSON or non-object roots, which will throw and abort startup rather than falling back to defaults. Consider catching parse/illegal-state exceptions here and either reset to defaults (with a warning) or delegate to ConfigMigratorUtil using gson.fromJson like the storage migrator does.
| try { | ||
| setter.run(); | ||
| ConfigManager.saveConfigChanges(); | ||
| ConfigManager.ConfigSaver(); |
There was a problem hiding this comment.
ConfigManager.ConfigSaver() is asynchronous and does not propagate IO failures, but setAndSave() reports success immediately. This can lead to user-visible inconsistencies (command says saved, but the file write fails). Consider using a synchronous save here (or waiting on the submitted Future) so the command result reflects the actual outcome.
| ConfigManager.ConfigSaver(); | |
| ConfigManager.ConfigSaver().get(); |
| public int getAutoSaveIntervalSeconds() { | ||
| return autoSaveIntervalSeconds; | ||
| } |
There was a problem hiding this comment.
Storage#getAutoSaveIntervalSeconds() returns the raw deserialized value. If a user edits the JSON to an out-of-range value (0/negative/very large), the autosave cadence in StorageManager.tick() can become pathological. Consider clamping in the getter (similar to Rtp#getRadius()), or normalizing after load by calling the setter once.
| private static String buildHideCommandLiteral(String command, String name) { | ||
| return command + " " + quoteCommandArgument(name) + " false"; | ||
| } | ||
|
|
||
| private static String normalizeSetName(String setName) { | ||
| return setName == null ? "" : setName.trim().toLowerCase(Locale.ROOT); | ||
| } | ||
|
|
||
| private static String quoteCommandArgument(String value) { | ||
| return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; | ||
| } |
There was a problem hiding this comment.
XaeroWaypointCommandHelper duplicates the command-argument quoting logic that now exists in utils.CommandHelper. Keeping multiple implementations increases the chance of escaping drifting over time. Consider reusing CommandHelper.quoteCommandArgument(...) here and in the mixins that currently have their own quoting helpers.
| public static StorageClass STORAGE; | ||
| private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); | ||
| private static final int defaultVersion = new StorageClass().getVersion(); | ||
| private static final ExecutorService IO_EXECUTOR = Executors.newSingleThreadExecutor(); |
There was a problem hiding this comment.
IO_EXECUTOR is created with the default thread factory (non-daemon, unnamed) and is never shut down. This can keep the JVM alive on shutdown and makes it harder to diagnose thread dumps. Consider using a custom ThreadFactory to name the thread and set it to daemon, and ensure the executor is shut down during server stop.
| public static void forceSaveOnShutdown() { | ||
| Constants.LOGGER.info("Forcing synchronous save on server shutdown..."); | ||
| saveStorageSync(); | ||
| isDirty = false; | ||
| ticksSinceLastSave = 0; |
There was a problem hiding this comment.
forceSaveOnShutdown() writes synchronously, but any previously queued async StorageSaver() tasks can still run afterwards and overwrite the file with an older serialized snapshot. To avoid data loss, shut down/drain the IO executor (e.g., shutdown() + awaitTermination() / shutdownNow() and/or block on the last submitted Future) before the final sync save, or route the final write through the same single-threaded executor with proper ordering.
No description provided.