QueryHy - HTTP Server Query

Provides a configurable HTTP JSON API endpoint exposing live server stats including player count, max players, MOTD, uptime, server name, and view distance. Perfect for server lists, monitoring tools, and status pages.

File Details

queryhy-1.4.1.jar

  • R
  • Apr 30, 2026
  • 339.33 KB
  • 18
  • Early Access

File Name

queryhy-1.4.1.jar

Supported Versions

  • Early Access

[1.4.1] - Security & Stability Patch

Security

  • XSS-Fixes: Player names, UUIDs, and chat messages are now fully HTML- and JavaScript-escaped before being rendered in the dashboard. Malicious player names can no longer inject code into the browser of anyone viewing the dashboard.
  • Removed API Key via Query Parameter: The ?apiKey= URL parameter is no longer accepted. API keys must be passed exclusively via the X-API-Key header, preventing keys from appearing in server logs, browser history, and proxy caches.
  • Constant-Time API Key Comparison: Replaced String.equals() with MessageDigest.isEqual() to eliminate timing-based brute-force attacks on the API key.
  • Console XSS Protection: The dashboard remote console now escapes all command input and server responses before injecting them into the DOM.

Fixed

  • Wrong Monitor Lock in Dashboard: synchronized(onlinePlayers) was using a different lock object than all other synchronized methods (synchronized(this)), creating a potential race condition. Now consistently uses QueryServer.this.
  • Non-Atomic Chat Log Writes: addChatMessage() was performing a multi-step add/size-check/remove sequence on a synchronized list without holding the lock across all steps. The entire operation is now wrapped in synchronized(chatLog).
  • Rate Limit Cleanup Race Condition: Replaced volatile long with AtomicLong and compareAndSet() to prevent multiple threads from triggering cleanup simultaneously.
  • lastHistoryUpdate Thread Visibility: Field is now volatile to ensure changes are visible across threads.
  • Plugin NPE in Dashboard: Added a null check for QueryHyPlugin.getInstance() in DashboardHandler; returns HTTP 503 if the plugin is unavailable instead of throwing a NullPointerException.
  • HTTP Server Start Failure Silent: start() now returns a boolean; the plugin logs a SEVERE message if the HTTP server fails to bind.
  • Reload Race Condition: reloadPlugin() now explicitly calls stop() before start() instead of relying on the implicit stop inside start().
  • Client Disconnect Error: IOException during response body writes is now caught silently (client disconnected) instead of propagating as an unhandled error.
  • Invalid Config Values: Added QueryConfig.validate() which clamps all numeric settings to safe ranges (e.g. port 1–65535, dashboardRefreshSeconds β‰₯ 1). Called automatically on every config load.

Changed

  • CDN Version Pinned: Chart.js CDN reference changed from unpinned chart.js to chart.js@4.4.9 to prevent unexpected breakage from upstream updates.
  • Dashboard HTML uses StringBuilder: Replaced string concatenation in loops with StringBuilder throughout DashboardHandler.
  • Gson updated: 2.10.1 β†’ 2.11.0.
  • Version aligned: build.gradle and .hytale/project.json now both reflect version 1.4.0 / 1.4.1.