This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Introduction
The Server and Player Details Protocol was added in ViaVersion 5.3.0. It allows ViaVersion platforms to exchange information about connected players and the server or application they connect to.
The protocol uses custom payload channels and is optional.
Protocol Types
There are two protocol parts:
| Protocol | Direction | Purpose |
|---|---|---|
| Player Details | Player → Server / Proxy | Information about the player’s client |
| Server Details | Server / Proxy → Player | Information about the server |
Both may be used during the same connection.
Channels
Each Via platform sends at most one payload per channel.
| Channel | Source |
|---|---|
vv:mod_details |
Client mods |
vv:app_details |
Standalone apps (e.g. ViaProxy) |
vv:proxy_details |
Proxies |
vv:server_details |
Backend servers |
Payload Format
All payloads are UTF-8 encoded JSON objects.
Specification Version
Every payload must include a specification version:
{
"specVersion": 1
}
| Field | Description |
|---|---|
specVersion |
Protocol specification version |
Player Details Protocol
Direction: Player → Server / Proxy
Player Details payloads describe the player’s client.
Example
{
"specVersion": 1,
"platformName": "ViaFabricPlus",
"platformVersion": "3.3.1",
"version": 760,
"versionName": "1.19.4",
"versionType": "RELEASE"
}
Fields
| Field | Description |
|---|---|
platformName |
Via platform name |
platformVersion |
Via platform version |
version |
Client protocol version |
versionName |
Client version name |
versionType |
See here |
Version types
| Value | Description |
|---|---|
CLASSIC |
Classic versions (0.0.2a – 0.30) |
ALPHA_INITIAL |
Alpha 1.0.0 – 1.0.17 |
ALPHA_LATER |
Alpha 1.1.0 – 1.2.6 |
BETA_INITIAL |
Beta 1.0 – 1.1_02 |
BETA_LATER |
Beta 1.2 – 1.9-pre6 / 1.0.0-RC2 |
RELEASE_INITIAL |
1.0.0 – 13w39b |
RELEASE |
13w41a → latest |
SPECIAL |
Non-standard versions (e.g. April Fools) |
Platform Behavior
- ViaFabric / ViaFabricPlus / ViaForge
Send
vv:mod_detailsto the server. - ViaProxy
Sends
vv:app_detailsto the server. - Proxies (Velocity, BungeeCord)
May send
vv:proxy_detailsto the backend server when acting as the endpoint. - Backend servers (Paper, Spigot)
May send
vv:server_detailsfor internal use / other plugins.
Caution
Please be aware that custom payload data can of course spoofed by players. The
vv:proxy_detailschannel is only validated when ViaVersion is present on the proxy. If such spoofing can cause issues on your end, add a configuration to your plugin and have the custom payload listeners disabled by default.
Server Details Protocol
Direction: Server / Proxy → Player
Server Details payloads describe the server version the player is connected to.
Example
{
"specVersion": 1,
"version": 762,
"versionName": "1.20.2",
"versionType": "RELEASE"
}
Fields
| Field | Description |
|---|---|
version |
Server protocol version |
versionName |
Server version name |
versionType |
See here |
Platform Behavior
- Backend servers send
vv:server_detailsto the client. - Proxies send
vv:proxy_detailsto the client. - Client mods send
vv:mod_detailsto the client. - ViaProxy sends
vv:app_detailsto the client.
Multiple Platforms
During one connection:
- Multiple channels may be used
- One payload is sent per channel per platform
- Payloads may arrive in any order
Example
ViaFabricPlus → Velocity → Paper
Player receives
vv:server_detailsvv:proxy_details
Server receives
vv:mod_details
Example Plugin (Paper)
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.PluginMessageListener;
public class ExamplePlugin extends JavaPlugin implements PluginMessageListener {
private static final String CHANNEL = "vv:mod_details";
private static final Gson GSON = new Gson();
@Override
public void onEnable() {
getServer().getMessenger().registerIncomingPluginChannel(this, CHANNEL, this);
}
@Override
public void onDisable() {
getServer().getMessenger().unregisterIncomingPluginChannel(this);
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] bytes) {
if (!CHANNEL.equals(channel)) {
return;
}
JsonObject payload = GSON.fromJson(new String(bytes), JsonObject.class);
int version = payload.get("version").getAsInt();
String name = payload.get("versionName").getAsString();
// Use version data
}
}