Peer SDK

From GameSpy SDK

Peer SDK

Overview

The GameSpy Peer SDK is designed to provide an in-game, lobby interface for starting peer-to-peer games. The Peer SDK does this using several other GameSpy SDKs, including Chat (for chatting), Query and Reporting 2 (for server reporting), and ServerBrowsing (for server lists and server querying), but for the most part these interfaces are hidden from you, and you only need to work with the Peer SDK calls.

The Peer SDK only deals with data. You will be responsible for creating all the GUI elements that are required for the lobby system. Typically, this includes a scrolling list control (for the games list and chat participants list) a scrolling text window (for the chat window), buttons, and a text entry line (for the chat line). You may wish to create other controls to take advantage of the more advanced features of the SDK including player cross-pings and player status indicators.

Peer is designed for games that want to provide an in-game lobby system for setting up multiplayer games. Following is a description of how a game might typically use Peer. When the player first connects, they are placed in the main chat room for the game, called the "title room". Once in the title room, you can request a list of the current games being played. A list of games that are joinable will be returned, and it will by dynamically updated to add/remove/update games as changes occur in the list. Players can choose to either join one of the existing games, or create their own. When a player creates their own game and is waiting for others to join they are placed in a separate chat room called the "staging room". As other players join the staging room, ping measurements are exchanged, which can be used to determine the quality of the connections between the players (important for peer to peer games). Players can indicate their readiness and the host can choose to launch the game when ready. Once the host sends out the launch message, everyone in the staging room can then start playing the actual game.

Due to its flexibility, there are various ways to use Peer. For example, if a game is joinable after it has been launched, the list of current games can include both games that are already running and those still in staging. The user could then have the option of joining a game in progress or joining a staging room.

Another option is to use group rooms to split the list of games into categories (by gametype, skill, region, etc.). In this case, when entering the title room, the user would get a list of group rooms instead of a list of games. They would see descriptions of the groups along with the number of players in each group. When the user selects a group, they would join that group's "group room". In here they can chat with others in the group room, and they would see a list of the games and/or staging rooms that are a part of this group. They could choose to either join one of the games, create their own room, or switch to another group.

A variation on this method would be to never join the title room - instead, the player would initially see just a list of group rooms they could join. This could help avoid people getting "stuck" chatting in the title room, without even seeing a list of games to play in. If Peer is just being used to report a game or get a list of servers, the application does not even need to connect to the chat server. After initializing and setting a title, just call peerStartReporting() to start reporting a server to the backend or peerStartListingGames() to start retrieving a server list.

File Manifest

The following files should be included with this package. If any of the files are missing, please contact devsupport@gamespy.com.

File
Description
peer.h
GameSpy Peer header (all user functions are prototypes here)
peerMain.c
Entry point for all user Peer functions
peerMain.h
Common header for internal code
peerCallbacks.c,h
Code for queueing/calling callbacks
peerSB.c,h
Code for dealing with the Server Browsing SDK
peerGlobalCallbacks.c,h
Code for chat and QR2 callbacks
peerKeys.c,h
Code for handling global and room keys
peerMangle.c,h
Converts to and from room names
peerOperations.c,h
Code for running/maintaining operations
peerPing.c,h
Code for calculating player pings
peerPlayers.c,h
Keeps track of players
peerRooms.c,h
Keeps track of rooms
peerHost.c,h
Hosting rooms
peerQR.c,h
Reproting as a server and responding to queries
peerAutoMatch.c,h
AutoMatch functionality
../nonport.c,h
Platform-specific code
../hastable.c,h
Hastable
../md5c.c,md5.h
MD5 generation
../darray.c,h
Dynamic-Array
../qr2/
Server reporting
../serverbrowsing/
Server listing
../pinger/
UDP-pings
../chat/
Chat SDK
/PeerLobby/
A sample application which uses the Peer SDK with a wizard-like interface
/PeerTest/
A test application used for testing specific Peer functionality
/PeerC/
A peer app written for the command-line in ANSI C

Implementation

Initializing

Before doing anything else, Peer must be initialized with a call to peerIntialize:

PEER peerInitialize
(
	PEERCallbacks * callbacks
);
disconnected
The chat connection has been disconnected by the server. You can attempt to reconnect with peerConnect, or shutdown with peerShutdown.
roomMessage
A chat message has arrived in one of the rooms the user is in.
roomUTM
An under-the-table message has arrived in a room the user is in.
roomNameChanged
The name of a room the user is in has changed.
roomModeChanged
The mode changed in a room the user is in.
playerMessage
A private chat message from another player has been received.
playerUTM
An under-the-table message has arrived from another player.
readyChanged
If the user is in a staging room, this will get called when one of the players changes his ready status (by default, all players are not ready).
gameStarted
If the user is in a staging room, this gets called when the host launches the game. The host's IP is available as part of the callback, as well as a text string specified by the host.
playerJoined
A player has joined one of the rooms the local player has joined.
playerLeft
A player has left one of the rooms the local player has joined.
kicked
The local player has been kicked from a room.
newPlayerList
The entire playerlist has been updated, and should be checked with peerEnumPlayers if listing players.
playerChangedNick
When joining a room, this gets called for each player in the room when his IP and profile ID becomes available.
playerFlagsChanged
A players's room flags have changed.
ping
A new average ping time has been calculated for a player in a room being pinged. Which rooms get pinged is determined when the title is set with peerSetTitle.
crossPing
A new average cross-ping time between two players is available. Which rooms get cross-pings is determined when the title is set with peerSetTitle.
globalKeyChanged
A global watch key has changed or is newly available.
roomKeyChanged
A room watch key has changed or is newly available, or a broadcast key has changed.
qrServerKey
When reporting this is used to report values for server keys.
qrPlayerKey
When reporting this is used to report values for player keys.
qrTeamKey
When reporting this is used to report values for team keys.
qrKeyList
When reporting this is used to list the keys that will be reported.
qrCount
When reporting this is used to get the number of players and the number of teams.
qrAddError
This is used to notify the application of a server reporting error.
qrNatNegotiateCallback
This is used to pass nat-negotiate cookies to the server.

Peer is initialized until peerShutdown is called:

void peerShutdown
(
	PEER peer
);

Thinking

Once peer has been initialized, peerThink must be called frequently to allow Peer to do any necessary processing, including calling callbacks and processing pings. It should be called at least every 10 ms, in order to get accurate ping times. This is typically called in the program's main loop.

void peerThink
(
	PEER peer
);

Title

Setting a title tells peer which game it should be dealing with, and should be done after peer has been initialized but before it is connected. After the title is set, peer can connect to the chat server, the title room can be joined, staging rooms can be created, and games and staging rooms can be joined. The title can later be changed without disconnecting. For information on getting your secret key, contact developer support

PEERBool peerSetTitle
(
	PEER peer, 
	const char * title, 
	const char * qrSecretKey,
	const char * sbName,
	const char * sbSecretKey, 
	int sbGameVersion, 
	int sbMaxUpdates,
	PEERBool natNegotiate,
	PEERBool pingRooms[NumRooms],
	PEERBool crossPingRooms[NumRooms]
);
peer
This is the peer object returned by peerInitialize.
title
The title for the game. This controls what serverlist hosted games show up in and what games to show in a serverlist.
qrSecretKey
This is the secret key used by the QR2 SDK (which is used by the Peer SDK).
sbName, sbSecretKey
This is the server-browsing name and secret key used by the Peer SDK (which uses the ServerBrowsing SDK).
Used to form a FilePlanet URL so the user can download the file.
sbGameVersion
This is a number that uniquely identifies this version of the game.
sbMaxUpdates
This is the maximum number of servers to update at a time. This should be 10-15 for modem users and 20-30 for high-bandwidth users.
natNegotiate
This should be set to PEERTrue if the game supports GameSpy's nat-negotation technology (or a 3rd party solution).
pingRooms
Each element in this array should be set to PEERTrue to do pings in that room, or PEERFalse not to do pings in that room. For example:
pingRooms[TitleRoom] = PEERTrue;
pingRooms[GroupRoom] = PEERFalse;
pingRooms[StagingRoom] = PEERTrue; 
crossPingRooms
Each element in this array should be set to PEERTrue to do cross-pings in that room, or PEERFalse not to do cross-pings in that room. For example:
crossPingRooms[TitleRoom] = PEERFalse;
crossPingRooms[GroupRoom] = PEERFalse;
crossPingRooms[StagingRoom] = PEERTrue;

