Skip to content

Commit f683a97

Browse files
committed
feat: initial commit — HGS Query Plugin
Hytale server plugin for HytaleGameServers.net that keeps server listings up to date with real-time status data. Core: - QueryPlugin entry point extending HytalePlugin with DI (@Application) - ApiManager with scheduled async updates, dynamic interval rescheduling, and graceful shutdown notification to HGS API - Bearer token auth over HTTPS with server-controlled update intervals - State machine (NONE → VERIFYING → VERIFIED → SHUTTING_DOWN) preventing shutdown calls before successful verification Network mode: - Peer-to-peer TCP mesh with JSON line protocol - Heartbeat-based liveness tracking (5s interval, 15s timeout) - Automatic controller election via lexicographic sort of alive nodeIds - Controller broadcasts REQUEST_DATA, collects NodeSnapshots via CountDownLatch with 3s timeout, sends aggregated update to API - Graceful shutdown with broadcast + random-delay leader-of-last-resort pattern ensuring exactly one node sends the API shutdown call - Synchronized PeerConnection.send() preventing interleaved writes - Socket timeouts (30s) on all connections preventing zombie threads Data: - ServerData (address, port, name, version, MOTD, password protection, boot time) - PlayerData (online/max count, player list with UUID + username) - WorldData (default world, world count, world names) - PluginData (self plugin + all installed plugins with group/name/version) - SystemData (OS environment name) - All data classes support privacy redaction via Config toggles Configuration: - Api.json (serverId, apiToken) with placeholder validation on startup - Config.json (enabled, privacy toggles for players/system/plugins) - Network.json (nodeId, port, peer list) with isNetworkMode() guard - Jackson ObjectMapper configured with FAIL_ON_UNKNOWN_PROPERTIES=false
0 parents  commit f683a97

29 files changed

Lines changed: 1504 additions & 0 deletions

.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Maven
2+
target/
3+
pom.xml.tag
4+
pom.xml.releaseBackup
5+
pom.xml.versionsBackup
6+
pom.xml.next
7+
release.properties
8+
dependency-reduced-pom.xml
9+
10+
# Compiled class files
11+
*.class
12+
13+
# Logs
14+
*.log
15+
16+
# IntelliJ
17+
.idea/
18+
*.iml
19+
20+
# Eclipse
21+
.project
22+
.classpath
23+
.settings/
24+
25+
# VS Code
26+
.vscode/
27+
28+
# OS
29+
.DS_Store
30+
Thumbs.db
31+
32+
# Package archives
33+
*.jar
34+
*.war
35+
*.ear
36+
37+
# Temporary files
38+
*.tmp
39+
*.temp

LICENSE

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Copyright (c) 2026 Hytale Game Servers (hytalegameservers.net)
2+
3+
All rights reserved.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to:
7+
8+
1. View, read, and study the source code for personal, educational, or
9+
reference purposes.
10+
11+
2. Use the official, unmodified Software on Hytale game servers in
12+
conjunction with a valid HytaleGameServers.net account and server listing.
13+
14+
3. Submit contributions (pull requests, issues, bug reports, and suggestions)
15+
to the official repository at https://github.com/HytaleGameServers/Plugin.
16+
By submitting a contribution, you grant Hytale Game Servers a perpetual,
17+
irrevocable, royalty-free license to use, modify, and distribute your
18+
contribution as part of the Software.
19+
20+
The following actions are expressly prohibited without prior written permission
21+
from Hytale Game Servers:
22+
23+
- Modifying, adapting, or creating derivative works of the Software for
24+
redistribution, commercial use, or personal deployment.
25+
26+
- Redistributing the Software or any modified version thereof, in whole
27+
or in part, through any medium.
28+
29+
- Using the Software, its source code, or any portion thereof to circumvent,
30+
bypass, or interfere with the security measures, rate limits, API
31+
restrictions, or Terms of Service of HytaleGameServers.net.
32+
33+
- Reverse engineering the Software for the purpose of developing competing
34+
products or services, or for any malicious purpose.
35+
36+
- Removing, altering, or obscuring this license notice, copyright notice,
37+
or any branding associated with Hytale Game Servers.
38+
39+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
45+
SOFTWARE.
46+
47+
For licensing enquiries, contact: contact@hytalegameservers.net

README.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# HGS Query Plugin
2+
3+
Official Hytale server plugin for [HytaleGameServers.net](https://hytalegameservers.net) — the premier server listing platform for Hytale.
4+
5+
This plugin keeps your server listing on HytaleGameServers.net up to date by periodically sending server status, player counts, and other metadata to the API.
6+
7+
## ✨ Features
8+
9+
- 🔄 **Automatic Status Updates** — Real-time player counts, MOTD, world info, and more sent to your server listing
10+
- 🌐 **Network Mode** — Run multiple Hytale servers as a single listing with automatic controller election and peer-to-peer TCP communication
11+
-**Fully Asynchronous** — All API calls and network I/O run on asynchronous threads with zero impact on gameplay
12+
- 🔒 **Secure Communication** — HTTPS with Bearer token authentication
13+
- 🛡️ **Privacy Controls** — Toggle what data is shared: player usernames, system environment, installed plugins
14+
- 📊 **Dynamic Intervals** — 3 minute updates by default (1 minute for sponsored/real-time servers) — faster than the website's built-in Query Port polling
15+
16+
## 📦 Installation
17+
18+
1. Download the latest release from [Releases](https://github.com/HytaleGameServers/Plugin/releases)
19+
2. Place the JAR in your Hytale server's `mods/` directory
20+
3. Start your server — configuration files will be generated in `mods/HGS_Query/`
21+
4. Create an account and server listing on [HytaleGameServers.net](https://hytalegameservers.net)
22+
5. Copy your **Server ID** and **API Token** from your server's dashboard
23+
6. Paste them into `mods/HGS_Query/Api.json`
24+
7. Restart your server
25+
26+
## ⚙️ Configuration
27+
28+
### `Api.json`
29+
30+
Your server credentials. Obtain these from your server dashboard on HytaleGameServers.net.
31+
32+
```json
33+
{
34+
"serverId": "YOUR_SERVER_ID_HERE",
35+
"apiToken": "YOUR_API_TOKEN_HERE"
36+
}
37+
```
38+
39+
> 🔑 **Keep your API token private.** Do not share it publicly or commit it to version control.
40+
41+
### `Config.json`
42+
43+
General plugin settings and privacy controls.
44+
45+
| Setting | Default | Description |
46+
|---|---|---------------------------------------------------------------------|
47+
| `enabled` | `true` | Master toggle — set to `false` to disable all API communication |
48+
| `sendSystemEnvironmentName` | `true` | Include OS name (e.g. "Windows 10", "Linux") in updates |
49+
| `sendOnlinePlayerUsernames` | `true` | Include individual player usernames (player counts are always sent) |
50+
| `sendPluginInfo` | `true` | Include installed plugin list (group, name and version only) |
51+
52+
### `Network.json` (Multi-Server Only)
53+
54+
Required only if you're running multiple Hytale servers as a single listing.
55+
56+
| Setting | Default | Description |
57+
|---|---|---|
58+
| `enabled` | `false` | Enable network mode |
59+
| `nodeId` | `"DEFAULT"` | Unique identifier for this node (e.g. `LOBBY`, `SURVIVAL-1`, `FACTIONS`) |
60+
| `port` | `9800` | TCP port for inter-node communication |
61+
| `nodes` | `[]` | List of peer addresses in `"host:port"` format (do not include this node) |
62+
63+
**How network mode works:**
64+
65+
Each node runs a TCP server and connects to all configured peers. Heartbeats track liveness every 5 seconds. The node with the lowest `nodeId` (lexicographic) is automatically elected as the **controller**. The controller collects snapshots from all peers and sends a single aggregated update to the HGS API.
66+
67+
If the controller goes down, a new controller is elected automatically — no manual intervention required.
68+
69+
**Example — 3 server network:**
70+
71+
On `LOBBY` (port 9800):
72+
```json
73+
{
74+
"enabled": true,
75+
"nodeId": "LOBBY",
76+
"port": 9800,
77+
"nodes": ["192.168.1.11:9800", "192.168.1.12:9800"]
78+
}
79+
```
80+
81+
On `SURVIVAL` (192.168.1.11):
82+
```json
83+
{
84+
"enabled": true,
85+
"nodeId": "SURVIVAL",
86+
"port": 9800,
87+
"nodes": ["192.168.1.10:9800", "192.168.1.12:9800"]
88+
}
89+
```
90+
91+
On `FACTIONS` (192.168.1.12):
92+
```json
93+
{
94+
"enabled": true,
95+
"nodeId": "FACTIONS",
96+
"port": 9800,
97+
"nodes": ["192.168.1.10:9800", "192.168.1.11:9800"]
98+
}
99+
```
100+
101+
> ⚠️ All nodes must share the same `serverId` and `apiToken` in their `Api.json`.
102+
103+
## 📋 Data Collected
104+
105+
The plugin sends the following to HytaleGameServers.net:
106+
107+
- Server name, MOTD, address, and port
108+
- Current and maximum player count
109+
- Online player usernames and UUIDs (if enabled)
110+
- World names and count
111+
- Server implementation version
112+
- Installed plugins — group, name, and version only (if enabled)
113+
- System environment name (if enabled)
114+
- Password protection status (boolean only — no passwords are ever transmitted)
115+
- Server boot timestamp
116+
117+
All data is automatically cleared when your server goes offline.
118+
119+
## 🔗 API Endpoints
120+
121+
The plugin communicates exclusively with:
122+
123+
- `POST https://hytalegameservers.net/api/plugin/query/update` — Status updates
124+
- `POST https://hytalegameservers.net/api/plugin/query/shutdown` — Graceful shutdown notification
125+
126+
## ⏱️ Update Intervals
127+
128+
There are two ways your server listing stays up to date — the **plugin** (this project) and the **website's built-in Query Port polling**. The plugin is faster and takes priority.
129+
130+
| Method | Default Interval | Sponsored / Real-Time |
131+
|---|---|---|
132+
| **Plugin** (recommended) | 3 minutes | 1 minute |
133+
| **Query Port** (website-side) | 5 minutes | 1 minute |
134+
135+
> When the plugin is actively syncing with the API, the website backend will **not** query your server's Query Port — the plugin takes over entirely. Query Port polling only applies to servers that don't have this plugin installed.
136+
137+
## 📝 Requirements
138+
139+
- Hytale Server (official release)
140+
- Java 21+
141+
- Account and server listing on [HytaleGameServers.net](https://hytalegameservers.net)
142+
- Outbound HTTPS access to `hytalegameservers.net`
143+
144+
## 🔨 Building from Source
145+
146+
```bash
147+
git clone https://github.com/HytaleGameServers/Plugin.git
148+
cd Plugin
149+
mvn clean package
150+
```
151+
152+
The compiled JAR will be in the `target/` directory.
153+
154+
## 💬 Support
155+
156+
- 🌐 **Website:** [hytalegameservers.net](https://hytalegameservers.net)
157+
- 💬 **Discord:** [hytalegameservers.net/discord](https://hytalegameservers.net/discord)
158+
159+
## ⚠️ Important Notice
160+
161+
Abuse of the API or plugin is strictly prohibited. This includes attempting to bypass rate limits, sending falsified data, reverse engineering for malicious purposes, or any other violation of our [Terms of Service](https://hytalegameservers.net/terms-of-service). Violations will result in suspension or permanent termination of your server listing and account.
162+
163+
---
164+
165+
*This is an unofficial community project. Hytale is a trademark of Hypixel Studios.*

pom.xml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>net.hytalegameservers.query</groupId>
8+
<artifactId>Query-Plugin</artifactId>
9+
<version>0.0.1</version>
10+
11+
<properties>
12+
<maven.compiler.source>21</maven.compiler.source>
13+
<maven.compiler.target>21</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
17+
<repositories>
18+
<repository>
19+
<id>hytale-release</id>
20+
<url>https://maven.hytale.com/release</url>
21+
</repository>
22+
23+
<repository>
24+
<id>github</id>
25+
<url>https://maven.pkg.github.com/Trae-Maven/hytale-plugin-framework</url>
26+
</repository>
27+
</repositories>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>org.projectlombok</groupId>
32+
<artifactId>lombok</artifactId>
33+
<version>1.18.36</version>
34+
<scope>provided</scope>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>com.hypixel.hytale</groupId>
39+
<artifactId>Server</artifactId>
40+
<version>2026.02.19-1a311a592</version>
41+
<type>jar</type>
42+
<scope>provided</scope>
43+
</dependency>
44+
45+
<dependency>
46+
<groupId>io.github.trae</groupId>
47+
<artifactId>hytale-plugin-framework</artifactId>
48+
<version>0.0.1</version>
49+
<scope>compile</scope>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>com.fasterxml.jackson.core</groupId>
54+
<artifactId>jackson-databind</artifactId>
55+
<version>2.20.2</version>
56+
</dependency>
57+
</dependencies>
58+
59+
<build>
60+
<finalName>HGS-Query</finalName>
61+
62+
<plugins>
63+
<plugin>
64+
<groupId>org.apache.maven.plugins</groupId>
65+
<artifactId>maven-compiler-plugin</artifactId>
66+
<version>3.13.0</version>
67+
<configuration>
68+
<release>21</release>
69+
<annotationProcessorPaths>
70+
<path>
71+
<groupId>org.projectlombok</groupId>
72+
<artifactId>lombok</artifactId>
73+
<version>1.18.36</version>
74+
</path>
75+
</annotationProcessorPaths>
76+
</configuration>
77+
</plugin>
78+
79+
<plugin>
80+
<groupId>org.apache.maven.plugins</groupId>
81+
<artifactId>maven-shade-plugin</artifactId>
82+
<version>3.6.0</version>
83+
<executions>
84+
<execution>
85+
<phase>package</phase>
86+
<goals>
87+
<goal>shade</goal>
88+
</goals>
89+
</execution>
90+
</executions>
91+
<configuration>
92+
<createDependencyReducedPom>false</createDependencyReducedPom>
93+
</configuration>
94+
</plugin>
95+
</plugins>
96+
</build>
97+
98+
</project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package net.hytalegameservers.query;
2+
3+
import com.hypixel.hytale.server.core.HytaleServer;
4+
import com.hypixel.hytale.server.core.HytaleServerConfig;
5+
import com.hypixel.hytale.server.core.io.ServerManager;
6+
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
7+
import com.hypixel.hytale.server.core.universe.Universe;
8+
import io.github.trae.di.annotations.type.Application;
9+
import io.github.trae.hytale.framework.HytalePlugin;
10+
11+
import javax.annotation.Nonnull;
12+
13+
@Application
14+
public class QueryPlugin extends HytalePlugin {
15+
16+
public static final long BOOT_START_AT = System.currentTimeMillis();
17+
18+
public static final HytaleServer HYTALE_SERVER = HytaleServer.get();
19+
public static final HytaleServerConfig HYTALE_SERVER_CONFIG = HYTALE_SERVER.getConfig();
20+
public static final Universe UNIVERSE = Universe.get();
21+
public static final ServerManager SERVER_MANAGER = ServerManager.get();
22+
23+
public QueryPlugin(@Nonnull final JavaPluginInit javaPluginInit) {
24+
super(javaPluginInit);
25+
}
26+
27+
@Override
28+
protected void setup() {
29+
this.initializePlugin();
30+
}
31+
32+
@Override
33+
protected void shutdown() {
34+
this.shutdownPlugin();
35+
}
36+
}

0 commit comments

Comments
 (0)