feat(auction): complete matching engine and frontend components#147
Open
noahbclarkson wants to merge 188 commits intomasterfrom
Open
feat(auction): complete matching engine and frontend components#147noahbclarkson wants to merge 188 commits intomasterfrom
noahbclarkson wants to merge 188 commits intomasterfrom
Conversation
Co-authored-by: root <root@vmi3091932.contaboserver.net>
…slots, loan exploit) (#137) * fix: resolve hash mismatch between getItemHash and getMaterialHash Plain vanilla ItemStacks in Paper 1.21.4 always carry an ItemMeta even when no custom data is set, causing getItemHash() to hash just the material name (e.g. "STONE") while shop items stored via addItem() used getMaterialHash() which hashes "MATERIAL:STONE". The two hashes never matched, so getItemByStack() returned Optional.empty() for every plain item, silently breaking shop lookups, autosell pickup, and sell-GUI matching for all default material-based shop entries. Fix: when the ItemMeta carries no distinguishing data (no display name, lore, enchants, or custom model data) fall back to getMaterialHash(), keeping the two code paths consistent. * fix: restrict autosell inventory scan to storage slots only PlayerInventory.getSize() returns 41, which includes armor slots 36-39 and the off-hand slot 40. Both AutosellManager.sellInventory() and AutosellListener.scanAndSellInventory() iterated up to getSize() and used getItem(slot), meaning armor and off-hand items that match a shop entry (e.g. a diamond chestplate when DIAMOND is a shop material) could be silently sold and removed from the player. Fix: replace the getSize()-bounded loop with getStorageContents() in both call sites. getStorageContents() returns exactly slots 0-35 (the player's main inventory including hotbar), leaving armor and off-hand untouched. The slot index returned by getStorageContents() still maps 1:1 to setItem(slot, null), so item removal remains correct. * fix: remove loan repayment overpayment exploit and validate amounts Two related bugs in the loan repayment flow: 1. Overpayment money exploit repayLoanAsync() capped the actual withdrawal at paymentAmount = amount.min(currentBalance) to avoid overcharging, but then calculated overpayment = amount - currentBalance and deposited that back to the player. When amount > currentBalance the player was charged only currentBalance yet received (amount - currentBalance) as a 'refund' they never paid — a net gain of free money. Example: balance 00, player types '/loan repay 500'; they pay 00 but receive 00 back, effectively settling the loan for 00. Fix: remove the overpayment deposit entirely. paymentAmount is already capped at currentBalance so there is never a genuine overpayment to refund. 2. Non-positive amount bypass Neither LoanCommand.takeLoanWithTerm / repayLoan nor LoanManager.requestLoanInternal / repayLoanAsync validated that the supplied amount is positive. A negative loan amount passed the maxLoan ceiling check (negative < 100) and then deposited a negative value via economy.depositPlayer(), which many Vault implementations treat as a withdrawal. Similarly a negative repayment would pass economy.has() (any balance > negative) and then withdrawPlayer() with a negative value. Fix: guard at both the command layer (early return with general.invalid-amount) and the manager layer (LoanResult.error) for defense-in-depth. --------- Co-authored-by: root <root@vmi3091932.contaboserver.net>
…e on join (#138) Two bugs in PlayerListener.checkLoanWarning(): 1. Wrong placeholder key: used 'days' but messages.yml warning-due template expects 'time_left'. Result: players saw literal '<time_left>' in the message. Fix: use 'time_left' with proper time formatting (matching LoanManager.processWarnings). 2. Premature 'defaulted' message: sent 'loan.defaulted' ("Credit score reduced by X") for ACTIVE loans that are past-due but not yet processed by the scheduled tick. No penalty has been applied at that point, so this was misleading. Fix: add 'loan.overdue' message key and use it when loan is past due but ACTIVE. Co-authored-by: root <root@vmi3091932.contaboserver.net>
- ParameterPanel: add 4 quick-preset buttons (New Server, Established Market, Economy Crash, Economy Boom) that instantly fill all parameter sliders - Mobile layout: responsive Tailwind classes (sm:/lg:) across simulator page, header, price-preview, spread-chart — stacks cleanly on small screens, header nav collapses to icon-only below sm breakpoint, chart heights shrink on mobile (h-48 sm:h-64), padding adjusted throughout - README.md: added to web-optimizer/ covering project overview, local dev setup, Vercel deployment (CLI + dashboard), tech stack, and project structure
…io matrices Phase 1 of Auto-Tune Real-Price Calculator. Computes 'true' item prices from cross-server price ratio observations using least-squares optimization in log-space. ## Algorithm - Collect r[i][j] = P_i/P_j ratio matrices from m servers - Aggregate using weighted geometric mean in log-space - Build least-squares system: log(P_i) - log(P_j) ≈ log(r_ij) - Anchor one item to fix absolute scale - Solve via LU decomposition + exponentiate ## Crate Contents - src/solver.rs — compute_prices_from_servers() + compute_prices_with_config() - src/aggregation.rs — AggregationMethod enum + aggregate_ratios() - Handles sparse matrices (0.0 = missing ratio) - GeometricMean / ArithmeticMean / Median aggregation methods - src/validation.rs — validate_ratio_matrix() + find_inconsistencies() ## Tests - 14 unit tests (solver, aggregation, validation) - 14 integration tests (accuracy, sparse, weighted, error cases) - 2 doc tests - 30 total passing ## Dependencies - nalgebra 0.32 (LU decomposition) - thiserror 1.0 (error types) - approx 0.5 (test assertions)
- New /true-prices route with interactive calculator UI - PriceCalculator component for ratio matrix input - Client-side least-squares solver (browser-compatible) - Navigation updated with True Prices link - Build passes, static page generated at 3.83 kB This completes Phase 4 (Frontend Integration) scaffold. Next: API route + backend solver integration.
Phase 2+3 of the real-price-calculator system: **Phase 2: Server Authentication** - HMAC-SHA256 API key generation (32-byte random, hex-encoded) - Constant-time key comparison (timing-attack resistant) - Actix-web middleware: ApiKeyAuth validates Bearer tokens against DB - Keys stored hashed (SHA-256); raw key shown exactly once on registration **Phase 3: Data Collection API (actix-web + SQLx + PostgreSQL)** - POST /api/servers/register — register server, receive UUID + API key - POST /api/servers/:id/prices — submit ratio matrix (authenticated) - GET /api/prices/true — current true prices (least-squares solved) - GET /api/prices/history/:item — price history for any item - GET /api/servers/exchange-rates — per-server economy multiplier **Architecture:** - price-solver crate integrated as workspace dependency - JSONB storage for ratio matrices (simpler than double precision[][]) - Background tokio::spawn() for price recomputation after each submission - Weighted by player count (larger servers = more trusted data) - PostgreSQL migrations: servers, price_submissions, true_prices, price_history **Tests:** 12 passing (9 auth + 3 price computer confidence scoring) Workspace Cargo.toml created; target/ added to .gitignore
Overhauls the landing page and simulator UI with enhanced visualizations, animations, and detailed factor breakdowns. Synchronizes the TypeScript market engine logic with the core Java and Rust implementations, specifically adding distinct trader scaling to liquidity calculations. Includes a comprehensive instructions file to assist with development workflows and architectural understanding.
…tandard_with_mm scenario - Add standard_with_mm_fixed_guild (standard+MM + 2 GuildBuyers at 5% threshold) - Add exploiter_stress scenario (standard+MM + 2 Exploiters from tick 0) - Add --exploiter-stress-test: head-to-head standard+MM vs +Exploiters - Add --fine-threshold-sweep: 1%, 3%, 5%, 7%, 10% GuildBuyer threshold sweep - Add avg_spd to SimSummary for more complete spread analysis - Add MarketMaker to regression archetype map; update baselines - Remove guild_stability from regression (inherently non-deterministic: random threshold) - Fix pre-existing clippy map_clone issue in api-server price_computer.rs - 5/5 regression: PASS (avg displacement 0.000% across all scenarios)
Built the exchange rate fetching and display system: - ExchangeRate model: server exchange rate vs global true-price baseline (rate > 1 = more expensive, < 1 = cheaper) - ExchangeRateService: fetches from /api/servers/exchange-rates on the shared API server, stores in-memory cache, refreshes on configurable interval (default 15 min). Enabled only when price-reporter is configured. - ExchangeRateConfig: exchange-rate.enabled + fetch-interval-minutes in config.yml (defaults to true / 15 min) - TaskScheduler: schedules periodic fetch (30s delay on startup, then every N min) - /at admin exchange: shows all servers' exchange rates, local server's own rate, and how many servers are contributing data Also fixed: ExchangeRateService private record field name (serverId as String, matching actual JSON UUID string from PostgreSQL/serde).
Bug fixes: - compute_avg_volatility: was using query_row (1 row only) → fixed to prepare+query+query_map to collect all 14 daily price samples. Volatility was reporting 0.0000 for ALL scenarios; now correctly ~0.05-0.20. - SPD display: sweep functions used avg_bpd for SPD column → fixed to avg_spd New scenarios: - guild_stability_mm_fixed_guild: guild_stability player mix + MM + 2 GB @ 7%. This is the best-performing config from prior runs (D/G 1.76x, vol 0.007, GDP 898K in single-seed). Deterministic 7% threshold replaces the non-deterministic random-threshold guild_stability. - exploiter_cap_test: 1 Exploiter (=5% of 12 players). Tests whether a capped Exploiter population provides buy/sell balance without the hyperinflation seen at 2 Exploiters. New CLI: - --multi-seed-compare: runs guild_stability at 7% vs 10% threshold, 5 seeds each (10 total runs). Reports mean ± std for GDP, D/G, buy ratio, vol. Regression suite: - Replaced marketmaker_test (random GuildBuyer thresholds, non-deterministic) with guild_stability_mm_fixed_guild (fixed 7% threshold, fully deterministic). Regression suite is now fully deterministic across all scenarios. analyzer.rs: - analyze_dir: changed spread column from avg_bpd → avg_spd (more useful for spread health assessment).
1. MarketEngine: make loadOverrideCache() final — eliminates ConstructorCallsOverridableMethod (field/method not final was the root) 2. ShopManager: suppress ConstructorCallsOverridableMethod — false positive, private loadCache()->loadDefaultItems()->public addItem() only reachable after object fully constructed 3. SellGuiListener: suppress AssignmentToNonFinalStatic — Guice @singleton guarantees single instance, instance=this in constructor is safe 4. ExchangeRateService: rename field lastFetchedAt->lastFetchedAtInstant — eliminates AvoidFieldNameMatchingMethodName (field conflicted with accessor) Violations: 104 → 100. Build passes clean.
Players can now click 'Set Alert' on any item to open a modal dialog that generates the /autotune alert add command. Dialog includes: - ABOVE/BELOW direction toggle (color-coded) - Price input pre-filled with current buy price - Live command preview - Copy-to-clipboard button - Expandable help explaining how alerts work No more guessing the command syntax — click, set price, copy, paste in-game.
Players can no longer have orders locked in escrow forever.
Changes:
- AuctionOrder: add expiresAt field + EXPIRED status
- AuctionRepository: add expires_at to all queries; add findExpiredOrders()
- AuctionManager: inject AuctionConfig, wire expiresAt into order creation,
add processExpiredOrders() for BUY refund and SELL item return
- TaskScheduler: register periodic expiration check (default every 15 min,
configurable in config.yml)
- ConfigManager: parse auction config section
- AutoTuneConfig: add AuctionConfig record
- config.yml: add auction.{default-duration-hours, expiration-check-interval-minutes}
- V1__Initial_Schema.sql: add expires_at NOT NULL column
- Fix 3 test files to include AuctionConfig.defaults() in constructor
Buy orders: escrowed funds refunded on expiration. Sell orders: items
returned to inventory if player is online (or left as EXPIRED in DB for
later /auction reclaim). Players notified by in-game message.
Players who were offline when their sell orders expired couldn't get their items back. Now /auction reclaim finds all EXPIRED sell orders for the player and returns the items to their inventory (marks as RECLAIMED in DB). New OrderStatus: RECLAIMED New repo query: findExpiredSellOrdersByPlayer(playerUuid) New manager method: reclaimExpiredOrders(Player) + getExpiredSellOrdersForPlayer New command: /auction reclaim
New archetype: InsiderTrader (Archetype variant + decide logic + GUI panel)
**Design**: Mean-reversion player. Tracks rolling price history per item.
When price < rolling_mean * (1 - threshold) → BUY (expecting rebound).
When price > rolling_mean * (1 + threshold) → SELL (expecting pullback).
Near mean → neutral.
Distinct from:
- Exploiter: rides momentum (buy when rising), InsiderTrader fades it
- MarketMaker: posts around perceived fair value, InsiderTrader exploits
deviations from recent price history
- ValueBuyer: uses static perceived_values, InsiderTrader uses live price history
Insight from testing:
- MM reduces avg_vol from ~0.19 (no MM) to ~0.006 (2 MM+GB) — 30x stabilization
- InsiderTrader with 2 ITs added to standard+MM: vol 0.0207→0.0310 (worse)
→ In Farmer-dominated sell-heavy economy, ITs buy dips which are plentiful,
adding more buy pressure without creating new sell pressure
→ ITs work better in balanced or slightly buy-dominated economies
→ MM remains the primary stabilizing mechanism; IT is supplementary
Also:
- Multi-seed compare now tests GuildStability+MM (1MM+1GB) across 5 seeds
- insider_trader_test scenario added
- 5/5 regression PASS
…oard Adds browser-accessible economy health diagnostics for remote admins who can't be in-game to run /at admin health. Java plugin: - WebServer: inject ShopManager + LoanManager - New GET /api/admin/health endpoint — mirrors in-game health command as JSON (GDP, debt, D/G ratio, circuit breaker tier, buy ratio, avg spread, volume multiplier, inflation label, top 5 volatile and undersold items) - adminHealthData() refactored from AdminCommand into WebServer using the same calculations and thresholds web/ frontend: - New /admin page with health score badge (0–100), key metric cards (GDP, debt, D/G ratio, trade mix, avg spread, volume activity), top volatile + undersold items tables, circuit breaker tier legend - Admin link added to header navigation (desktop + mobile) - Auto-refreshes every 15s - Graceful error state when API unreachable PMD: 105 violations (all style — unchanged from pre-commit)
Adds guild economy dashboard as a new player-facing feature: - /guild — shows your guild's economy stats (volume, net position, debt, etc.) - /guild stats <tag> — view a specific guild's stats - /guild top — top 10 guilds by trading volume Guild detection: uses Vault Permission groups as guild identifiers. Guild membership is synced on player join and persisted in at_players.guild_tag. If no Vault permission provider is available, guild features silently degrade. Schema: added guild_tag VARCHAR(64) NULL to at_players table. Also adds: - GuildService with GuildStats record aggregating member data - Vault Permission setup in AutoTune (non-fatal if absent) - Permission provider in AutoTuneModule for DI - PlayerListener now syncs Vault group → guild_tag on join Closes PLAN.md: guild economy dashboard (engagement driver)
…API docs page - Expand feature-cards from 3 to 6: add Guild Economy Dashboard, Auction House, Price Alerts, and Cross-Server True Prices - Add /api-docs page: full HTTP API reference covering server registration, price submission, true-prices, exchange-rates, error codes, rate limits, and auth - Add API docs link to header navigation
Players can now look up any other player's portfolio via the web
dashboard. Shows holdings, average buy prices, unrealized P&L, vault
balance, active loans, and net worth — all computed from the last
90 days of transaction history.
Java:
- PortfolioService: aggregates transaction history → holdings with P&L
- PortfolioDto: data transfer record for the portfolio payload
- WebServer: new GET /api/portfolio/{playerName} endpoint
- EconomyManager: add getBalance(OfflinePlayer) overload for web context
- PlayerRepository: add findByName() lookup
- ItemRepository: expose getJdbi() for raw SQL queries
Web:
- /portfolio page with player search, summary cards, holdings table,
and active loans panel
- Portfolio link in nav header
- TypeScript types + api.portfolio.get()
- Add MarketEvent model (types: DEMAND_SURGE, SUPPLY_GLUT, INFLATION_BOOST, DEFLATION_DROP, GOLD_RUSH, CUSTOM) - Add MarketEventRepository (JDBI persistence) - Add MarketEventService (event lifecycle, price multiplier application) - Hook into MarketEngine.calculateNewPrice() to apply price change multipliers - Add /at event command (list, active, trigger, cancel, info) - Add at_market_events DB table - Add market-events config section (YAML template + defaults) - Fix test fixtures (MarketEngineTest, LoanManagerTest, EconomyManagerTest) - Use Locale.ROOT for case-insensitive material matching Market events amplify/dampen price velocity for matching items without overriding natural market forces. Players see chat broadcasts when events start/end. Admins can trigger events with custom materials, multipliers, and durations via command. Co-authored-by: Arc <arc@noah.dev>
…cleanup Issue: data.db grows unbounded because DatabaseCleanupManager only pruned three of nine tables. The auction order book and fill history accumulated forever, as did ended market events. Changes: - CleanupConfig: added auctionOrders, auctionFills, marketEvents fields - ConfigManager.parseCleanupConfig: parse new cleanup sections from YAML - AuctionRepository: add deleteOrdersOlderThan(), deleteFillsOlderThan(), countOrders(), countFills() - MarketEventRepository: add deleteEndedOrCancelledOlderThan(), count() - DatabaseCleanupManager: clean up auction orders (terminal status older than retention), auction fills (older than retention), market events (ENDED/ CANCELLED older than retention); inject AuctionRepository, MarketEventRepository, DatabaseManager; update CleanupStats to include new table counts - AutoTuneModule: provide DatabaseCleanupManager singleton - config.yml: document new cleanup sections with default retention days (orders: 30d, fills: 60d, events: 7d) Config defaults are conservative — admin can tune per-server needs. Active OPEN/PARTIALLY_FILLED auction orders are never deleted by cleanup.
New src/events.rs — mirrors Java MarketEventService.java: - 6 event types: DEMAND_SURGE, SUPPLY_GLUT, INFLATION_BOOST, DEFLATION_DROP, GOLD_RUSH, CUSTOM - Pattern matching: exact, PREFIX_*, *_SUFFIX, *MIDDLE* - apply_event_multiplier() — sums all matching event effects - 10 unit tests, all passing Integration: - engine.rs: calculate_new_price() applies events after trend dampening - simulation.rs: Simulation.events field, active events filtered per tick - main.rs: Scenario.events field, market_event_test scenario, all 14 existing scenarios initialize events=Vec::new() Regression: 5/5 PASS (0.000% delta) — non-event scenarios unaffected. New market_event_test: 14-day standard+MM+GB economy with all 4 event types across different time windows. Formula verification: Java computeEventEffect() behavior confirmed (Java comments describe intent; actual implementation uses suppressed vs extra as documented in MEMORY.md).
New /at admin audit command runs a comprehensive system health check covering 5 areas and reports actionable issues to admins: - Vault & dependencies: checks Vault Economy provider is registered - Configuration: validates baseSpread, maxPriceChange, tick interval, loan interest rates, exchange rate fetch status, cleanup interval - Economy state: GDP sanity, Debt/GDP ratio, stale snapshots, expired overrides, stale item prices (no history in 7 days) - Database: table sizes, large-table warnings (>1M transactions or >5M market history rows), stuck market events count - Circuit breaker: tier/badge, interest multiplier, overdue loans Each check returns ✅ /⚠️ / ❌ with a specific explanation. Summary line at the end tells admins how many issues need attention. Also adds LoanManager.getOverdueLoans() helper (no-side-effect read). DatabaseCleanupManager.CleanupStats was already public — used directly.
…hart, events panel web-optimizer now models the full Auto-Tune market event system: - market-engine.ts: MarketEvent interface, EventType enum, matchesMaterialPattern(), computeEventEffect() (mirrors Java MarketEventService.computeEventEffect exactly), applyEventMultipliers(), getNetEventMultiplier(), simulatePriceWithEvents() - MarketEventsPanel: add/remove events with type selector, multiplier, material search, and quick presets (ore families, gold family, building blocks, etc.) - ProjectionChart: SVG price trajectory — shows baseline vs with-events lines, material selector synced with page state, 60-tick horizon (5h at 5min ticks) - Simulator page: events panel in left column, projection chart above price preview - computeEventEffect verified against Java: DEMAND_SURGE/SUPPLY_GLUT asymmetric, INFLATION_BOOST/DEFLATION_DROP always-positive/negative drift, GOLD_RUSH/CUSTOM symmetric amplification. Matches Rust events.rs exactly.
The shadow JAR minimize plugin was stripping META-INF/versions/ from Guice's multi-release JAR, breaking Paper's classloader and causing 'zip file closed' errors on plugin load. Additionally, Guice's complex SPI/service-loading behavior doesn't survive relocation in Paper's plugin classloader hierarchy. Fixes: 'zip file closed' / 'zip file error' on Paper 1.21.4 startup.
- next.config.js: add outputFileTracingRoot to tell Next.js the workspace root explicitly (silences the multiple lockfiles warning) - package.json: add overrides.eslint-visitor-keys to ^3.0.0 — v5.x (pulled in by ESLint 9.x) requires Node.js 20.19+, but the env has 20.10.0. The override pins a compatible v3 version.
The minimize{} block was causing 'zip file closed' errors in Paper's
plugin classloader. Even with selective excludes, it strips META-INF
entries and versioned classes that Paper's classloader depends on during
plugin initialization.
Relocation already provides namespace isolation from other plugins.
Size reduction is not worth the classloader instability. JAR grows from
~22MB to 30MB — negligible for a server plugin.
…d view toggle web-optimizer/: ChangelogSection — timeline of 6 recent commits with icons, tags, dates web-optimizer/: CompareSection — Auto-Tune vs Essentials/ShopGUI+/PlayerShops feature matrix web/: ItemGrid component — card-based browse view with mini spread bars web/items: table/grid view toggle (LayoutGrid/List icons in header bar)
Shadow JAR relocation (merging classes into relocated namespaces) is incompatible with Paper's PaperPluginClassLoader on Paper 1.21.4. The classloader's ZIP lifecycle management conflicts with shadow's merged classpath, causing 'zip file closed' errors during class loading. Paper's plugin classloader already isolates plugins from each other. Namespace relocation is unnecessary and harmful in this environment. The JAR is now a flat merge at original package paths (30MB). Build passes, plugin should load cleanly on Paper 1.21.4.
Root cause: 'zip file closed' errors on Paper 1.21.4 were caused by the shadow JAR merging multiple multi-release JARs (sqlite-jdbc, mariadb) into one bundle. The merged META-INF/versions/ entries combined with Paper's ClassloaderBytecodeModifier create a race condition that closes the JAR ZIP while classes are still being loaded. Fix: Remove shadow JAR entirely. Dependencies are now declared in paper-plugin.yml's libraries: section and Paper downloads+manages them at runtime. The plugin JAR contains only plugin classes (~1.2MB vs 30MB before). This avoids all multi-release JAR conflicts and classloader lifecycle issues in Paper's plugin classloader. Breaking change: plugin JAR no longer bundles dependencies. Requires Paper to download libraries from Maven Central on first load.
Revert to original shadow JAR with relocate+minimize (guice excluded). This was the working configuration before recent misguided changes. The libraries: section in paper-plugin.yml caused Paper to download deps alongside the shadow JAR creating separate classloaders — not a valid approach.
Runtime deps added to testImplementation so test classpath mirrors the bundled JAR classpath (fixes test ClassNotFoundException failures). Shadow JAR config unchanged: relocate + minimize (guice excluded). paper-plugin.yml unchanged: no libraries: section (pure shadow).
These were the real plugin load failures, masked behind the zip-file-closed classloader error. Two pre-existing Guice DI misconfigurations: 1. Server was not bound — provideGuildService requested Server but there was no binding. Added bind(Server.class).toInstance(plugin.getServer()) 2. AutoTuneConfig was not injectable — provideScoreboardManager requested AutoTuneConfig but there was no binding. Added @provides method that returns plugin.getConfigManager().getConfig()
…patibility Cloud 2.0.0-beta.14 has a Brigadier argument registration compatibility issue with Paper 1.21.11 causing 'Argument is not declared in syntax'. Disabled native Brigadier in CommandManager — commands still work via Cloud's standard annotation parser. Also fixed GuildCommand: had two @command('guild') methods and two @command('guild stats') methods causing duplicate chain registration. Collapsed to unique paths: /guild, /guild stats, /guild stats <guild>, /guild top.
createNative triggers Brigadier initialization which fails on Paper 1.21.11 due to breaking API changes in Paper's Brigadier integration (Cloud issue #132). Using the standard constructor with SenderMapper.identity() avoids Brigadier entirely — commands register via Cloud's standard annotation parser through Paper's command dispatch without native Brigadier support. Commands still work.
…1.11 Paper 1.21.11 has breaking Brigadier API changes that affect cloud-paper:2.0.0-beta.14's Brigadier integration, causing "Argument is not declared in syntax" errors during command registration. Use createNative() which nullifies brigadierManagerHolder, then additionally remove BRIGADIER and NATIVE_BRIGADIER capabilities via reflection to prevent Paper 1.21.11's Brigadier API from interfering with Cloud's annotation parsing pipeline.
Cloud v2 requires all @argument annotations to have corresponding <argument> syntax fragments in @command strings. Missing fragments cause "Argument is not declared in syntax" errors during command registration. Fixed commands: - TreasuryCommand: treasury deposit <amount>, treasury withdraw <amount> - AutosellCommand: autosell minprice <material> [price], autosell minprice remove <material> - AuctionCommand: auction browse <material>, auction sell <price> <quantity>, auction buy <material> <price> <quantity>, auction cancel <orderId>, auction history <limit> - PriceAlertCommand: alert add <material> <price> <type>, alert remove <identifier>, alert rearm <identifier>, alert toggle <identifier> - AdminCommand: admin transactions [player], admin price set <material> <price> [hours], admin price remove <material>, admin item spread <material> <value>, admin item maxchange <material> <value>, admin item info <material>, admin item reset <material> Also updates CommandManager to remove Brigadier capabilities via reflection for Paper 1.21.11 compatibility.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Auto-Tune Auction House
This PR completes the auction house infrastructure and frontend.
Backend Changes
Frontend Changes
/auctionpage routeOrderBookcomponent (bids/asks display)TradeHistorycomponentPlaceOrdercomponent with buy/sell tabsTests all pass across workspace.