peerClearTitle

peerClearTitle can be used to reset to no title. This can be useful during a game for freeing up resources and bandwith, while not disconnecting totally from chat. However, if the game was launched from a staging room, there will be no way to return to the staging room after the game if peerClearTitle is called.

void peerClearTitle
(
	PEER peer
);

Connecting

Once Peer is initialized and a title is set, we can connect to the chat server. This is normally done with peerConnect. However if the program needs to authenticate the user's login information with the chat server, peerConnectLogin or peerConnectPreAuth should be used. See the Logging In section for further details.

void peerConnect
(
	PEER peer,
	const char * nick,
	int profileID,
	peerNickErrorCallback nickErrorCallback,
	peerConnectCallback connectCallback,
	void * param,
	PEERBool blocking
);
peer
This is the peer object returned by peerInitialize.
nick
This is the nick with which to connect to the chat server. See below for chat nickname restrictions.
profileID
This is the local user's GP (GameSpy Presence and Messaging) profile ID. If the user doesn't have a GP account, or the profileID is not used by the program, this can be set to 0 and ignored. You can get another player's profileID with peerGetPlayerProfileID or peerGetPlayerInfoNoWait.
nickErrorCallback
If there was some sort of error with the nickname during the connection process, this callback is called. After a program receives this notice, it can either try to continue the connect with a new nickname by calling peerRetryWithNick with the new nick, or it can stop the connection attempt by calling peerRetryWithNick with a NULL nick.
If the connection attempt is stopped, then the connectCallback will be called with a failure. If there is another nick error, nickErrorCallback will be called again. PeerRetryWithNick does not need to be called immediately - the program can prompt the user to try with a new nickname, then call peerRetryWithNick after the user selects a new one.
connectCallback
This gets called when the connection attempt completes.
param
User-data passed to both callbacks.
blocking
If PEERTrue, then the call won't return until the attempt has completed.

If successful, Peer will stay connected to chat until either peerDisconnect or peerShutdown is called:

void peerDisconnect
(
	PEER peer
);

Peer uses the Chat SDK for all of its chat functionality. The CHAT object that Peer uses can also be used directly by the program to, for example, join a separate chat channel.

CHAT peerGetChat
(
	PEER peer
);

Rooms

There are three types of rooms used by Peer: title rooms, group rooms, and staging rooms. The application uses these rooms to setup the path that the user takes between initially connecting and actually getting into a game. Each room type is optional, allowing for a variety of possible setups. Here is the first of two typical paths:

  1. The user connects and is put into a title room, where he can chat with other users who are looking for a game to join. At this point the user can get a list of all joinable games, or create his own game.
  2. The user joins/creates a game. If the game is joined and is already running, the user is launched directly into the game. Otherwise, the user is put into that game's staging room, where he can talk with other users getting ready to play the game.
  3. When the user is prepared to play, he hits his "ready" button. After the host sees that everyone is ready, he hits his launch button, and everyone in the staging room gets launched directly into the game.

Another common path is similar to the above choice, but with the addition of group rooms between the title room and staging rooms (Note: to use group rooms, you must contact developer support to set them up):

  1. The user connects and is put into a title room, where he can chat with other users who are looking for a game to join. At this point the user can see a list of group rooms, possibly sorted by skill level, location, or gametype.
  2. The user picks a group and joins it. Now he can talk with other users that have chosen that group. The user can also get a list of all joinable games within the group, or create his own game within the group.
  3. The user joins/creates a game. If the game is joined and is already running, the user is launched directly into the game. Otherwise, the user is put into that game's staging room, where he can talk with other users getting ready to play the game.
  4. When the user is prepared to play, he hits his "ready" button. After the host sees that everyone is ready, he hits his launch button, and everyone in the staging room gets launched directly into the game.

Again, each room type is optional, so it is very easy to come up with a path that fits the needs of a particular game. For example, either of the above paths could be modified to skip the title room. Just don't join the title room and start off by showing a list of joinable games (or group rooms).

Title Rooms

There is one title room for each game. This is the main lobby where people can meet and chat while they look for a game to join. To join the title room, use peerJoinTitleRoom:

void peerJoinTitleRoom
(
	PEER peer, 
	const char password[PEER_PASSWORD_LEN],
	peerJoinRoomCallback callback,
	void * param,
	PEERBool blocking
);
peer
This is the peer object returned by peerIntialize.
password
An optional password for the room, usually NULL.
callback
Gets called when the join completes or fails.
param
User-data passed to the callback.
blocking
If PEERTrue, then the call won't return until the attempt has completed.

To leave the title room, use peerLeaveRoom with the roomType set to TitleRoom.

Group Rooms

For certain applications it may be desirable to split up games (either in staging or already playing) into various groups. This can be done for several reasons, including categorizing servers by region ("Europe", "Asia", "North America", etc.), or to group players by skill level ("Newbie", "Intermediate", "Expert"). Peer allows this to be done by providing group rooms. When a user enters a group room, they will be able to chat with other players in that room, get a list of games in that group, and start a game in that group. To get a list of group rooms, use peerListGroupRooms. The peerListGroupRoomsCallback will be called once for each group room, then once again with a groupID of 0 to signal that there are no more groups. If you want to use group rooms in a game, contact devsupport@gamespy.com to get them set up.

void peerListGroupRooms
(
	PEER peer,
	const char * fields,
	PeerListingGroupRoomsCallback callback,
	void * param,
	PEERBool blocking
);
peer
This is the peer object returned by peerIntialize.
fields
This is an optional backslash-delimited list of extra kye/values to get for each group room.
callback
Gets called once for each group room, and once more to signal the end of the list.
param
User-data passed to the callback.
blocking
If PEERTrue, then the call won't return until the attempt has completed.
typedef void (* peerListGroupRoomsCallback)
(
	PEER peer,
	PEERBool success,
	int groupID,
	SBServer server
	const char * name, 
	int numWaiting, 
	int maxWaiting, 
	int numGames, 
	int numPlaying,
	void * param
);
peer
This is the peer object returned by peerIntialize.
success
This will be PEERFalse if there is an error listing groups. If there is an error, there will be no more calls to the callback.
groupID
This is unique identifier for the group, and it is used when joining a group room. If there is no error, and this is 0, it is signaling that there are no more groups to be listed. If it is 0, then name will be NULL, and numWaiting, maxWaiting, numGames, and numPlaying will all be 0.
server
This server object may contain extra key/value information for this group.
name
The name of the group.
numWaiting
The number of players in the group room.
maxWaiting
The maximum number of players allowed in the group room.
numGames
The number of games currently in this group, either in staging or already running.
numPlaying
The total number of players in all of this group's games.
param
User-data passed to peerListGroupRooms.

To join a group room, use peerJoinGroupRoom. Once the room has been joined, the listing of games will be filtered so that only games that are in the same group are listed. If a game listing is in progress when a group room is joined (or left), the listing will be cleared and started over (the callback will be called with msg==PEER_CLEAR).

void peerJoinGroupRoom ( PEER peer, int groupID, peerJoinRoomCallback callback, void * param, PEERBool blocking );
peer
This is the peer object returned by peerInitialize
groupID
The ID of the group to join (as passed to the peerListGroupRoomsCallback).
callback
Gets called when the join completes or fails.
param
User-data passed to the callback.
blocking
If PEERTrue then the call won't return until the attempt has completed.

To leave a group room, use peerLeaveRoom with the roomType set to GroupRoom.

Staging Rooms

Staging rooms are chat rooms where players can join up and chat before launching into a game. To create a staging room, use peerCreateStagingRoom. Once a staging room has been created, the six QR callbacks that were specified as part of peerIntialize will be called periodically to get information on the server. This will last until the host leaves the staging room (or, if the host has started a game and then left the staging room, until the game stops).

