diff --git a/AGENTS.md b/AGENTS.md index 92aff64..0072e9c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,9 +20,10 @@ This document defines repository-wide guidance for contributors and coding agent ## Build & test expectations - Java version: **17**. - Preferred verification flow before submitting: - 1. `mvn -q -DskipTests compile` + 1. `mvn -q -DskipTests package` 2. `mvn -q test` 3. `mvn spotless:check` — if violations are reported, run `mvn spotless:apply` to fix them, then re-run the check. + 4. run markdownlint and fix issues. - If a full test run is too expensive, run targeted tests for touched areas and explicitly note what was skipped. - After editing any `pom.xml` or Java source file, run `mvn spotless:check` (or `mvn spotless:apply`) to ensure formatting is clean before committing. diff --git a/CHANGELOG.md b/CHANGELOG.md index ac934c5..e68377f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,21 @@ Release tags use the `v` prefix (e.g. `v3.0.2`). --- +## [3.1.0] - 2026-05-09 + +### Added + +- **Message suppression via config** (`config.yml`): + - `messages.suppress-player`: when `true`, silences all teleport-related messages to players globally (searching, countdown, queue position, success, failure, cost). + - `messages.suppress-console`: when `true`, silences the executor notification that `/forcertp` sends to the command sender globally. +- **`--skip-message` command flag**: can be appended to `/rtp`, `/rtp `, `/forcertp [world]`, and `/rtp forcertp [world]` to suppress both player-facing and executor messages for that single invocation. Tab-completion suggests the flag. + +--- + ## [3.0.2] - 2026-05-09 ### Added + - Initial changelog entry. See repository history for prior changes. --- diff --git a/docs/api/plugin-api.md b/docs/api/plugin-api.md index 567b03e..afcc756 100644 --- a/docs/api/plugin-api.md +++ b/docs/api/plugin-api.md @@ -162,7 +162,7 @@ not exposed by the static helpers. cost and cooldown rules are applied. | Value | When to use | -|:------|:------------| +| :--- | :--- | | `COMMAND` | Player triggered the teleport via a command or button. Cooldowns and costs apply. | | `JOIN` | Player joined the server and was auto-teleported. Uses the `on-join` cost/cooldown rules. | @@ -196,7 +196,7 @@ public interface TeleportService { any YAML section. Below are the keys you can set: | Key | Type | Example | Description | -|:----|:-----|:--------|:------------| +| :--- | :--- | :--- | :--- | | `world` | String | `world_the_end` | World to teleport into. `auto` = player's current world. | | `center.x` / `center.z` | int | `0` | Search centre coordinates. | | `radius.min` | int | `500` | Minimum distance from centre. | diff --git a/docs/commands.md b/docs/commands.md index d6ad059..2df1b88 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -13,6 +13,9 @@ nav_order: 3 - `/rtp ` - Teleports using the named center configured under `centers.named` in `rtp.yml`. - Named center is applied as a center override only; the world's normal RTP settings still apply. +- `/rtp [centerName|regionId] --skip-message` + - Suppresses all teleport-related messages to the player for this invocation. + - Can be combined with a named center or WorldGuard region argument. ## RTP subcommands @@ -31,8 +34,9 @@ nav_order: 3 ## Force command -- `/forcertp [world]` +- `/forcertp [world] [--skip-message]` - If world is omitted, EzRTP uses `force-rtp.yml` `default-world`. + - `--skip-message`: suppresses the executor notification and all player-facing teleport messages for this invocation. The flag may appear anywhere in the argument list. ## WorldGuard region mode (optional) diff --git a/docs/config/config.md b/docs/config/config.md index 8add096..f7f146f 100644 --- a/docs/config/config.md +++ b/docs/config/config.md @@ -13,10 +13,12 @@ their own dedicated files. ## Settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `message-prefix` | `"&7[&bEzRTP&7] &r"` | Text prepended to every chat message the plugin sends. Supports `&` color codes and MiniMessage. | | `language` | `en` | Selects which file under `messages/` is used for player-facing text. Example: `en` loads `messages/en.yml`. | | `messages.force-legacy-colors` | `false` | Set to `true` on servers running very old clients that do not understand MiniMessage formatting. Converts all output to legacy `§` color codes. | +| `messages.suppress-player` | `false` | When `true`, suppresses all teleport-related messages sent to players globally (searching, countdown, success, failure, queue). Useful for automation or silent teleports. | +| `messages.suppress-console` | `false` | When `true`, suppresses the executor notification that admin commands (e.g. `/forcertp`) normally send to the command sender. | | `worldguard.region-command.enabled` | `false` | Allows `/rtp ` to teleport players randomly **inside** a named WorldGuard region. Requires WorldGuard. | | `worldguard.region-command.autocomplete` | `false` | When enabled, tab-completing `/rtp` will suggest WorldGuard region names. | | `world` | `world` | Fallback world name used by utility commands (e.g. `/rtp pregenerate`). Does not affect normal RTP — that is set in `rtp.yml`. | @@ -31,6 +33,8 @@ language: en messages: force-legacy-colors: false + suppress-player: false # suppress all teleport-related messages to players + suppress-console: false # suppress executor notifications for admin commands worldguard: region-command: diff --git a/docs/config/force-rtp.md b/docs/config/force-rtp.md index 50a0253..8295f59 100644 --- a/docs/config/force-rtp.md +++ b/docs/config/force-rtp.md @@ -15,7 +15,7 @@ choose which normal restrictions are bypassed when the command is used. ## Settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `default-world` | `world` | World used when the command is run without specifying a world. Set to `auto` to send the target player to a random location in their current world. | | `bypass.cooldown` | `true` | When `true`, `/forcertp` ignores the target player’s cooldown. Recommended — admins should never be blocked by a cooldown on a moderation tool. | | `bypass.permission` | `true` | When `true`, `/forcertp` ignores any per-destination permission checks on the target player. | diff --git a/docs/config/gui.md b/docs/config/gui.md index 8f54819..88f9e90 100644 --- a/docs/config/gui.md +++ b/docs/config/gui.md @@ -15,7 +15,7 @@ inventory. ## Top-level settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `enabled` | `true` | Set to `false` to disable the GUI entirely. Players use `/rtp` only as a plain command. | | `title` | `Random Teleport` | Title shown at the top of the inventory. Supports MiniMessage formatting. | | `rows` | `5` | Number of rows in the chest GUI (1–6). Each row has 9 slots, so 5 rows = 45 slots total (0–44). | @@ -66,7 +66,7 @@ worlds: ### Entry fields | Field | Description | -|:------|:------------| +| :--- | :--- | | `slot` | Inventory slot (0–53). Omit to place entries in order. | | `permission` | Permission node required to click. Leave blank for no restriction. | | `icon.material` | Any valid Bukkit/Minecraft item ID (e.g. `GRASS_BLOCK`, `NETHERRACK`). | @@ -133,7 +133,7 @@ pre-cached locations ready, so players are never shown an option that would make them wait. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `disable-cache-filtering` | `false` | Set to `true` to always show all destinations regardless of cache state. | | `admin-only-cache-info` | `false` | When `true`, the “only showing cached options” notice is only shown to players with admin permissions. | | `rare_biomes.enabled` | `true` | Apply stricter cache requirements to rare biomes listed in `rtp.yml`. | diff --git a/docs/config/limits.md b/docs/config/limits.md index 49da7fe..3124f08 100644 --- a/docs/config/limits.md +++ b/docs/config/limits.md @@ -16,7 +16,7 @@ The `rtp-limits.default` block applies to all players and worlds unless a more specific override exists. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `cooldown-seconds` | `300` | Seconds a player must wait between teleports. `0` = no cooldown. | | `daily-limit` | `10` | Maximum number of RTP uses per calendar day. `-1` = unlimited. | | `weekly-limit` | `50` | Maximum number of RTP uses per calendar week. `-1` = unlimited. | @@ -77,7 +77,7 @@ rtp-limits: ## Other settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `allow-gui-during-cooldown` | `true` | When `true`, players on cooldown can still open the destination GUI — they just cannot confirm a teleport until the cooldown expires. Set to `false` to hide the GUI entirely. | ## Storage backend diff --git a/docs/config/network.md b/docs/config/network.md index 5fa303a..b2906a4 100644 --- a/docs/config/network.md +++ b/docs/config/network.md @@ -18,7 +18,7 @@ Leave it disabled on game servers unless they also show the selection GUI. ## Top-level settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `enabled` | `false` | Set to `true` to enable network entries in the GUI. | | `lobby` | `false` | Set to `true` on the server that hosts the GUI (typically the lobby). | | `ping-interval-ticks` | `200` | How often EzRTP pings each configured server to check if it’s online, in ticks (200 = 10 seconds). | @@ -55,7 +55,7 @@ servers: ### Server entry fields | Field | Description | -|:------|:------------| +| :--- | :--- | | `bungee-server` | Server name as defined in your proxy’s `config.yml` (`servers` section). | | `host` / `port` | Address used to ping the server and check if it’s online. | | `slot` | GUI slot (0–53). | diff --git a/docs/config/queue.md b/docs/config/queue.md index 7cd9dcb..d9bb2ab 100644 --- a/docs/config/queue.md +++ b/docs/config/queue.md @@ -16,7 +16,7 @@ multiple players teleport simultaneously. ## Settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `enabled` | `false` | Set to `true` to turn on the queue. | | `max-size` | `0` | Maximum number of players allowed to wait in line. `0` = no cap. When the queue is full, additional requests are rejected until a slot opens. | | `bypass-permission` | `ezrtp.queue.bypass` | Players with this permission skip the queue and teleport immediately. Useful for VIP or staff. | diff --git a/docs/config/rtp.md b/docs/config/rtp.md index a1654f5..95cb389 100644 --- a/docs/config/rtp.md +++ b/docs/config/rtp.md @@ -17,7 +17,7 @@ biome filtering and countdown timers. These settings define where a teleport destination can be. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `world` | `world` | The world players are teleported into. Use the exact world folder name (e.g. `world_nether`). Set to `auto` to always teleport within the player's current world — handy on multi-world servers. | | `center.x` / `center.z` | `0` / `0` | The X/Z coordinate used as the centre of the search circle. Defaults to 0,0 (world spawn area). | | `radius.min` | `500` | Closest a destination can be from the centre, in blocks. | @@ -42,7 +42,7 @@ max-y: 320 ## Search settings | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `search-pattern` | `random` | The shape used when picking candidate coordinates. See [Search Patterns](search-patterns) for all options. | | `max-attempts` | `16` | How many candidate locations EzRTP tries before giving up and sending a failure message. Higher values reduce failed teleports but cost slightly more CPU per attempt. | @@ -66,7 +66,7 @@ take damage during the countdown can have their teleport cancelled (configure that in `limits.yml`). | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `countdown-seconds` | `5` | How many seconds to count down. `0` disables the countdown entirely. | | `countdown.bossbar.enabled` | `true` | Shows a bossbar with the countdown. | | `countdown.bossbar.title` | *(see below)* | MiniMessage text shown in the bossbar. `` is replaced with the remaining time. | @@ -114,7 +114,7 @@ When the chosen location is mid-air or underground, EzRTP scans up or down to find solid footing before confirming the destination. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `safety.recovery.enabled` | `true` | Enables vertical scanning to find a safe Y level. | | `safety.recovery.max-vertical-adjust` | `6` | Maximum blocks to move up or down during surface recovery. | | `safety.recovery.max-surface-scan-depth` | `20` | How far below the candidate to scan for a footing block in normal worlds. Keep this small for performance. | @@ -141,7 +141,7 @@ Controls how EzRTP loads chunks while searching for destinations. On Paper 1.21+ the async API is used automatically for the best performance. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `chunk-loading.use-paper-async-api` | `auto-detect` | `auto-detect` uses Paper's async chunk API when available. `always` forces it. `never` falls back to the legacy throttle on all platforms. | | `legacy-throttle.enabled` | `true` | Enables the tick-based throttle used on Spigot/Bukkit or older Paper. | | `legacy-throttle.interval-ticks` | `10` | Ticks between chunk load batches. | @@ -155,7 +155,7 @@ Biome filtering lets you restrict (or require) specific biomes for RTP destinati The full feature set includes pre-caching and rare-biome optimisation. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `biomes.enabled` | `true` | Master switch. Set to `false` to disable all biome features. | | `biomes.include` | `[]` | If non-empty, only destinations in one of these biomes are accepted. Use Bukkit biome names, e.g. `FOREST`, `PLAINS`. | | `biomes.exclude` | `[]` | Destinations in any listed biome are rejected. | @@ -199,7 +199,7 @@ biomes: These caps prevent a single biome search from blocking the server too long. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `biome-filtering.performance-budget.max-total-time-ms` | `0` | Maximum wall-clock search time for normal searches (ms). `0` = auto (100 ms when filters active). | | `max-total-time-ms-rare` | `8000` | Maximum search time for rare biomes. | | `max-biome-rejections` | `0` | Maximum number of biome mismatches before giving up. `0` = auto. | @@ -245,7 +245,7 @@ particles: Automatically teleport new (or returning) players when they join the server. | Key | Default | Description | -|:----|:--------|:------------| +| :--- | :--- | :--- | | `on-join.enabled` | `false` | Enables automatic RTP on join. | | `on-join.only-first-join` | `false` | When `true`, only teleports players who have never joined before. | | `on-join.bypass-permission` | `""` | Players with this permission are **not** teleported on join (e.g. for staff). | diff --git a/docs/config/search-patterns.md b/docs/config/search-patterns.md index 1e22db5..a7c5f88 100644 --- a/docs/config/search-patterns.md +++ b/docs/config/search-patterns.md @@ -117,7 +117,7 @@ search-pattern: triangle ## Comparison summary | Pattern | Shape | Coverage type | Radius sampling | -|:--------|:------|:-------------|:----------------| +| :--- | :--- | :--- | :--- | | `random` | Circle perimeter | Perimeter only | Integer | | `circle` | Circle perimeter | Perimeter only | Floating-point | | `square` | Square perimeter | Perimeter only | Integer | diff --git a/docs/index.md b/docs/index.md index 21f1e53..b4e47ac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ cross-platform compatibility, and configuration-driven control for server owners ## For Server Owners & Admins | | | -|:---|:---| +| :--- | :--- | | [Getting Started](overview-installation) | Install EzRTP, choose a platform module, verify your setup | | [Commands](commands) | Player and admin command reference | | [Permissions](permissions) | Permission nodes and recommended role assignments | @@ -35,7 +35,7 @@ cross-platform compatibility, and configuration-driven control for server owners ## Configuration Reference | | | -|:---|:---| +| :--- | :--- | | [config.yml](config/config) | Global plugin settings and language | | [rtp.yml](config/rtp) | RTP bounds, safety, biomes, chunky, and countdown | | [limits.yml](config/limits) | Cooldowns, usage limits, cost overrides, and storage backend | @@ -48,7 +48,7 @@ cross-platform compatibility, and configuration-driven control for server owners ## Platform Modules | | | -|:---|:---| +| :--- | :--- | | [Bukkit / CraftBukkit](modules/installation-bukkit) | Base plugin only | | [Spigot](modules/installation-spigot) | Base plugin only | | [Paper](modules/installation-paper) | Base + `ezrtp-paper` module | @@ -57,7 +57,7 @@ cross-platform compatibility, and configuration-driven control for server owners ## Integrations | | | -|:---|:---| +| :--- | :--- | | [Vault / Economy](integrations/vault-economy) | Charge players for RTP | | [PlaceholderAPI](integrations/placeholderapi) | Dynamic placeholders in GUI | | [Chunky](integrations/chunky) | World pre-generation | @@ -67,6 +67,6 @@ cross-platform compatibility, and configuration-driven control for server owners ## For Developers | | | -|:---|:---| +| :--- | :--- | | [Developer API](api/plugin-api) | Trigger RTP programmatically from other plugins | | [Developer Guide](development-collaboration) | Architecture, build workflow, contributor conventions | diff --git a/docs/modules/index.md b/docs/modules/index.md index e53a332..273d2a6 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -10,7 +10,7 @@ EzRTP ships a base plugin jar plus optional platform modules. Install the module that matches your server software. | Server | Required jars | -|:-------|:--------------| +| :--- | :--- | | Bukkit / CraftBukkit | `EzRTP-.jar` | | Spigot | `EzRTP-.jar` | | Paper | `EzRTP-.jar` + `ezrtp-paper-.jar` | diff --git a/docs/overview-installation.md b/docs/overview-installation.md index 339f2a7..cfdaac4 100644 --- a/docs/overview-installation.md +++ b/docs/overview-installation.md @@ -44,7 +44,7 @@ matches your server software. ### Choose the correct module(s) | Server software | Required jar(s) in `plugins/` | Notes | -|---|---|---| +| --- | --- | --- | | Bukkit / CraftBukkit | `EzRTP-.jar` | Base runtime already includes Bukkit-compatible adapters. | | Spigot | `EzRTP-.jar` | Spigot runs on the Bukkit-compatible base runtime. | | Paper | `EzRTP-.jar` + `ezrtp-paper-.jar` | Paper module registers Paper-specific runtime adapters. | diff --git a/docs/permissions.md b/docs/permissions.md index b56adaf..6eaec8b 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -8,7 +8,7 @@ nav_order: 4 ## Declared permissions | Permission | Default | Description | -|:-----------|:--------|:------------| +| :--- | :--- | :--- | | `ezrtp.use` | `true` | Use `/rtp` | | `ezrtp.reload` | `op` | Reload configuration with `/rtp reload` | | `ezrtp.stats` | `op` | View RTP statistics with `/rtp stats` | diff --git a/ezrtp-api/pom.xml b/ezrtp-api/pom.xml index 74f10cc..f1412b3 100644 --- a/ezrtp-api/pom.xml +++ b/ezrtp-api/pom.xml @@ -5,13 +5,13 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml com.skyblockexp ezrtp-api - 3.0.3 + 3.1.0 jar EzRTP API Lightweight public API for EzRTP intended for third-party plugins. diff --git a/ezrtp-bukkit/pom.xml b/ezrtp-bukkit/pom.xml index 4661511..e383688 100644 --- a/ezrtp-bukkit/pom.xml +++ b/ezrtp-bukkit/pom.xml @@ -5,13 +5,13 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml com.skyblockexp ezrtp-bukkit - 3.0.3 + 3.1.0 jar EzRTP (Bukkit) EzRTP Bukkit-compatible plugin module. @@ -111,7 +111,7 @@ com.skyblockexp ezrtp-common - 3.0.3 + 3.1.0 diff --git a/ezrtp-common/pom.xml b/ezrtp-common/pom.xml index 372e5cd..9e473c8 100644 --- a/ezrtp-common/pom.xml +++ b/ezrtp-common/pom.xml @@ -5,13 +5,13 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml com.skyblockexp ezrtp-common - 3.0.3 + 3.1.0 jar EzRTP Common Shared utilities for EzRTP (platform-independent) diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/ForceRtpCommand.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/ForceRtpCommand.java index 724bc19..a13341a 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/ForceRtpCommand.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/ForceRtpCommand.java @@ -51,6 +51,18 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return true; } + // Strip --skip-message flag from args before normal processing + boolean skipMessage = false; + List filteredArgs = new ArrayList<>(); + for (String arg : args) { + if ("--skip-message".equalsIgnoreCase(arg)) { + skipMessage = true; + } else { + filteredArgs.add(arg); + } + } + args = filteredArgs.toArray(new String[0]); + if (args.length < 1) { com.skyblockexp.ezrtp.util.MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_INVALID_USAGE)); return true; @@ -86,6 +98,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (!worldName.equals(settings.getWorldName())) { settings = settings.withWorldName(worldName); } + if (skipMessage) { + settings = settings.withSuppressPlayerMessages(true); + } RandomTeleportService service = teleportServiceSupplier.get(); if (service == null) { @@ -93,14 +108,19 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return false; } + boolean suppressConsole = skipMessage || (configuration != null && configuration.isSuppressConsoleMessages()); // Notify executor and target - com.skyblockexp.ezrtp.util.MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_EXECUTOR_NOTIFICATION, Map.of("player", target.getName()))); + if (!suppressConsole) { + com.skyblockexp.ezrtp.util.MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_EXECUTOR_NOTIFICATION, Map.of("player", target.getName()))); + } // Provide the target message with the 'world' placeholder so messages // like "You are being teleported to ..." are resolved. - com.skyblockexp.ezrtp.util.MessageUtil.send(target, plugin.getMessageProvider().format( - MessageKey.FORCERTP_TARGET_NOTIFICATION, - Map.of("world", worldName != null ? worldName : target.getWorld().getName()), - target)); + if (!settings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(target, plugin.getMessageProvider().format( + MessageKey.FORCERTP_TARGET_NOTIFICATION, + Map.of("world", worldName != null ? worldName : target.getWorld().getName()), + target)); + } // Teleport instantly, bypassing configured restrictions service.teleportPlayer(target, settings, TeleportReason.COMMAND); @@ -123,15 +143,24 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman } if (args.length == 2) { - // Suggest world names and the special "auto" sentinel + // Suggest world names, the special "auto" sentinel, and the --skip-message flag List suggestions = new ArrayList<>(); suggestions.add("auto"); + suggestions.add("--skip-message"); for (org.bukkit.World world : Bukkit.getWorlds()) { suggestions.add(world.getName()); } return suggestions; } + if (args.length == 3) { + List suggestions = new ArrayList<>(); + if (!java.util.Arrays.asList(args).contains("--skip-message")) { + suggestions.add("--skip-message"); + } + return suggestions; + } + return Collections.emptyList(); } } \ No newline at end of file diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/RandomTeleportCommand.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/RandomTeleportCommand.java index 9b863df..a77d2a2 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/RandomTeleportCommand.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/RandomTeleportCommand.java @@ -85,6 +85,18 @@ public RandomTeleportCommand(EzRtpPlugin plugin, @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + // Strip --skip-message flag before normal dispatch + boolean skipMessage = false; + List filteredArgsList = new ArrayList<>(); + for (String arg : args) { + if ("--skip-message".equalsIgnoreCase(arg)) { + skipMessage = true; + } else { + filteredArgsList.add(arg); + } + } + args = filteredArgsList.toArray(new String[0]); + if (args.length > 0) { Subcommand subcommand = subcommands.get(args[0].toLowerCase()); if (subcommand != null) { @@ -93,20 +105,20 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return subcommand.execute(sender, subArgs); } if (args.length == 1) { - if (handleWorldGuardRegionTeleport(sender, args[0])) { + if (handleWorldGuardRegionTeleport(sender, args[0], skipMessage)) { return true; } - if (handleNamedCenterTeleport(sender, args[0])) { + if (handleNamedCenterTeleport(sender, args[0], skipMessage)) { return true; } } } // Default RTP command - open GUI or teleport directly - return handleDefaultRtp(sender); + return handleDefaultRtp(sender, skipMessage); } - private boolean handleNamedCenterTeleport(CommandSender sender, String centerName) { + private boolean handleNamedCenterTeleport(CommandSender sender, String centerName, boolean skipMessage) { if (!(sender instanceof Player player)) { return false; } @@ -134,6 +146,9 @@ private boolean handleNamedCenterTeleport(CommandSender sender, String centerNam centerOverride.set("center.z", namedCenter.z()); RandomTeleportSettings centerSettings = RandomTeleportSettings.fromConfiguration(centerOverride, plugin.getLogger(), baseSettings); + if (skipMessage) { + centerSettings = centerSettings.withSuppressPlayerMessages(true); + } RandomTeleportService service = teleportServiceSupplier.get(); if (service == null) { @@ -144,7 +159,7 @@ private boolean handleNamedCenterTeleport(CommandSender sender, String centerNam return true; } - private boolean handleWorldGuardRegionTeleport(CommandSender sender, String regionId) { + private boolean handleWorldGuardRegionTeleport(CommandSender sender, String regionId, boolean skipMessage) { if (!(sender instanceof Player player)) { return false; } @@ -179,6 +194,9 @@ private boolean handleWorldGuardRegionTeleport(CommandSender sender, String regi } RandomTeleportSettings regionSettings = resolveRegionSettings(player, normalizedRegionId, baseSettings, boundsOptional.get()); + if (skipMessage) { + regionSettings = regionSettings.withSuppressPlayerMessages(true); + } RandomTeleportService service = teleportServiceSupplier.get(); if (service == null) { MessageUtil.send(player, "Teleport service is not available right now."); @@ -234,7 +252,7 @@ private record RegionOverrideCacheEntry(long lastModified, YamlConfiguration con /** * Handles the default /rtp command (no subcommands). */ - private boolean handleDefaultRtp(CommandSender sender) { + private boolean handleDefaultRtp(CommandSender sender, boolean skipMessage) { if (!(sender instanceof Player player)) { MessageUtil.send(sender, "This command may only be used by players."); return true; @@ -260,6 +278,10 @@ private boolean handleDefaultRtp(CommandSender sender) { } } } + if (skipMessage) { + settings = settings.withSuppressPlayerMessages(true); + } + if (hasBypass) { // Bypass all limits if (guiManager != null && guiManager.openSelection(player)) { @@ -267,7 +289,7 @@ private boolean handleDefaultRtp(CommandSender sender) { } RandomTeleportService service = teleportServiceSupplier.get(); if (service != null) { - service.teleportPlayer(player, TeleportReason.COMMAND); + service.teleportPlayer(player, settings, TeleportReason.COMMAND); } return true; } @@ -300,7 +322,7 @@ private boolean handleDefaultRtp(CommandSender sender) { RandomTeleportService service = teleportServiceSupplier.get(); if (service != null) { // Only increment usage/cooldown after a successful teleport - service.teleportPlayer(player, TeleportReason.COMMAND, success -> { + service.teleportPlayer(player, settings, TeleportReason.COMMAND, success -> { if (success) { usageStorage.setLastRtpTime(player.getUniqueId(), world, System.currentTimeMillis()); usageStorage.incrementUsage(player.getUniqueId(), world, "daily"); @@ -325,6 +347,7 @@ private boolean handleDefaultRtp(CommandSender sender) { } completions.addAll(getWorldGuardRegionCompletions(sender, args[0])); completions.addAll(getNamedCenterCompletions(args[0])); + completions.add("--skip-message"); return completions; } else if (args.length > 1) { Subcommand subcommand = subcommands.get(args[0].toLowerCase()); @@ -333,6 +356,10 @@ private boolean handleDefaultRtp(CommandSender sender) { System.arraycopy(args, 1, subArgs, 0, subArgs.length); return subcommand.tabComplete(sender, subArgs); } + // For non-subcommand paths, suggest --skip-message if not yet present + if (!java.util.Arrays.asList(args).contains("--skip-message")) { + return java.util.Collections.singletonList("--skip-message"); + } } return java.util.Collections.emptyList(); } diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/subcommands/ForcertpSubcommand.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/subcommands/ForcertpSubcommand.java index 03ea17f..7468a83 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/subcommands/ForcertpSubcommand.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/command/subcommands/ForcertpSubcommand.java @@ -43,6 +43,18 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String[] args) { return true; } + // Strip --skip-message flag from args before normal processing + boolean skipMessage = false; + java.util.List filteredArgs = new java.util.ArrayList<>(); + for (String arg : args) { + if ("--skip-message".equalsIgnoreCase(arg)) { + skipMessage = true; + } else { + filteredArgs.add(arg); + } + } + args = filteredArgs.toArray(new String[0]); + if (args.length < 1) { MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_INVALID_USAGE)); return true; @@ -73,6 +85,9 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String[] args) { if (worldName != null && !worldName.equals(settings.getWorldName())) { settings = settings.withWorldName(worldName); } + if (skipMessage) { + settings = settings.withSuppressPlayerMessages(true); + } RandomTeleportService service = teleportServiceSupplier.get(); if (service == null) { @@ -80,9 +95,14 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String[] args) { return false; } + boolean suppressConsole = skipMessage || (configuration != null && configuration.isSuppressConsoleMessages()); // Notify executor and target - MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_EXECUTOR_NOTIFICATION, Map.of("player", target.getName()))); - MessageUtil.send(target, plugin.getMessageProvider().format(MessageKey.FORCERTP_TARGET_NOTIFICATION, target)); + if (!suppressConsole) { + MessageUtil.send(sender, plugin.getMessageProvider().format(MessageKey.FORCERTP_EXECUTOR_NOTIFICATION, Map.of("player", target.getName()))); + } + if (!settings.isSuppressPlayerMessages()) { + MessageUtil.send(target, plugin.getMessageProvider().format(MessageKey.FORCERTP_TARGET_NOTIFICATION, target)); + } // Teleport instantly, bypassing GUI and limits service.teleportPlayer(target, settings, TeleportReason.COMMAND); @@ -106,15 +126,24 @@ public List tabComplete(@NotNull CommandSender sender, @NotNull String[] } if (args.length == 2) { - // Suggest world names and the special "auto" sentinel + // Suggest world names, the special "auto" sentinel, and the --skip-message flag List suggestions = new ArrayList<>(); suggestions.add("auto"); + suggestions.add("--skip-message"); for (org.bukkit.World world : Bukkit.getWorlds()) { suggestions.add(world.getName()); } return suggestions; } + if (args.length == 3) { + List suggestions = new ArrayList<>(); + if (!java.util.Arrays.asList(args).contains("--skip-message")) { + suggestions.add("--skip-message"); + } + return suggestions; + } + return Collections.emptyList(); } } \ No newline at end of file diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/EzRtpConfiguration.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/EzRtpConfiguration.java index 9a58ecf..bbf9149 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/EzRtpConfiguration.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/EzRtpConfiguration.java @@ -41,11 +41,14 @@ public final class EzRtpConfiguration { private final boolean allowGuiDuringCooldown; private final boolean humanReadableCooldown; private final Map namedCenters; + private final boolean suppressPlayerMessages; + private final boolean suppressConsoleMessages; private EzRtpConfiguration(RandomTeleportSettings defaultSettings, GuiSettings guiSettings, TeleportQueueSettings queueSettings, NetworkConfiguration networkConfiguration, boolean allowGuiDuringCooldown, boolean humanReadableCooldown, - Map namedCenters) { + Map namedCenters, + boolean suppressPlayerMessages, boolean suppressConsoleMessages) { this.defaultSettings = defaultSettings; this.guiSettings = guiSettings; this.queueSettings = queueSettings; @@ -53,6 +56,8 @@ private EzRtpConfiguration(RandomTeleportSettings defaultSettings, GuiSettings g this.allowGuiDuringCooldown = allowGuiDuringCooldown; this.humanReadableCooldown = humanReadableCooldown; this.namedCenters = namedCenters; + this.suppressPlayerMessages = suppressPlayerMessages; + this.suppressConsoleMessages = suppressConsoleMessages; // Parse rtp-limits from config ConfigurationSection config = defaultSettings.getConfigSection().getRoot(); ConfigurationSection rtpLimits = config.getConfigurationSection("rtp-limits"); @@ -173,7 +178,7 @@ public double resolveTeleportCost(Player player, RandomTeleportSettings settings } public RandomTeleportSettings getDefaultSettings() { - return defaultSettings; + return suppressPlayerMessages ? defaultSettings.withSuppressPlayerMessages(true) : defaultSettings; } /** @@ -185,18 +190,19 @@ public RandomTeleportSettings getDefaultSettings() { */ public RandomTeleportSettings getSettingsForWorld(String worldName) { if (worldName == null || worldName.isEmpty()) { - return defaultSettings; + return getDefaultSettings(); } // Look through GUI world options for matching world for (GuiWorldOption option : guiSettings.getWorldOptions()) { if (worldName.equals(option.getSettings().getWorldName())) { - return option.getSettings(); + RandomTeleportSettings s = option.getSettings(); + return suppressPlayerMessages ? s.withSuppressPlayerMessages(true) : s; } } // Fall back to default settings if world not found - return defaultSettings; + return getDefaultSettings(); } public GuiSettings getGuiSettings() { @@ -227,6 +233,10 @@ public boolean isHumanReadableCooldown() { return humanReadableCooldown; } + public boolean isSuppressConsoleMessages() { + return suppressConsoleMessages; + } + public List getNamedCenterNames() { return new ArrayList<>(namedCenters.keySet()); } @@ -271,9 +281,11 @@ public static EzRtpConfiguration fromConfigurations(ConfigurationSection baseCon boolean allowGuiDuringCooldown = baseConfiguration != null && baseConfiguration.getBoolean("rtp-limits.allow-gui-during-cooldown", true); boolean humanReadableCooldown = baseConfiguration != null && baseConfiguration.getBoolean("rtp.human-readable-cooldown", true); Map namedCenters = parseNamedCenters(baseConfiguration, logger); + boolean suppressPlayerMessages = baseConfiguration != null && baseConfiguration.getBoolean("messages.suppress-player", false); + boolean suppressConsoleMessages = baseConfiguration != null && baseConfiguration.getBoolean("messages.suppress-console", false); return new EzRtpConfiguration(defaultSettings, guiSettings, queueSettings, networkConfig, - allowGuiDuringCooldown, humanReadableCooldown, namedCenters); + allowGuiDuringCooldown, humanReadableCooldown, namedCenters, suppressPlayerMessages, suppressConsoleMessages); } private static void copySection(ConfigurationSection source, ConfigurationSection target) { @@ -300,7 +312,7 @@ private EzRtpConfiguration(RandomTeleportSettings defaultSettings, TeleportQueueSettings queueSettings, NetworkConfiguration networkConfiguration) { this(defaultSettings, guiSettings, queueSettings, networkConfiguration, true, true, - Collections.emptyMap()); + Collections.emptyMap(), false, false); } private static boolean isSectionPopulated(ConfigurationSection section) { diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/RandomTeleportSettings.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/RandomTeleportSettings.java index 14a2232..1c2c4a2 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/RandomTeleportSettings.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/config/RandomTeleportSettings.java @@ -57,6 +57,7 @@ public final class RandomTeleportSettings { private final SafetySettings safetySettings; private final SearchPattern searchPattern; private final ChunkyIntegrationSettings chunkyIntegrationSettings; + private final boolean suppressPlayerMessages; public RandomTeleportSettings(ConfigurationSection configSection, String worldName, int centerX, int centerZ, int minimumRadius, int maximumRadius, @@ -81,6 +82,40 @@ public RandomTeleportSettings(ConfigurationSection configSection, SafetySettings safetySettings, SearchPattern searchPattern, ChunkyIntegrationSettings chunkyIntegrationSettings) { + this(configSection, worldName, centerX, centerZ, minimumRadius, maximumRadius, + maxAttempts, useWorldBorderRadius, unsafeBlocks, messages, particleSettings, + onJoinTeleportSettings, countdownBossBarSettings, countdownParticleSettings, + teleportCost, countdownSeconds, countdownChatMessagesEnabled, debugRejectionLogging, + minY, maxY, biomeInclude, biomeExclude, protectionSettings, preCacheSettings, + rareBiomeOptimizationSettings, chunkLoadingSettings, enableFallbackToCache, + biomeSearchSettings, biomeFilteringEnabled, biomeSystemEnabled, safetySettings, + searchPattern, chunkyIntegrationSettings, false); + } + + public RandomTeleportSettings(ConfigurationSection configSection, + String worldName, int centerX, int centerZ, int minimumRadius, int maximumRadius, + int maxAttempts, boolean useWorldBorderRadius, Set unsafeBlocks, + TeleportMessages messages, ParticleSettings particleSettings, + OnJoinTeleportSettings onJoinTeleportSettings, + CountdownBossBarSettings countdownBossBarSettings, + CountdownParticleSettings countdownParticleSettings, + double teleportCost, + int countdownSeconds, boolean countdownChatMessagesEnabled, boolean debugRejectionLogging, + Integer minY, Integer maxY, + Set biomeInclude, + Set biomeExclude, + ProtectionSettings protectionSettings, + BiomePreCacheSettings preCacheSettings, + RareBiomeOptimizationSettings rareBiomeOptimizationSettings, + ChunkLoadingSettings chunkLoadingSettings, + boolean enableFallbackToCache, + BiomeSearchSettings biomeSearchSettings, + boolean biomeFilteringEnabled, + boolean biomeSystemEnabled, + SafetySettings safetySettings, + SearchPattern searchPattern, + ChunkyIntegrationSettings chunkyIntegrationSettings, + boolean suppressPlayerMessages) { this.configSection = configSection; this.worldName = worldName; this.centerX = centerX; @@ -114,6 +149,7 @@ public RandomTeleportSettings(ConfigurationSection configSection, this.safetySettings = safetySettings != null ? safetySettings : SafetySettings.defaults(); this.searchPattern = searchPattern != null ? searchPattern : SearchPattern.RANDOM; this.chunkyIntegrationSettings = chunkyIntegrationSettings != null ? chunkyIntegrationSettings : ChunkyIntegrationSettings.defaults(); + this.suppressPlayerMessages = suppressPlayerMessages; } public Integer getMinY() { return minY; } public Integer getMaxY() { return maxY; } @@ -130,6 +166,7 @@ public RandomTeleportSettings(ConfigurationSection configSection, public boolean isBiomeSystemEnabled() { return biomeSystemEnabled; } public SafetySettings getSafetySettings() { return safetySettings; } public SearchPattern getSearchPattern() { return searchPattern; } + public boolean isSuppressPlayerMessages() { return suppressPlayerMessages; } public String getWorldName() { return worldName; } public int getCenterX() { return centerX; } @@ -179,7 +216,21 @@ public RandomTeleportSettings withWorldName(String newWorldName) { protectionSettings, preCacheSettings, rareBiomeOptimizationSettings, chunkLoadingSettings, enableFallbackToCache, biomeSearchSettings, biomeFilteringEnabled, biomeSystemEnabled, safetySettings, - searchPattern, chunkyIntegrationSettings); + searchPattern, chunkyIntegrationSettings, suppressPlayerMessages); + } + + public RandomTeleportSettings withSuppressPlayerMessages(boolean suppress) { + return new RandomTeleportSettings( + configSection, worldName, centerX, centerZ, minimumRadius, maximumRadius, + maxAttempts, useWorldBorderRadius, unsafeBlocks, + messages, particleSettings, onJoinTeleportSettings, + countdownBossBarSettings, countdownParticleSettings, + teleportCost, countdownSeconds, countdownChatMessagesEnabled, debugRejectionLogging, + minY, maxY, biomeInclude, biomeExclude, + protectionSettings, preCacheSettings, rareBiomeOptimizationSettings, + chunkLoadingSettings, enableFallbackToCache, biomeSearchSettings, + biomeFilteringEnabled, biomeSystemEnabled, safetySettings, + searchPattern, chunkyIntegrationSettings, suppress); } public static RandomTeleportSettings fromConfiguration(ConfigurationSection section, java.util.logging.Logger logger) { diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/CountdownManager.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/CountdownManager.java index d3677b7..b7a241a 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/CountdownManager.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/CountdownManager.java @@ -52,7 +52,7 @@ public void startCountdown(Player player, RandomTeleportSettings teleportSetting } // Show countdown start message - if (teleportSettings.isCountdownChatMessagesEnabled()) { + if (teleportSettings.isCountdownChatMessagesEnabled() && !teleportSettings.isSuppressPlayerMessages()) { com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.COUNTDOWN_START, Map.of("seconds", String.valueOf(countdown)), player)); } @@ -76,7 +76,7 @@ private void runCountdown(Player player, RandomTeleportSettings teleportSettings } // Show countdown tick message - if (teleportSettings.isCountdownChatMessagesEnabled()) { + if (teleportSettings.isCountdownChatMessagesEnabled() && !teleportSettings.isSuppressPlayerMessages()) { com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.COUNTDOWN_TICK, Map.of("seconds", String.valueOf(seconds)), player)); } diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportExecutor.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportExecutor.java index 766e459..39cc7c6 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportExecutor.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportExecutor.java @@ -185,17 +185,21 @@ private void performTeleport(Player player, : teleportSettings; World world = plugin.getServer().getWorld(effectiveSettings.getWorldName()); if (world == null) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.WORLD_MISSING, - Map.of("world", effectiveSettings.getWorldName()), player)); + if (!effectiveSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.WORLD_MISSING, + Map.of("world", effectiveSettings.getWorldName()), player)); + } if (callback != null) callback.accept(false); if (completionHook != null) completionHook.run(); return; } - if (reason == TeleportReason.JOIN) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.JOIN_SEARCHING, player)); - } else { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORTING, player)); + if (!effectiveSettings.isSuppressPlayerMessages()) { + if (reason == TeleportReason.JOIN) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.JOIN_SEARCHING, player)); + } else { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORTING, player)); + } } long startTime = System.currentTimeMillis(); @@ -244,8 +248,10 @@ private void performTeleport(Player player, if (costCalculator.requiresPayment(reason, resolvedCost) && !costCalculator.withdraw(player, resolvedCost)) { locationFinder.cacheValidLocation(validLocation, teleportSettings); - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.INSUFFICIENT_FUNDS, - Map.of("cost", String.format(java.util.Locale.US, "%.2f", resolvedCost)), player)); + if (!effectiveSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.INSUFFICIENT_FUNDS, + Map.of("cost", String.format(java.util.Locale.US, "%.2f", resolvedCost)), player)); + } statistics.recordEconomyFailure(); statistics.recordAttempt(false, duration, biome, cacheHit, cacheChecked); if (callback != null) callback.accept(false); @@ -271,8 +277,10 @@ private void performTeleport(Player player, finalDuration, finalBiome, finalCacheHit, finalCacheChecked, finalValidLocation); } else { locationFinder.cacheValidLocation(finalValidLocation, effectiveSettings); - com.skyblockexp.ezrtp.util.MessageUtil.send(player, - messageProvider.format(MessageKey.TELEPORT_FAILED, player)); + if (!effectiveSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, + messageProvider.format(MessageKey.TELEPORT_FAILED, player)); + } statistics.recordTeleportApiFailure(); statistics.recordAttempt(false, finalDuration, finalBiome, finalCacheHit, finalCacheChecked); } diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportPreCheckHandler.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportPreCheckHandler.java index 972f31e..aa43858 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportPreCheckHandler.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportPreCheckHandler.java @@ -59,8 +59,10 @@ public boolean checkPayment(Player player, RandomTeleportSettings teleportSettin double resolvedCost = costCalculator.calculateCost(player, teleportSettings); if (costCalculator.requiresPayment(reason, resolvedCost) && !costCalculator.hasBalance(player, resolvedCost)) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.INSUFFICIENT_FUNDS, - Map.of("cost", String.format(java.util.Locale.US, "%.2f", resolvedCost)), player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.INSUFFICIENT_FUNDS, + Map.of("cost", String.format(java.util.Locale.US, "%.2f", resolvedCost)), player)); + } return false; } return true; diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportResultHandler.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportResultHandler.java index 8eda0e4..548e59a 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportResultHandler.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/TeleportResultHandler.java @@ -45,7 +45,9 @@ public TeleportResultHandler( public void handleSuccess(Player player, Location destination, SearchResult result, RandomTeleportSettings teleportSettings, long duration, org.bukkit.block.Biome biome, boolean cacheHit, boolean cacheChecked, Location validLocation) { - sendSuccessMessage(player, destination, result); + if (!teleportSettings.isSuppressPlayerMessages()) { + sendSuccessMessage(player, destination, result); + } playParticles(destination, teleportSettings.getParticleSettings()); statistics.recordAttempt(true, duration, biome, cacheHit, cacheChecked); if (!cacheHit && validLocation != null) { @@ -69,30 +71,38 @@ public void handleFailure(Player player, RandomTeleportSettings teleportSettings if (cacheFallbackFailure) { reasonClass = "CACHE_FALLBACK_NO_CACHE"; - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FALLBACK_NO_CACHE, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FALLBACK_NO_CACHE, player)); + } triggerCacheWarmup(teleportSettings); statistics.recordGenericSearchErrorFailure(); } else if (limitType != SearchLimitType.NONE && limitType != SearchLimitType.BIOME_REJECTIONS) { reasonClass = "SEARCH_LIMIT_" + limitType.name(); - switch (teleportSettings.getBiomeSearchSettings().getFailoverMode()) { - case ABORT -> com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED, player)); - default -> com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + switch (teleportSettings.getBiomeSearchSettings().getFailoverMode()) { + case ABORT -> com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED, player)); + default -> com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); + } } statistics.recordTimeoutFailure(); } else if (result != null && result.noValidBiome()) { reasonClass = "NO_VALID_BIOME"; - if (!teleportSettings.isEnableFallbackToCache()) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); - } else { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_BIOME, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + if (!teleportSettings.isEnableFallbackToCache()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); + } else { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_BIOME, player)); + } } statistics.recordBiomeFailure(null); } else { reasonClass = "SEARCH_EXHAUSTED_OR_GENERIC"; - if (!teleportSettings.isEnableFallbackToCache()) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); - } else { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + if (!teleportSettings.isEnableFallbackToCache()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED_SEARCH, player)); + } else { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORT_FAILED, player)); + } } statistics.recordGenericSearchErrorFailure(); } diff --git a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/queue/TeleportQueueManager.java b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/queue/TeleportQueueManager.java index 15751de..23ad57d 100644 --- a/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/queue/TeleportQueueManager.java +++ b/ezrtp-common/src/main/java/com/skyblockexp/ezrtp/teleport/queue/TeleportQueueManager.java @@ -61,25 +61,33 @@ public boolean enqueueIfNeeded(Player player, RandomTeleportSettings teleportSet UUID playerId = player.getUniqueId(); if (activeTeleportPlayer != null && activeTeleportPlayer.equals(playerId)) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORTING, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.TELEPORTING, player)); + } return true; } int existingPosition = findQueuePosition(playerId); if (existingPosition >= 0) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_QUEUED, - Map.of("position", String.valueOf(existingPosition + 1)), player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_QUEUED, + Map.of("position", String.valueOf(existingPosition + 1)), player)); + } return true; } if (queueSettings.getMaxSize() > 0 && teleportQueue.size() >= queueSettings.getMaxSize()) { - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_FULL, player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_FULL, player)); + } return true; } teleportQueue.addLast(new QueuedTeleport(playerId, teleportSettings, reason)); - com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_QUEUED, - Map.of("position", String.valueOf(teleportQueue.size())), player)); + if (!teleportSettings.isSuppressPlayerMessages()) { + com.skyblockexp.ezrtp.util.MessageUtil.send(player, messageProvider.format(MessageKey.QUEUE_QUEUED, + Map.of("position", String.valueOf(teleportQueue.size())), player)); + } if (!queueProcessing) { queueProcessing = true; diff --git a/ezrtp-paper/pom.xml b/ezrtp-paper/pom.xml index e890abd..375e26d 100644 --- a/ezrtp-paper/pom.xml +++ b/ezrtp-paper/pom.xml @@ -5,13 +5,13 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml com.skyblockexp ezrtp-paper - 3.0.3 + 3.1.0 jar EzRTP (Paper) Paper-optimized module for EzRTP @@ -32,7 +32,7 @@ com.skyblockexp ezrtp-common - 3.0.3 + 3.1.0 org.junit.jupiter diff --git a/ezrtp-purpur/pom.xml b/ezrtp-purpur/pom.xml index 7593b07..4a16468 100644 --- a/ezrtp-purpur/pom.xml +++ b/ezrtp-purpur/pom.xml @@ -5,7 +5,7 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml @@ -18,12 +18,12 @@ com.skyblockexp ezrtp-paper - 3.0.3 + 3.1.0 com.skyblockexp ezrtp-common - 3.0.3 + 3.1.0 io.papermc.paper diff --git a/ezrtp-spigot/pom.xml b/ezrtp-spigot/pom.xml index 18674eb..0cece33 100644 --- a/ezrtp-spigot/pom.xml +++ b/ezrtp-spigot/pom.xml @@ -5,13 +5,13 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 ../pom.xml com.skyblockexp ezrtp-spigot - 3.0.3 + 3.1.0 jar EzRTP (Spigot) Spigot-optimized module for EzRTP @@ -26,7 +26,7 @@ com.skyblockexp ezrtp-common - 3.0.3 + 3.1.0 diff --git a/pom.xml b/pom.xml index aa7487c..cd10ef6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.skyblockexp ezrtp-parent - 3.0.3 + 3.1.0 pom EzRTP Parent Aggregator POM for EzRTP multi-module build diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7d4357c..52316e1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -19,6 +19,14 @@ messages: # Convert MiniMessage output to legacy colors before sending (for legacy client compatibility). force-legacy-colors: false + # Suppress all teleport-related messages sent to players (searching, success, failure, countdown, + # queue position). Useful for automation or when another plugin handles feedback. + suppress-player: false + + # Suppress messages sent to the command executor for admin commands such as /forcertp. + # Does not affect error messages that require a response (e.g. invalid usage). + suppress-console: false + # WorldGuard region command support. # Kept in config.yml for command-layer compatibility. worldguard: