Live Plugin Specification

Notes

  • client: the game server
  • server: the admin panel
  • All integers are little-endian, all strings are null-terminated
  • Enums are shown in light blue, responses are in light pink, records are in light purple
  • Fields with asterik* are always present, if not present, it may not be sent

Connection Flow

Once a socket connection is established, the client (the game server), will send a Auth Record, and the server will either respond with an OK Response, or an Error Response (with an optional message). Once the client gets the OK, it will perform a full sync and send these group of records:

  • Game Record
    • Finale Record (if finale active)
  • Player Record (per player)
    • Survivor Record (if survivor)
    • Survivor Item Record (if survivor)
    • Infected Record (if infected)

The server then will send specific records when they occur (play joins: PlayerRecord, map changes: GameRecord, etc).

Data Types

All data types are little-endian and signed

Name

Value

Byte

8-bit signed little-endian integer

Short

16-bit signed little-endian integer

Int

32-bit signed little-endian integer

Float

32-bit signed little-endian float

String

Null-terminated ASCII String

Enums

SurvivorState

Bitfield, can be any combination of values (besides None)

Name

Value

None

0

Black & White

1

In Saferoom

2

Is Calm (intensity = 0)

4

Is Boomed

8

Is Pinned (by special infected)

16

Alive

32

SurvivorMovement

Name

Value

Idle

0

Incapped

-1

Hanging From Ledge

-2

Under Attack (SurvivorState.IsPinned should be set)

-3

Walking

1

Running

2

Crouched

3

On Ladder

4

SurvivorAction

Name

Value

None

0

Being Healed

-1

Healing

1

Deploying Ammo Pack (unused)

2

Defibbing Teammate

4

Being Defibbed

5

Deploying Fire Ammo

6

Deploying Explosive Ammo

7

Pouring Gas

8

Delivering Cola

9

Pressing Button

10

UsePointScript

11

Builtin Commands

When a Run Command Response is sent, these are the available commands for the builtin namespace. The format is namespace:command

  • <param> indicates a required parameter (<> should not be included)
  • [param]indicates an optional parameter ([] should not be included)
  • Any string with spaces should be surrounded with quotes, “my argument”, otherwise it will be split as another argument

Command

Description

builtin:stop

Informs the server to exit. This ignores if there are any players online. he sourcemod plugins runs exit

builtin:request_stop

Asks the server to stop. If there is players, the Command Response record's result will be 0, if successful, will be 1.

builtin:kick <steamid or #userid> [reason:string]

Kicks the player. If game server is sourcemod, then can be STEAM_#_#_##### or #userid

builtin:ban <steamid or #userid> [time:number] [reason:string]

Bans the player. If game server is sourcemod, then can be STEAM_#_#_##### or #userid. Time will determine how long, 0 for permanent.

builtin:players

Returns the number of players, mostly used for testing

builtin:unreserve

Removes lobby reservation on compatible source engine servers

builtin:start

Not sent to server, but admin panel can start servers when it detects this.

Packets

Server → Client Packets (Responses)

LiveRecordResponse Enum

Name

Value

OK

0

Reconnect

1

Error

2

Refresh

3

RunCommand

4

The types Reconnect, Error, and Refresh have no extra arguments, only the response type field is needed

Response: OK

Sent periodically (as a heartbeat) and when the view count changes

Field

Type

Value

Response Type*

Byte

LiveRecordResponse.OK (0)

View Count*

Byte

The number of current viewers of live view

Response: Reconnect

Informs the client to reconnect. The client should wait a few seconds before performing, as this response is used from panel when it is restarting.

Field

Type

Value

Response Type*

Byte

LiveRecordResponse.Reconnect (1)

Response: Error

An error occurred, with an optional message. If during first Auth Record, then indicates auth failure, otherwise any other type of error.

Field

Type

Value

Response Type*

Byte

LiveRecordResponse.Error (2)

Message*

Byte

An optional message for the error. Blank for no message.

Response: Refresh

Requests the client to give a full refresh, same as what is performed after successful authentication ((Game+Finale) + Player + (Survivor+SurvivorItems Infected))

Field)

Type

Value

Response Type*

Byte

LiveRecordResponse.Refresh (3)

Response: Run Command

Runs a command on the client (game server). The client will return a Command Response Record if the command exists, or an Error Record if it does not.

Namespace is optionally, send a single null terminator to use default. Command Response Records should be sent in order, but an ID can be set to verify as well.

Field

Type

Value

Response Type*

Byte

LiveRecordResponse.RunCommand (4)

ID*

Byte

An id for the command, the Command Response Record will contain the same id.

Command*

String

The command to run

Namespace*

String

Optional. The namespace of commands, default is "default" or blank, or "builtin" (see Builtin Commands)


Client → Server Packets (Records)

Multiple records can be included per packet, each record has a header of it’s size, then it’s type. It’s then followed by an ASCII separator 0×1E which is just useful for debugging purposes.

Sometimes the plugin may send multiple group of records together, they will be separated by 0×0A (new line), but you should only rely on the size of records.

LiveRecordType Enum

Name

Value

Game

0

Player

1

Survivor

2

Infected

3

Finale

4

Survivor Items

5

Command Response

6

Auth

7

Meta

8

Record Headers

Field

Type

