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:
- 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.
- 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.
- 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):
- 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.
- 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.
- 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.
- 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.
- 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:
-
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.
-
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.
-
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.
-
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.
-
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.