|
||
---|---|---|
arch-pkg@665c6eba42 | ||
libs | ||
src | ||
.gitignore | ||
.gitmodules | ||
build_releases.sh | ||
CMakeLists.txt | ||
LEARN.md | ||
LICENSE | ||
README.md | ||
run_debug.sh | ||
slpcliConfig.h.in | ||
version.txt.in |
slpcli
🚀 A simple C++ tool to query the Server List Ping (SLP) of a Minecraft: Java Edition (Notchian) server.
🔧 A naive implementation of the Server List Ping (SLP) protocol in C++ using non-boost Asio.
⭐ Enjoying this repo? A star would mean a lot.
📌 Usage
./slpcli [OPTIONS] addr [port]
POSITIONALS:
addr TEXT REQUIRED Server address with optional ":port".
port UINT Port of the Minecraft server (default 25565).
OPTIONS:
-h, --help Print this help message and exit
-s, --silent Only prints the JSON or an empty string if error.
-a, --address TEXT REQUIRED
Server address with optional ":port".
-p, --port UINT Port of the Minecraft server (default 25565).
-t, --timeout INT The timeout in seconds at which the query is dropped
--protocol-version INT
The protocol version that the client plans on using to connect to
the server. Do not change if you do not know what it means.
🛠️ Examples
🎯 Basic Usage
Without specifying a port (default port 25565):
./slpcli mc.hypixel.net
Specifying a port:
./slpcli 23.230.3.162:25572
Specifying a port (option 2):
./slpcli 23.230.3.162 25572
Real example for Hypixel, prettified with jq
:
$ ./slpcli --silent mc.hypixel.net | jq .
{
"version": {
"name": "Requires MC 1.8 / 1.21",
"protocol": 47
},
"players": {
"max": 200000,
"online": 31198,
"sample": []
},
"description": " §aHypixel Network §c[1.8-1.21]\n §6§lSB 0.23.1 §2§lFORAGING §8§l- §e§lSUMMER EVENT",
"favicon": "<trimmed for GitHub>"
}
🔍 Extracting Data with jq
Display the number of online players using jq
:
./slpcli -s purpleprison.net | jq '.players.online'
# Output: 438
🖼️ Displaying Server Favicon
Use chained bash commands with feh
to display the server favicon:
./slpcli mc.hypixel.net -s | jq .favicon -r | cut -d, -f2 | base64 -d | feh -
Save favicon as an image file:
./slpcli mc.hypixel.net -s | jq .favicon -r | cut -d, -f2 | base64 -d > favicon.png
🤫 Quiet Mode
The -s
or --silent
option suppresses diagnostic messages, outputting only the raw JSON payload or an empty string upon error. Useful for shell pipelines.
📦 Installation
Warning
The project is currently only available on Arch Linux's User Repository (AUR). On other distributions and OSes you will have to build it manually or download a binary from the Releases.
You have two main ways to install slpcli
on Arch Linux:
yay -S slpcli-git
- Install directly from the
PKGBUILD
file:
sudo pacman -S --needed git base-devel
git clone --recursive https://github.com/Urpagin/slpcli.git
cd slpcli/arch-pkg
makepkg -si
🏗️ Building
Use the provided run_debug.sh
script or build manually.
Manual Build
mkdir build && cd build
cmake ..
make -j$(nproc)
(To be improved later.)
💻 Compatibility
Platforms 🌐
Cross platform thanks to Asio
OS | Compatibility |
---|---|
Linux | ✅ YES |
macOS | ✅ YES |
Windows | ✅ YES |
Note
Manual build required on macOS and Windows. On Arch Linux you can use the AUR package.
📐 C++ Version
- Requires C++23 or newer.
📖 Integrating SLP Code in Your C++ Project
Starting from a basic project structure:
main.cpp
int main() {
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(myapp)
add_executable(myapp main.cpp)
🚩 Steps
- 📥 Clone the repository (do not omit
--recursive
):
git clone --recursive https://github.com/Urpagin/slpcli.git
- 🔗 Link the library in your project's
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.24)
project(myapp)
# Include SLP library
add_subdirectory(slpcli/libs/slp)
add_executable(myapp main.cpp)
# Link SLP library
target_link_libraries(myapp PRIVATE slp)
- 📝 Use the library in your project:
#include <iostream>
#include "slp.h"
int main() {
auto ping = slp("mc.hypixel.net");
auto response = ping.query_slp();
std::cout << response << std::endl;
return 0;
}
- 🏭 Build and run:
mkdir -p build && cd build
cmake ..
make -j$(nproc)
./myapp
⚠️ Known Issues
🔢 VarInt handling
We are storing VarInt
s as a 32-bit signed integer, however, a VarInt
is defined in the protocol with a maximum of 5 bytes, which is 35 bits.
I think this means I am not spec-compliant, but with the packets we're handling, I don't think it matters.
TODO
- Remove the small overhead of launching a new thread with
std::thread
by using an Asio-native solution (see Timeouts) / Source Code. - Add support for Bedrock Edition?
- Add a thread pool and async requests to check a text file for online MC servers.
Why not Rust?
I objectively think Rust would be better for this project. But I also think C++ is awesome and deserves some love, it is also funny how easily I can shoot myself in the foot, thrilling.