Value

Length*

Short

The length of the following record, excluding these bytes.

Type*

Byte

The type of the record

Record: Auth

This is only sent on once, on initial connection.

Field

Type

Value

Type*

Byte

LiveRecordType.Auth (7)

Version*

Byte

The version of the plugin protocol

Token*

String

JWT token, generated from panel

Port

Short

The port the server is running on, for panel to link plugin to server on that port

Game Version

String

Version of the game

Record: Command Response

The value of the Result field is determined by the Response Type field.

For non-builtins, response type is always 0 and result is always 1 (unless command does not exist)

Field

Type

Value

Type*

Byte

LiveRecordType.CommandResponse (6)

ID*

Byte

The ID that was specified when command was sent

Response Type*

Byte

-1: Result is an error

0: No response

1: Result is a boolean

2: Result is a int

3: Result is a float

Result*

Byte

The result of the command, can be boolean or a number.

Message*

String

The raw text response, may be blank.

Record: Game

Sent every time a map is loaded, and when starting a transition.

Can be re-sent by sending a Refresh response

Field

Type

Value

Type*

Byte

LiveRecordType.Game (0)

Start Timestamp*

Int

Unix timestamp (seconds).

When the plugin has started, which can be used as server uptime

Campaign Start Timestamp*

Int

Unix timestamp (seconds).

When the current campaign has started

Difficulty*

Byte

The difficulty level, in order:

Easy(0), Normal(1), Advanced(2), Expert(3)

State*

Byte

Enum, in order:

None, Transitioning(1), Hibernating(2)

Max Players

Byte

The maximum amount of players that can join.

Gamemode*

String

The current gamemode

Map*

String

The current map

Record: Player

Typically, this record is followed with either SurvivorRecord + SurvivorItemsRecord or InfectedRecord unless the state is Disconnected

Field

Type

Value

Type*

Byte

LiveRecordType.Player (0)

User ID*

Int

User ID (auto incremented for each user, for a duration of a session)

SteamID*

String

User's SteamID 2 (STEAM_#:#:#######). Is "BOT" if a fake client

Player State

Byte

Enum, in order:

[0] Normal / In-Game

[1] Connected

[2] Disconnected

[3] Idle

Join/Leave Timestamp

Byte

Unix timestamp (seconds).

If state is Disconnected, is the time when the player disconnected

Otherwise, the time will be when the player first joined the campaign. It should not reset on transitions, but it can.

Name

String

The player's name.

Record: Survivor

Represents a survivor. If a player is idle, this will be the idle player’s bot’s data.

Field

Type

Value

Type*

Byte

LiveRecordType.Player (1)

User ID*

Int

User ID (auto incremented for each user, for a duration of a session)

Is the same as the Player record

Survivor*

Byte

The survivor type

0=Nick, 1=Rochelle, 2=Coach, 3=Ellis

4=Bill, 5=Francis, 6=Zoey, 7=Louis

Temp Health*

Byte

Temp health, from pills/adrenaline

Permanent Health*

Byte

Permanent health, assumed to be max 100.
To get total health add with temp health

Flow Progress Percent*

Byte

How far through a campaign as a percent (0-100) the player is. Can go up/down

Survivor State*

Byte

Survivor state enum, see below

Movement State*

Byte

Survivor movement enum, see below

Survivor Action*

Byte

Survivor action enum, see below

Record: Survivor Items

Slots may be empty (and only include a single null terminator).

Slot 1, if the weapon was weapon_melee, the melee weapon’s name will be given instead. All other weapons retain their weapon_ prefix

Field

Type

Value

Type*

Byte

LiveRecordType.SurvivorItems (5)

User ID*

Int

User ID (auto incremented for each user, for a duration of a session)

Slot 0*

String

The weapon in slot 0 (primary)

Slot 1*

String

The weapon in slot 1 (secondary, pistols)

Slot 2*

String

The weapon in slot 2 (throwables)

Slot3*

String

The weapon in slot 3 (kit/ammo packs)

Slot 4*

String

The weapon in slot 4 (pills / adrenaline)

Slot 5*

String

The weapon in slot 5 (any carryables, ex. gascans, gnome)

Record: Infected

Represents a player-controllable special infected.

There is never a record for Infected with special type witch (7), as it’s not a player-controllable enemy.

Field

Type

Value

Type*

Byte

LiveRecordType.Infected (3)

User ID*

Int

User ID (auto incremented for each user, for a duration of a session)

Current Health*

Short

The infected's current health

Max Health*

1Short

The infected's maximum health, such as for tanks

Special Type*

Byte

Enum, starting at 0, in order:

Smoker(1), Boomer(2), Hunter(3), Spitter(4), Jockey(5), Charger(6), Witch(7), Tank(8)

Victim User ID*

Byte

If infected has a victim (hunted player, smoked player, etc), their user id.

Record: Finale

Sent every time the finale stage changes, indicates the finale is active

Field

Type

Value

Type*

Byte

LiveRecordType.Finale (4)

Finale Stage*

Byte

The current finale stage

Escape Vehicle Active*

Byte

Is the finale escape vehicle ready?

Record: Meta

Field

Type

Value

Type*

Byte

LiveRecordType.Meta (8)

Steam State

Byte

Boolean, does server have connection to steam?