If the user is in a group room when the staging room is created, the staging room will be reported as part of that group. This association will stick even if the player then leaves the group room.

void peerCreateStagingRoom
(
	PEER peer,
	const char * name,
	int maxPlayers,
	const char password[PEER_PASSWORD_LEN],
	peerJoinRoomCallback callback,
	void * param,
	PEERBool blocking
);
peer
This is the peer object returned by peerInitialize
name
The name to give the room.
maxPlayers
The maximum number of players to allow in the staging room.
password
An optional password for the staging room.
callback
Gets called when the create completes or fails.
param
User-data passed to the callback.
blocking
If PEERTrue then the call won't return until the attempt has completed.

peerStartListingGames is a way for the program to get a dynamic list of all games for the current title. The callback is repeatedly called to let the program know what to do to make its game list current. This continues until peerStopGames is called. If the user is in a group room, only the games for that group will be listed. If the user is not in a group room, games that are not part of any group room will be listed.

After peerStartListingGames() completes its initial list of all available game servers, it goes into automatic update mode, where game updates are propagated as they are reported by the games themselves to the master. The list of keys you receive during this update phase is determined by a specific list of push keys that have been defined for your title. Push keys come directly from the master server and avoid any NAT/firewall problems the host may be having.

The set of push keys differs from the initial list requested via the fields array, as you may care less about certain keys during updates (the hostname of a game is not likely to change e.g.). By default, the BASIC keys that are pushed from the master are: hostname, mapname, gametype, numplayers, maxplayers, country, gamemode, password and gamever. You can contact developer support and request a modified list for your title. (Please make sure to include in your e-mail the ascii names of the keys to be added, ie. "mapname", "gametype", etc.)

The maximum number of push keys that can be sent out (including the default keys) is 50. The string listing all the keys (including the delimiting backslashes) can be up to 256 characters. The total list of name value pairs returned (including backslashes) can be up to 1024 characters.

void peerStartListingGames
(
	PEER peer,
	const unsigned char * fields,
	int numFields,
	const char * filter,
	peerListingGamesCallback callback,
	void * param
);
peer
This is the peer object returned by peerInitialize
fields
An array of registered QR2 keys to request from servers.
NumFields
The number of keys in the array.
filter
This is a SQL-style filter that is applied to the initial listing of servers.
callback
Gets called each time there is a change in the game list.
param
User-data passed to the callback.
typedef void (* peerListingGamesCallback)
(
	PEER peer,
	PEERBool success,
	const char * name,
	SBServer server,
	PEERBool staging,
	int msg,
	int progress,
	void * param
);
peer
This is the peer object returned by peerInitialize
success
This will be PEERFalse if there is an error listing games. The listing stops as soon as that happens.
name
The name of the game.
server
The ServerBrowsing SBerver object for this game. This can be used to get various information about the game, including ping, number of players, player names and pings, etc. See the ServerBrowsing SDK documentation and the bottom of serverbrowsing\sb_serverbrowsing.h for further information. It is also used as a way of uniquely identifying a game. The server object for a game is the same object from the time it gets added with PEER_ADD, through any PEER_UPDATE's, until its removed with PEER_REMOVE.
The server object should be stored for each game listed as a way of identifying it when a PEER_UPDATE or PEER_REMOVE is sent for it. This parameter is NULL if the msg is PEER_CLEAR or PEER_COMPLETE.
staging
If this is PEERTrue, then this game has not been launched yet, and is still in the staging room. That means that this game can be joined with peerJoinStagingRoom. If this is PEERFalse, this game is already running. In this case, the application can just join the game whenever it wants by getting any necessary info from the server object (such as address with ServerGetAddress).
progress
When first starting to list games, an intial list of current games is received, then updated as new game are started and old games are updated or removed. While the initial listing is happening, this lets the program know what percentage of the initial list has been added so far. It will start at 0 with the PEER_CLEAR message, then rise up to 100 with the PEER_COMPLETE message. When it reaches 100, it will stay there until the listing is stopped.
param
User-data passed to peerStartListingGames.
Possible msg types are:
PEER_CLEAR
Clear the list. This has the same effect as if a PEER_REMOVE were sent for every game listed. One of these is sent initially when listing starts, and it is also sent if a group room is joined or left while games are being listed. The server object is NULL for this type.
PEER_ADD
This is a new game. Add it to the list.
PEER_UPDATE
This game is already on the list, and its been updated. To match this game up to the one in your internal list, use the server object. If the program is only listing server names this can be ignored.
PEER_REMOVE
Remove this game from the list. Use the server object to match up the game to the one in your internal list. The server object is valid during this call, but will become invalid immediately after the call, and so should NOT be used after returning from the callback.
PEER_COMPLETE
The listing of current servers is complete. The application will now get dynamic updates as servers get started, get updated, or get shutdown. The server object is NULL for this type.

