diff --git a/README.md b/README.md
index 1529194..6e9bed4 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,19 @@
# mineping
-This JavaScript library provides an implementation of the Minecraft server ping protocol. **It allows you to gather information about a Minecraft server**, such as the MOTD, current online players, server icon (Java Edition only), and more.
+[](https://www.npmjs.com/package/@minescope/mineping)
-Mirror on my [
Git](https://git.zeldon.ru/zeldon/mineping)
+A simple and efficient JavaScript library for pinging Minecraft servers. It supports both Java and Bedrock editions through a async/await-friendly API.
+
+`@minescope/mineping` automatically resolves SRV records for Java servers and parses rich status data, including MOTD, player counts, version info, and server icons. Comes with full TypeScript support.
+
+*Mirror on my [
Git](https://git.zeldon.ru/zeldon/mineping)*
+
+## Features
+
+- **Dual Protocol Support:** Ping both Java and Bedrock servers with a consistent API.
+- **SRV Record Resolution:** Automatically resolves SRV records for Java Edition servers, so you don't have to worry about custom ports.
+- **Rich Data:** Parses the full response from servers, including player samples, favicons, gamemodes, and more.
+- **Lightweight:** Has only **one** runtime dependency — [debug](https://www.npmjs.com/package/debug) (used for tracing).
## Requirements
@@ -12,22 +23,56 @@ Mirror on my [
import("@minescope/mineping").then((module) => module.pingBedrock(...args));
```
-## Usage
+## Debugging
-Ping a Java server with default options:
+`mineping` uses the [`debug`](https://www.npmjs.com/package/debug) library to provide detailed tracing information, which can be useful for diagnosing connection issues or understanding the library's internal workings.
-```js
-import { pingJava } from "@minescope/mineping";
+To enable debug logs, set the `DEBUG` environment variable when running your script. The library uses two namespaces:
-const data = await pingJava("mc.hypixel.net");
-console.log(data);
+- `mineping:java` for the Java Edition pinger.
+- `mineping:bedrock` for the Bedrock Edition pinger.
+
+### Examples
+
+**Enable all `mineping` debug logs:**
+
+You can use a wildcard (`*`) to enable all logs from this library.
+
+```bash
+DEBUG=mineping:* node your-script.js
```
-Ping a Bedrock server with custom options:
+
+Click to see output for DEBUG="mineping:*" node examples/01-basic-ping.js
-```js
-import { pingBedrock } from "@minescope/mineping";
+```bash
+DEBUG="mineping:*" node examples/01-basic-ping.js
+ mineping:java pinging Java server hypixel.net with options: {} +0ms
+ mineping:java attempting SRV lookup for _minecraft._tcp.hypixel.net with 5000ms timeout +2ms
+ mineping:java SRV lookup successful, new target: mc.hypixel.net:25565 +2ms
+ mineping:java creating TCP connection to mc.hypixel.net:25565 +0ms
+ mineping:java socket connected to mc.hypixel.net:25565, sending packets... +182ms
+ mineping:java received 1440 bytes of data, total buffer size is now 1440 bytes +130ms
+ mineping:java packet incomplete, waiting for more data +0ms
+ mineping:java received 12960 bytes of data, total buffer size is now 14400 bytes +1ms
+ mineping:java packet incomplete, waiting for more data +0ms
+ mineping:java received 1601 bytes of data, total buffer size is now 16001 bytes +129ms
+ mineping:java received raw JSON response +0ms
+ mineping:java successfully parsed full response +0ms
+ mineping:java cleaning up resources for mc.hypixel.net:25565 +0ms
+--- Java Server ---
+{
+ version: { name: 'Requires MC 1.8 / 1.21', protocol: 47 },
+ players: { max: 200000, online: 28654, sample: [] },
+ description: ' §aHypixel Network §c[1.8-1.21]\n' +
+ ' §6§lSB 0.23 §2§lFORAGING §8§l- §e§lSUMMER EVENT',
+ favicon: 'data:image/png;base64,iVBORw0K'... 5738 more characters
+}
-const data = await pingBedrock("mco.mineplex.com", {
- port: 19132,
- timeout: 500,
-});
-console.log(data);
+====================
+
+ mineping:bedrock pinging Bedrock server geo.hivebedrock.network:19132 with 5000ms timeout +0ms
+ mineping:bedrock sending Unconnected Ping packet to geo.hivebedrock.network:19132 +1ms
+ mineping:bedrock packet: +0ms
+ mineping:bedrock received 124 bytes from geo.hivebedrock.network:19132 +104ms
+ mineping:bedrock received raw MOTD string: MCPE;BEDWARS + BUILD BATTLE;121;1.0;13074;100001;-4669279440237021648;Hive Games;Survival +0ms
+ mineping:bedrock cleaning up resources for geo.hivebedrock.network:19132 +0ms
+--- Bedrock Server ---
+{
+ edition: 'MCPE',
+ name: 'BEDWARS + BUILD BATTLE',
+ levelName: 'Hive Games',
+ gamemode: 'Survival',
+ version: { protocol: 121, minecraft: '1.0' },
+ players: { online: 13074, max: 100001 },
+ port: { v4: undefined, v6: undefined },
+ guid: -4669279440237021648n,
+ isNintendoLimited: undefined,
+ isEditorModeEnabled: undefined
+}
```
+
-> More complex example can be found in the `example` folder!
+**_PowerShell_ uses different syntax to set environment variables:**
+
+```powershell
+$env:DEBUG="mineping:*";node your-script.js
+```
## Acknowledgements
-Special thanks to the following projects:
+Special thanks to the following projects for inspiration and protocol details:
- [mcping](https://github.com/Scetch/mcping) crate for Rust
-- [mcping-js](https://github.com/Cryptkeeper/mcping-js) library for quering Minecraft Java Edition servers
+- [mcping-js](https://github.com/Cryptkeeper/mcping-js) library for querying Minecraft Java Edition servers
+- The amazing community at [minecraft.wiki](https://minecraft.wiki/) for documenting the protocols.
diff --git a/example/parallel.js b/example/parallel.js
deleted file mode 100644
index 9a1e641..0000000
--- a/example/parallel.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { pingBedrock } from '../index.js';
-
-const hosts = [
- 'play.timecrack.net',
- 'geo.hivebedrock.network',
- 'oasys-pe.com',
- 'play.galaxite.net',
-];
-
-const pingPromises = hosts.map(host => pingBedrock(host));
-const results = await Promise.allSettled(pingPromises);
-
-for (let result of results) {
- if (result.status === 'rejected') {
- console.error(result.reason);
- break;
- }
-
- console.log(result.value);
-}
\ No newline at end of file
diff --git a/example/single.js b/example/single.js
deleted file mode 100644
index ff3831b..0000000
--- a/example/single.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { pingBedrock } from "../index.js";
-
-const host = "0.0.0.0";
-const motd = await pingBedrock(host);
-console.log(motd);
diff --git a/examples/01-basic-ping.js b/examples/01-basic-ping.js
new file mode 100644
index 0000000..14b4ead
--- /dev/null
+++ b/examples/01-basic-ping.js
@@ -0,0 +1,19 @@
+import { pingJava, pingBedrock } from "../index.js";
+
+try {
+ const javaData = await pingJava("hypixel.net");
+ console.log("--- Java Server ---");
+ console.log(javaData);
+} catch (error) {
+ console.error("Could not ping Java server:", error);
+}
+
+console.log("\n" + "=".repeat(20) + "\n");
+
+try {
+ const motd = await pingBedrock("geo.hivebedrock.network");
+ console.log("--- Bedrock Server ---");
+ console.log(motd);
+} catch (error) {
+ console.error("Could not ping Bedrock server:", error);
+}
diff --git a/examples/02-error-handling.js b/examples/02-error-handling.js
new file mode 100644
index 0000000..819c94a
--- /dev/null
+++ b/examples/02-error-handling.js
@@ -0,0 +1,14 @@
+import { pingJava } from "../index.js";
+
+const offlineServer = "this.server.does.not.exist";
+const port = 12345;
+
+console.log(`Pinging an offline server: ${offlineServer}:${port}`);
+
+try {
+ // We set a short timeout to fail faster.
+ const data = await pingJava(offlineServer, { port, timeout: 500 });
+ console.log("Success!?", data);
+} catch (error) {
+ console.error("Caught expected error:", error.message);
+}
diff --git a/examples/03-server-dashboard.js b/examples/03-server-dashboard.js
new file mode 100644
index 0000000..22a0d85
--- /dev/null
+++ b/examples/03-server-dashboard.js
@@ -0,0 +1,47 @@
+import { pingJava, pingBedrock } from "../index.js";
+
+const servers = [
+ { type: "Java", host: "mc.hypixel.net" },
+ { type: "Java", host: "play.cubecraft.net" },
+ { type: "Java", host: "an-offline-java-server.com" },
+ { type: "Bedrock", host: "geo.hivebedrock.network" },
+ { type: "Bedrock", host: "buzz.insanitycraft.net" },
+ { type: "Bedrock", host: "an.offline.bedrock.server" },
+];
+
+console.log("Pinging all servers...");
+
+// Create an array of ping promises
+const pingPromises = servers.map((server) => {
+ if (server.type === "Java") {
+ return pingJava(server.host, { timeout: 3000 });
+ } else {
+ return pingBedrock(server.host, { timeout: 3000 });
+ }
+});
+
+// Wait for all pings to complete (or fail)
+const results = await Promise.allSettled(pingPromises);
+
+// Process and display results
+const displayData = results.map((result, index) => {
+ const server = servers[index];
+ if (result.status === "fulfilled") {
+ const data = result.value;
+ return {
+ Server: `${server.type} - ${server.host}`,
+ Status: "✅ Online",
+ Players: `${data.players.online} / ${data.players.max}`,
+ Version: data.version.name ?? data.version.minecraft,
+ };
+ } else {
+ return {
+ Server: `${server.type} - ${server.host}`,
+ Status: "❌ Offline",
+ Players: "N/A",
+ Version: `Error: ${result.reason.message.slice(0, 30)}...`,
+ };
+ }
+});
+
+console.table(displayData);
diff --git a/example/cli.js b/examples/04-cli.js
similarity index 68%
rename from example/cli.js
rename to examples/04-cli.js
index 7885a11..ab51ee8 100644
--- a/example/cli.js
+++ b/examples/04-cli.js
@@ -86,31 +86,31 @@ function shouldShowHelp(args) {
function printHelp() {
console.log(`node cli.js [..]
- A simple to use, efficient, and full-featured Minecraft server info parser!
-
- USAGE:
- node cli.js [OPTIONS] --host --port --timeout
-
- OPTIONS:
- -j Use for Minecraft Java Edition
- -b Use for Minecraft Bedrock Edition
- -h, --help Show this help message
-
- --host The server address (required)
- --port The server port (default: ${JAVA_DEFAULT_PORT} for Java, ${BEDROCK_DEFAULT_PORT} for Bedrock)
- --timeout The socket timeout in milliseconds (default: ${DEFAULT_TIMEOUT})
-
- P.S. Don't use -j and -b at the same time!`);
+ A simple to use, efficient, and full-featured Minecraft server info parser!
+
+ USAGE:
+ node cli.js [OPTIONS] --host --port --timeout
+
+ OPTIONS:
+ -j Use for Minecraft Java Edition
+ -b Use for Minecraft Bedrock Edition
+ -h, --help Show this help message
+
+ --host The server address (required)
+ --port The server port (default: ${JAVA_DEFAULT_PORT} for Java, ${BEDROCK_DEFAULT_PORT} for Bedrock)
+ --timeout The socket timeout in milliseconds (default: ${DEFAULT_TIMEOUT})
+
+ P.S. Don't use -j and -b at the same time!`);
}
function printInterestingFacts() {
console.log(`Some interesting facts about MOTDs on bedrock:
- - so far they seem to exclusively use legacy color codes
- - the random style has a special impl for periods, they turn into animated
- colons that warp up and down rapidly
- - motd_2 is ignored? client displays "motd_1 - v{version}", where the
- appended version text is considered part of motd_1 for color code processing
- - motd_2 seems to mainly be used to return the server software in use (e.g. PocketMine-MP)`);
+ - so far they seem to exclusively use legacy color codes
+ - the random style has a special impl for periods, they turn into animated
+ colons that warp up and down rapidly
+ - motd_2 is ignored? client displays "motd_1 - v{version}", where the
+ appended version text is considered part of motd_1 for color code processing
+ - motd_2 seems to mainly be used to return the server software in use (e.g. PocketMine-MP)`);
}
function getDefaultPort(args) {
@@ -120,7 +120,7 @@ function getDefaultPort(args) {
async function pingJavaServer(host, port, timeout) {
const data = await pingJava(host, { port, timeout });
console.log(`Host: ${host}
-Version: ${data.version?.name} (protocol: ${data.version?.protocol})
+Version: ${data.version.name} (protocol: ${data.version.protocol})
Players: ${data.players?.online}/${data.players?.max}
Description: ${
typeof data.description === "string"
@@ -133,8 +133,8 @@ async function pingBedrockServer(host, port, timeout) {
const data = await pingBedrock(host, { port, timeout });
console.log(`Host: ${host}
Edition: ${data.edition}
-Version: ${data.version.minecraftVersion} (protocol: ${data.version.protocolVersion})
+Version: ${data.version.minecraft} (protocol: ${data.version.protocol})
Players: ${data.players.online}/${data.players.max}
Name: ${data.name}
-Gamemode: ${data.gameMode}`);
+Gamemode: ${data.gamemode}`);
}