Skip to content

Instantly share code, notes, and snippets.

@Jackzmc
Created March 28, 2024 18:50
Show Gist options
  • Save Jackzmc/49ac32a64a37d9226b389e89bf6bf172 to your computer and use it in GitHub Desktop.
Save Jackzmc/49ac32a64a37d9226b389e89bf6bf172 to your computer and use it in GitHub Desktop.

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)

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

Built in Commands

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

  • &lt;param**>** indicates a required parameter (<> should not be included)
  • [param] indicates an optional parameter (<> should not be included)

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>

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

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

The number of current viewers of live view

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", can be "builtin"


Client → Server Packets (Records)

Multiple records can be included per packet, they are separated by ASCII Record Separator 0xE1. Client → Server Packets are always suffixed by a newline \n character.

The end of a record is then indicated by:

  • Presence of a newline character \n(LF) 0x0A
  • Presence of a record separator RS 0xE1

LiveRecordType Enum

Name

Value

Game

0

Player

1

Survivor

2

Infected

3

Finale

4

Survivor Items

5

Command Response

6

Auth

7

Record: Auth

Field

Type

Value

Type*

Byte

LiveRecordType.Auth (7)

Token*

String

JWT token, generated from panel

Record: Command Response

Field

Type

Value

Type*

Byte

LiveRecordType.CommandResponse (6)

ID*

Byte

The ID that was specified when command was sent

Result*

Byte

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

-1 is for command does not exist

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)

In Transition*

Byte

Is the server transitioning to the next map

Gamemode*

String

The current gamemode

Map*

String

The current map

Record: Player

The first 3 fields are always given, if the last 3 fields are missing this is a disconnection and the player should be removed from your cache.
Typically, this record is followed with either [SurvivorRecord + SurvivorItemsRecord] or InfectedRecord

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

Is Idle

Byte

Is the player idle (thus, the following survivor records are for their bot)

Join Timestamp

Byte

Unix timestamp (seconds).

When player first joined campaign, shouldn't reset during 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment