Peer Protocol

From ASSS Wiki
Jump to: navigation, search

This protocol is UDP and bi-directional. It is used by Subgame and the VIE servers.
SubSpace game servers can communicate with each other via the SubSpace Peer protocol.
Unlike most other protocols in SubSpace, the peer protocol does not make use of the SubSpace Control Protocol.
Rather, it uses lightweight datagrams and accepts packets based on a whitelist of the datagram source's (IP, port) pair.
Player lists/player count packets are sent at approximately 250ms intervals.


SendTo Command

sendto command example usage:
/*sendto zone ip, zone port
full subgame syntax is:
*sendto IP,port,arenaname
does not work for staff members being sent with staff password appended to their password

Settings

Go request (GR) definition:
Any time a client asks to go to a new arena. In Cont, when a zone is first entered, it asks to go to a NULL arena (i.e. no arena name is given). This is the same as typing "?go" in subgame (no arena name). Other clients (bots, chatnet clients, etc.) can and do sometimes ask to go to specific arenas on zone entry.

server.ini sections:
[Peers]
//must include port and be valid hostname or entire entry is ignored.
MyArenas=<ARENA SPEC>
// see below for ARENA SPEC

// maximum number of peers is 8 and # starts at 0: Peer0, Peer1, ... Peer7
[Peer<#>]
//location of peer
Address=<IP>:<PORT>
// passwords explained below
Password=testpw
//arenas to route, players will be sent upon ?go
Arenas=<ARENA SPEC>
//see below
SendOnly=0
//if least one player is in the zone, send player list packet
SendPlayerList=1

<ARENA SPEC>: A comma-separated list of arena names to match. It may not be longer than 511 characters. No more than 32 different arenas may be given. No whitespace is allowed, unless it's meant as part of the arena name. 2 special arena names are recognized, "$pub" and "$pvt". $pub matches any time no arena name is given in a GR. $pvt is the converse of $pub; it _always_ matches unless no arena name is given.

SendOnly: SendOnly could have something to do with *zone and ?alert messages. Both of these are sent in the peering protocol. SendOnly could be a boolean saying you don't want your instance of subgame to broadcast *zone and ?alert if they come from other peers, or an enum for various combinations. This should be easily testable. It could also have something to do with the sending of private (#-prefixed) arena names. edit: it could also be an <ARENASPEC>, to send player lists for only matched arenas.

GR Matching:
When a GR is issued in a zone (or more accurately, subgame instance), it first consults the list Peer:MyArenas, if it exists. If a match is found, the GR is processed normally (as if there were no peers). The purpose appears to be for use with $pvt. If you have a $pvt rule in a [Peer<#>] section to send people to another zone whenever they go to a named arena, this acts as a mask, a list of the arenas you explicitly want this subgame instance to manage.

If no match is found in Peer:MyArenas, each Peer<#>:Arenas list is consulted in order (by number, not the order they appear in the file). On the first match found, the player is transparently redirected to the address for that peer. Note that the arena name will be part of the initial GR issued when the client enters that zone. If after consulting all available peers no match is found, the request is handled normally.

Passwords:
If you decide to have 2 subgame instances peer, they must agree on a password. The password must agree in each INI [Peer<#>] entry which refers to the other zone.

Example: 2 zones running on localhost, subgame-A on port 5000 and subgame-B on port 7777

in subgame-A's ini:
[Misc]
Port=5000

[Peer3]
Address=127.0.0.1:7777
Password=hackme

and in subgame-B's ini:
[Misc]
Port=7777

[Peer1]
Address=127.0.0.1:5000
Password=hackme

Packets

All packets have the following form:
00 01 <passwordHash (4)> FF <type (1)> <timestamp (4)> <payload>
The passwordHash is a CRC32 of the peer password in server.ini. 
The payload depends on the type field and their formats are described below. 


0x01: Player List

This packet is sent if SendPlayerList=1 and at least one player is in the zone.
It lists all arenas in the zone with a list of all players in each arena.
The list of players for a given arena is null terminated as indicated by the 00 field below.
The arenaID field is a random 32-bit integer that is associated with each arena at the time of its creation.
An arena maintains its arenaID until the arena gets re-created or manually recycled.
{
  <arenaID (4)>
  <arenaName (asciiZ)>
  {
    <playerName (asciiZ)>
  }
  00
} (repeated until end of packet)


0x02: Chat Message

When a peer receives this packet, it broadcasts it as if it were a zone-wide message (*zone).
<type:0 (1)>        //currently ignored by subgame, can be anything
<message (asciiZ)>


0x03: ?alert messages

Technically exactly the same as the 0x02 packet, but as this is the result of ?help, ?cheater, etc it should be restricted to the appropriate staff members.
<type:0 (1)>        //currently ignored by subgame, can be anything
<message (asciiZ)>


0x04: Player Count

This packet is sent if SendPlayerList=0 or there are no players in the zone. The player count is the total number of players in the zone.
<playerCount (2)>

Subgame internal data structs

struct s2c_sendto
{
   BYTE   type;           // 0x3B
   DWORD  ip_addr;        // IP Address (little endian)
   WORD   port_num;       // Port number (little endian)
   WORD   join_type;      // Same as the arena login packet
   char   arena_name[16]; // Arena Name
   DWORD  loginid;
};