To join a staging room, use peerJoinStagingRoom. NOTE: These should only be used for games listed with staging set to PEERTrue. If this is set to PEERFalse, the game is already running, and the staging room cannot be joined.

void peerJoinStagingRoom
(
	PEER peer,
	GServer server,
	const char password[PEER_PASSWORD_LEN],
	peerJoinRoomCallback callback,
	void * param,
	PEERBool blocking
); 
peer
This is the peer object returned by peerInitialize
server
The server object received when listing games.
password
The password for this room. Ignored if the room has no password.
callback
Gets called each time there is a change in the game list.
param
User-data passed to the callback.
blocking
If PEERTrue then the call won't return until the attempt has completed.

To leave a staging room, use peerLeaveRoom with the roomType set to StagingRoom.

Messaging

To send a message to a room the user is in, use peerMessageRoom:

void peerMessageRoom
(
	PEER peer,
	RoomType roomType,
	const char * message,
	MessageType messageType
);
peer
This is the peer object returned by peerInitialize
roomType
The room to send the message to: TitleRoom, GroupRoom, or StagingRoom.
message
The message to send.
messageType
The type of message to send: NormalMessage, ActionMessage, NoticeMessage.

Players

Listing

To enumerate through all of the players in a room, use peerEnumPlayers. This is done using a local list maintained by Peer, and so it will do the enumerating before returning.

