8 Server and Player Details Protocol
FlorianMichael edited this page 2026-01-21 18:53:46 +01:00
This file contains ambiguous Unicode characters

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 players 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 players 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_details to the server.
  • ViaProxy Sends vv:app_details to the server.
  • Proxies (Velocity, BungeeCord) May send vv:proxy_details to the backend server when acting as the endpoint.
  • Backend servers (Paper, Spigot) May send vv:server_details for internal use / other plugins.

Caution

Please be aware that custom payload data can of course spoofed by players. The vv:proxy_details channel 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_details to the client.
  • Proxies send vv:proxy_details to the client.
  • Client mods send vv:mod_details to the client.
  • ViaProxy sends vv:app_details to 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_details
  • vv: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
  }
}