
Warp Hopper
Boost server performance by swapping tangled hopper lines for sleek, wireless item routing. Eliminate lag‑filled storage rooms and embrace invisible, high‑efficiency logistics.
Список изменений
✨ WarpHopper v3.5-pre – The Ultimate Cross-Dimensional Logistics & Storage Engine ✨
WarpHopper v3.5-pre introduces a massive architectural evolution. This update features cross-dimensional item routing, highly-optimized smart chunk loading to prevent server overhead, a pluggable multi-provider storage system supporting SQL databases, an automated data migration and backup suite, and a completely redesigned filter system with independent Whitelist/Blacklist routing, per-filter destroy mode, and deep route analytics.
🚀 Version 3.5-pre Change-log
🧱 Physical Infrastructure Cost (Virtual Pipeline)
- Distance-Based Cost: Linking containers now deducts physical hoppers from your inventory based on exact Manhattan distance.
- Shared Routes: Overlapping paths in the same direction share hopper costs, forming an efficient, branching pipeline.
- Pending Deposits: If you lack enough hoppers, the plugin sets a 10-minute pending state (use
deposit allorcancel). - Exploit-Safe Refunds: Unlinking containers smartly calculates orphaned route segments and dynamically refunds the exact unused hoppers. Click here for more detailed about the architecture of the 3.5-pre
🌌 Cross-Dimensional Routing
- Cross-World Links: Containers can now be linked across different dimensions (Overworld, Nether, and The End). WarpHopper routes items across dimensions seamlessly.
- Configurable Control: Toggle cross-dimensional transfers server-wide via
allow-cross-dimensional-transfer(default:true).
⚡ Smart Chunk Loading
- Zero-Stall Delivery: If a linked destination container resides in an unloaded chunk, WarpHopper temporarily loads the chunk to deposit the item and schedules it to unload immediately after.
- Dynamic Load Scaling: Chunk load duration scales dynamically. It starts at a base load time (
base-chunk-load-ticks, default:20ticks / 1 second) and adds8ticks per item transferred to guarantee complete logistics delivery. - Per-Player Safety Limits: Players are capped to a configurable maximum of concurrent temporarily loaded chunks (
max-temp-chunks-per-player, default:2) to safeguard server performance. - Cross-Dimensional Load Protection: Cross-dimensional loading is independently controlled via
cross-dim-chunk-loading(default:true),cross-dim-chunk-load-ticks(default:20ticks), and its own per-player ticket capcross-dim-max-chunks-per-player(default:2). - Source Chunk Keeps Alive: Optionally loads the source hopper's chunk if it unloads during a cross-dimensional transfer to keep high-speed transfers active.
💾 Pluggable Multi-Provider Storage
- 5 Supported Engines: Swap between
.dat(NBT),.yml(YAML),.json(JSON), MySQL, and MariaDB by updating thestorage-typeoption inconfig.yml. - Database Connection Pooling: Built-in connection pooling for MySQL and MariaDB via shaded
HikariCPfor fast, non-blocking off-thread operations. - Robust Schema Auto-Creation: Database tables are automatically initialized and indexed for rapid queries.
🔄 Migration & Auto-Config Suite
- Interactive Migration Command: Use
/wh migrate <type>to migrate all WarpHopper data from the active storage type to any of the other four formats. - Safe Async Transfers: Data migration runs asynchronously in a background thread to ensure zero gameplay spikes or server lag.
- Automatic Backups: Migrating from file-based storage automatically creates a backup of the source files named in the format
(storage).(storageType).backup(e.g.hoppers.yml.backup). - Config Auto-Updater: Whenever
/wh reloador the plugin starts, WarpHopper merges new configuration properties from the default template into the user's existingconfig.ymlwithout modifying their custom settings (e.g., maintaining a user's customround-robinortransfer-interval-ticks). - Hot-Swap Engine: Reloading the plugin with a changed
storage-typeinconfig.ymlautomatically triggers an asynchronous migration on the fly.
🔀 Whitelist vs Blacklist Filters — Independent Routing
Every item filter now carries an explicit type that controls exactly how items are routed through the system:
| Type | Behaviour |
|---|---|
| Whitelist (default) | Items go to the filter containers first; any remainder falls through to default routing as normal. |
| Blacklist | Items go to filter containers only — they are never forwarded to default routing, giving them a fully independent route. |
- Status displayed on every filter — the main menu shows each filter's type with colour coding:
[W]in green for Whitelist,[B]in red for Blacklist, so you can tell at a glance which filters are independent. - Default routing is smart — default containers only receive items that have no filter at all, or items from a Whitelist filter that still have remainder capacity. Blacklist filter items never reach default routing under any circumstance.
- Change Status button — inside every filter menu, a dedicated Change Status button (slot 3) lets you flip a filter between Whitelist and Blacklist instantly with a single click. The change is saved immediately.
➕ Dual "Add Filter" Buttons
The main menu now has two dedicated filter creation buttons instead of one:
| Slot | Button | Effect |
|---|---|---|
| 0 | Add Whitelist Filter (green glass pane) | Creates a Whitelist filter for the item held in your main hand. Remainder items fall through to default routing. |
| 1 | Add Blacklist Filter (red glass pane) | Creates a Blacklist filter for the item held in your main hand. Items follow this filter exclusively and never reach default routing. |
Hold the item you want to filter in your main hand, then click the appropriate button.
🔥 Per-Filter Destroy Mode
💡 Feature suggested by @mhk924 — thank you for the idea!
Each individual filter can have its own Destroy Mode, giving fine-grained control over which item types are permanently deleted rather than routed.
- Destroy Mode toggle — slot 4 inside every filter menu. Lava Bucket icon means destroy mode is ON; empty Bucket means it is OFF.
- Live destroyed-items counter — hovering over the lava bucket shows exactly how many items that specific filter has destroyed during the current server session. The counter resets on server restart.
- Routing priority — destroy mode fires before any container routing. If a filter has destroy mode enabled, matching items are permanently deleted and the counter is incremented; no containers are touched at all.
- Works with both filter types — destroy mode is independent of whether the filter is Whitelist or Blacklist.
- Fully persisted — destroy filter settings are saved across all five storage backends.
🚫 Global Item Blacklist (Default Routing)
- Per-Hopper Blacklist: Block specific item types from ever being transferred by a WarpHopper, no matter how many default links are configured.
- In-GUI Management: Open the Default Routing menu and click the red glass pane (slot 1 of the toolbar):
- Hold an item + click to toggle that item type on or off the blacklist.
- Empty hand + click to print the current blacklist to chat.
- Empty hand + shift-click to clear the entire blacklist instantly.
- Fully Persisted: The blacklist is saved and loaded across restarts for all five storage backends (YAML, JSON, DAT, MySQL, MariaDB).
- Zero Performance Overhead: Blacklist rejection happens at the very start of the transfer pipeline — blacklisted items are skipped in a single
Set.contains()check before any container access.
📊 Per-Filter Route Analytics
Every filter entry in the main menu now displays a full route breakdown without needing to open the filter menu:
- Linked containers — total container count for that filter.
- Route breakdown — shown as
N (A indep | B shared | C backbone):- indep — routes whose entire pipeline path is owned exclusively by this hopper.
- shared — routes that reuse part of another route's existing backbone (partially shared cost).
- backbone — routes that ride entirely on existing infrastructure at zero extra hopper cost.
- Hoppers in use — total virtual pipeline hoppers currently charged to that filter.
The same breakdown appears inside each filter's info panel.
📦 Hopper Inventory View
- Direct Inventory Access: A "View Hopper Inventory" button (hopper icon, slot 3) is available in the main WarpHopper GUI.
- Native Minecraft UI: Clicking the button closes the WarpHopper menu and opens the physical hopper's vanilla 5-slot inventory — exactly as if you sneaked and right-clicked the hopper directly.
- Full Interaction: Players can freely add, remove, or rearrange items inside the hopper through this view. All standard Minecraft inventory interactions work as expected.
- Safety Guards: If the hopper block no longer exists at the registered location (e.g., broken by another player), the plugin sends a clear error message instead of crashing.
⚡ Streamlined Deletion (No More Shift-Click)
- Frictionless UI: Removed the cumbersome "Shift-click to confirm" requirement across all GUIs.
- Direct Deletion: You can now delete filters, clear all default links, and remove admins with a single, simple click.
- Consistent UX: Matches the behavior of unlinking individual containers, providing a much faster and smoother management experience.
🔁 Routing Priority (Full Chain)
1. Global blacklist → item stays in hopper, never transferred.
2. Per-filter destroy mode → item permanently destroyed; destroyed-items counter incremented.
3. Filter containers (Whitelist or Blacklist type):
Whitelist → send to filter containers; any remainder proceeds to step 4.
Blacklist → send to filter containers ONLY; stop here regardless of remainder.
4. Default containers → receives Whitelist remainders and items with no filter at all.
🛠️ Performance Engine
- Asynchronous Data Handling: Heavy file/database writing is performed off the main thread.
- Memory-Efficient Caching: Optimized indexing to look up active hopper setups with zero overhead.
- Strict Chunk Load Tracking: Complete ticketing system to load, lock, and release chunks safely.
- Single-pass route analytics: Route type breakdowns (independent / shared / backbone) are computed in one precomputed pass per page render with zero redundant container lookups.
📦 Unrouted Items — Internal Storage Chest
Items that have no route (no matching filter, no default links, or a full Blacklist filter with no space left) can now be handled in three configurable ways. A cycle button in the main menu (slot 5) lets you switch between them with a single click:
| Mode | Icon | Behaviour |
|---|---|---|
| Keep | Empty Bucket | Items stay in the source hopper. Safe default. |
| Internal Chest | Chest | Items move into a dedicated 54-slot virtual storage (double-chest size) attached to this hopper. Click the button again to open and inspect the storage. |
| Destroy | Lava Bucket | Unrouted items are permanently deleted. |
- Smart skip — Internal Chest mode is automatically skipped when default routing is already configured, since all unfiltered items already have somewhere to go. The cycle goes directly Keep → Destroy.
- Fully persisted — the virtual inventory contents and mode are saved across all five storage backends (YAML, JSON, DAT, MySQL, MariaDB). Items survive server restarts.
- Open from GUI — when Internal Chest mode is active, clicking the button opens the 54-slot inventory directly in the GUI. All standard Minecraft inventory interactions work inside it.
🌐 Cross-Dimensional Flat Cost
A new config option controls how much linking a cross-dimensional container costs on top of the normal Manhattan distance fee:
# config.yml
cross-dim-flat-cost: 0 # default: 0 (free — distance only)
- Set to 0 — no extra charge; cross-dim links cost only distance, exactly like same-world links.
- Set to any positive number — that many hoppers are charged once per new destination world when the first link to that world is created.
- Shared across routes — if you already have a link to the same destination world, the flat fee is not charged again. The portal infrastructure is considered shared, consistent with how same-world shared routes work.
- Multi-link batches — when linking multiple containers at once (region link, wand), each new destination world encountered in the batch pays the fee only once.
- Refunds — the flat fee is refunded when the last link to a given world is removed, using the same orphaned-route logic as distance refunds.
Seamless logistics. Independent routes. Precision filtering.
WarpHopper 3.5-pre – Next-Generation Wireless Logistics. Zero Lag.