void peerEnumPlayers
(
	PEER peer,
	RoomType roomType,
	peerEnumPlayersCallback callback,
	void * param
);
peer
This is the peer object returned by peerInitialize
roomType
The room for which to list the players.
callback
Gets called once for each player in the room, and then once at the end of the listing (or once if there's an error).
param
User-data passed to the callback.

This callback gets called for each player in the room:

typedef void (* peerEnumPlayersCallback)
(
	PEER peer,
	PEERBool success,
	RoomType roomType,
	int index,
	const char * nick,
	PEERBool host,
	void * param
);
peer
This is the peer object returned by peerInitialize
success
If this is PEERFalse, there has been an error.
roomType
The room for which to list the players.
index
The index of the player, from 0 to the one less than the total number of players (N - 1). Or, if this is -1, that means the enumerating has completed.
nick
The nick of this player.
host
PEERTrue if tis player is the host of the room (this is equivalent to having operator privileges in a chat channel).
param
User-data passed to the peerEnumPlayers.

Messaging

To send a private message to another player, use peerMessagePlayer.

void peerMessagePlayer
(
PEER peer,
const char * nick,
const char * message,
MessageType messageType
);
peer
This is the peer object returned by peerInitialize
nick
The nick of the player to send them message to. See Nickname restrictions for valid chat nicks.
message
The message to send.
messageType
The type of message to send: NormalMessage, ActionMessage, NoticeMessage.

Flags

Every player has a set of flags associated with them in each room they are in. Flags are reported in the peerFlagsChangedCallback, and can also be checked at any time with peerGetPlayerFlags:

PEERBool peerGetPlayerFlags
(
	PEER peer,
	const char * nick,
	RoomType roomType,
	int * flags
);
peer
This is the peer object returned by peerInitialize
nick
The nick of the player to get flags for. See Nickname restrictions for valid chat nicks.
roomType
The room to get the flags for.
flags
The address at which to store the flags.

The flags can be any combination of the following bit defines:

PEER_FLAG_STAGING
in a staging room
PEER_FLAG_READY
ready in a staging room
PEER_FLAG_PLAYING
playing a game
PEER_FLAG_AWAY
set as away
PEER_FLAG_HOST
host of the room
PEER_FLAG_OP
has operator priviliges in the room
PEER_FLAG_VOICE
has voice (+v) in the room

Launching

Once a staging room has been created, and usually after more players have joined the room, the host can launch the game itself. When the host chooses to launch the game with peerStartGame, every player in the staging room will get the peerGameStartedCallback. The game should be launched immediately after the call for the host, and as soon as the callback is called for other players. All players must call peerStopGame when either the game ends or they leave.

Ready

Each player in a staging room has a ready state, which is on or off. It is initially off when a staging room is joined. To get a player's ready state use peerGetReady. Whenever a player's ready state changes, the peerReadyChangedCallback will be called. peerAreAllReady is a utility function that checks if all the players in the staging room are ready. It can be used by the program to determine if the host can launch the game or not.To set your ready state, use peerSetReady.

Starting

When the host is ready to start the game, the program should call peerStartGame. It will cause everyone in the staging room (except for the host) to have their peerGameStartedCallback called. The host can leave the staging room once the game has started. However, the host won't be able to get back into the staging room, a new one would need to be created.

To maintain compatibility with GameSpy Arcade, the message string should be of the form "<dotted-IP>[:<port>]". Dotted-IP is the IP of the server in string form. This is optionally followed by the port the game is being hosted on. If the port is not used, the default port for the game will be assumed. To get the local IP, call peerGetLocalIP(), which returns the IP (in network byte order).

void peerStartGame
(
	PEER peer,
	const char * message,
	int reportingOptions
);
peer
This is the peer object returned by peerInitialize
message
This is a text string that all the other players will get as part of the peerGameStartedCallback. See the above paragraph for an explanation of the message.
ReportingOptions
This determines if Peer should continue reporting the game, or if it should stop and let the program take over. For games that use Peer internally, it is recommended that they set the PEER_KEEP_REPORTING flag and let Peer handle server reporting. For games that are launched externally, from GameSpy Arcade, for example, it will be necessary to stop reporting with PEER_STOP_REPORTING and let the external process take over the reporting. If Peer continues to report, PEER_REPORT_INFO and PEER_REPORT_PLAYERS can be used to control what information Peer reports.

Stopping

After the host has started a game, it has to let Peer know when the game has stopped. This is done with a call to peerStopGame. This lets Peer either stop reporting the game (if the host has left the staging room), or to return to reporting it as a staging room.

This call should also be used by clients after a game they were playing in has finished. This allows peer to correctly report if this player is in game or not.

void peerStopGame
(
	PEER peer
);

Logging In

In the Connecting section above, peerConnect is shown as the function to use when connecting to the chat server. However there are a couple of other functions that can be used to not only connect to the chat server, but to also login using account information. These two functions are peerConnectLogin and peerConnectPreAuth.

In total, there are five different options for connecting:

  1. Anonymous Login (peerConnect)

    This is the function to use if you want to connect to Peer without logging in or authenticating any user information. You will be able to use Peer normally, however you won't have uniquenicks, and there will be no way to verify that a given user is really who they say they are. The player's chat nick will be the nick passed to peerConnect. See Nickname restrictions for valid chat nicks.

  2. GameSpyID Login with no uniquenick (peerConnectLogin with a namespaceID of 0)

    This is the method to use if you want to login to the GameSpyID system, but don't want to use uniquenicks. You'll use peerConnectLogin with the email, profilenick, and password for the account you are attempting to login under, and you'll set the namespaceID to 0. This is the "null" namespace, and is used to tell Peer that it should not set a namespace. The player's chat nick will be the profilenick passed to peerConnectLogin. If the profilenick is an invalid chat nick, or is already in use on the server, the nickErrorCallback will be called. Note that the chat nickname rules apply. See Nickname restrictions for valid chat nicks.

  3. GameSpyID Login with a uniquenick in the default namespace (peerConnectLogin with a namespaceID of 1)

    This method is similar to the above method, however the namespaceID is set to 1, indicating the default GameSpy namespace. This is the same namespace that is used by GameSpy Arcade. The login information you pass to peerConnectLogin will be the profile's email, nick, and password. You do not need to pass the uniquenick for this method. The provided information will uniquely identify a GameSpyID profile account. When logging in with this method, the chat nickname will be the profile's uniquenick with "-gs" appended. "-gs" is the namespace extension for the default GameSpy namespace. For example, if a user has the uniquenick Joe, his chat nick will be "Joe-gs". peerTranslateNick can be used to strip extensions off of nicks.

    If the profile does not have a uniquenick associated with it in the GameSpy namespace, then the nickErrorCallback will be called with a type of PEER_NO_UNIQUENICK. If there is a uniquenick, but it has expired, then the nickErrorCallback will be called with a type of PEER_UNIQUENICK_EXPIRED. In either of these two cases, the application should use peerRegisterUniqueNick to register a uniquenick for the profile. If there is a problem registering the uniquenick, such as it being invalid or already in use, then the nickErrorCallback will be called again with a type of PEER_INVALID_UNIQUENICK, and the suggestedNicks field will be filled in with suggestions. In this case peerRegisterUniqueNick should be called again, and continue to be called until a valid nick is registered. When this happens, the connectCallback will be called indicating a successful login.

    peerConnectLogin should not be used with just a uniquenick and password when in the default namespace, or in any other namespace where uniquenicks can expire. This is because if a user's uniquenick has expired, and another user has since registered that uniquenick, then the user will no longer be able to login with just that uniquenick and password. Unique nicks have similar restrictions as chat nicks. See Nickname restrictions for valid unique nicks.

  4. GameSpyID Login with a uniquenick in a custom namespace (peerConnectLogin with the custom namespaceID)

    You should only be using this method if you have been assigned a custom namespace. You can contact devsupport@gamespy.com for information about getting a custom namespace.

    If the namespace has expiring uniquenicks, then this method is almost identical to the above method, with the exception of using a custom namespaceID instead of 1 for the default namespace.

    If the namespace does not have expiring uniquenicks, then the main difference is that peerConnectLogin can be used with just a uniquenick and password instead of the email, nick, and password used in the above method.

    Another difference between this method and the above method is the namespace extension. The default GameSpy namespace has an extension of "-gs", while other namespaces have their own unique extensions. When you are assigned a custom namespace, you will be given the custom extension for use in your namespace. The chat nick for a player in this namespace will be his uniquenick with the namespace extension appended. For example, if a user has the uniquenick Joe in the GameSpy test namespace, his chat nick will be "Joe-gmt". peerTranslateNick can be used to strip extensions off of nicks. See Nickname restrictions for valid unique nicks.

  5. Remote Authentication (peerConnectPreAuth)

    The remote authentication login method is used to login using information from a partner authentication system. You login using a token and a challenge, which are supplied by the partner authentication system. Contact devsupport@gamespy.com for further information on using this login method.

Nickname Restrictions

There are three different nicknames used in the Peer. A profile nick passed to peerConnectLogin is only restricied to all characters except the "\" character and a limite of 30 characters. The chat and unique nicks have more restrictiions. The character limit for both nicks is 20. Chat and Unique nicks have the following restrictions:

  • The first character cannot be one of the following characters: +, @, #, :
  • Numeric characters are only allowed after the first character.
  • All characters in the ASCII character range 34-126 are valid except for the backslash character (character 92, "\").

UNICODE Support

The GameSpy SDKs support an optional UNICODE interface for widestring applications. To use this interface, first define the symbol "GSI_UNICODE". Then, use widestrings wherever ANSI strings were previously called for. When in doubt, please refer to the header files for specific function declarations.

Although the GameSpy SDK interfaces support UNICODE parameters, some items may be stripped of their extra UNICODE information. These items include: nickname, email address, and URL strings. You may pass in widestring values, but they will first be converted to their ANSI counterparts before transmission.