|
|
|
Interface RakNet with Live, including voice chat The XBOX does not offer the concept of rooms and lobbies, and in fact requires that the user do the network communication to setup matches. RakNet handles this for you with Lobby2Client_360. The XBOX also does not handle host migration - however, if you including the FullyConnectedMesh2 plugin, the Lobby2Client_360 plugin will detect host migrations and perform the appropriate calls for you. For the sample code, open RakNet_360_VS2008.sln and run the LiveTest project. Usage: As per main() in LiveTest.cpp, you instantiate Lobby2Client_360 and attach it to an instance of RakPeer. If your match is peer to peer, and you want host migration, you will also need to attach FullyConnectedMesh2. If you want voice chat, you will also need to attach RakVoiceXBOX360, and define the preprocessor flag RAKNET_USE_VDP which is used in SocketLayer.cpp. Creating a room: Send the message Console_CreateRoom_360. It is possible to create more than one room at a time. The room is associated with the XBOX console - however, when created the room does not have any users. To add users to the room, you must then send the message Console_SignIntoRoom_360. There are restrictions on what users can sign into the room - for example, if the room is for a ranked session, guests cannot sign into the room. IMPORTANT: Due to a design flaw in the Live API, it is not possible to end and restart ranked game sessions. Ranked sessions must be destroyed and recreated. However, doing so causes loss of connectivity of all users in that session. Therefore, there is no way to reliably keep users together between game sessions without significant hassle. RakNet solves this problem by always creating 2 sessions (even if you do not use ranked). The first, called a presence session in the XBOX terminology, is only used for connectivity. The presence session persists as long as you are in the room, and is not ranked / arbitrated (XSESSION_CREATE_USES_ARBITRATION). Even if the desired game mode is ranked, the presence session is not ranked. The presence session is returned through searching, and enables you to connect to other consoles. However, this does carry two problems:
To get around the first issue, you should add an additional flag in your .xlast file is basically a search property on your presence session, indicating if the associated gameplay room is ranked or not. The .xlast file is a file that predefines what kind of searches you will be running, what game modes you have, languages, and other things. The PS3 does this all programatically. For example, to generate a new matchmaing query, open the .xlast file, opening "Xbox 360 and Live authoring submission tool", open the xlast file, right clicking, and clicking new matchmaking query Joining a room: First, search for rooms using Console_SearchRooms_360. The XSESSION_INFO member, found in the rooms list Console_SearchRooms_360::rooms[index].sr->info, is the structure that contains information about the room to join. Next, execute Console_JoinRoom_360, copying the XSESSION_INFO to the roomToJoin member of the structure. If Console_JoinRoom completes successfully, a local copy of the room was created and NAT traversal has completed. You can now get the IP address of the remote system from the session ID, which is the XNKID member of XSESSION_INFO. Use SystemAddress::SetFromXSessionInfo for this. Here is an example of extracting the IP address and calling Connect() SystemAddress roomToJoinAddress; Note that you still have to call Console_SignIntoRoom_360 to actually join the room, similar to how you do so with Console_CreateRoom_360. Host migration: When creating the room, you have the option to destroy the room when the host leaves, or to migrate the host, as per the supportHostMigration member of Console_CreateRoom_360. If you choose to migrate the host, the FullyConnectedMesh2 plugin is required for automatic host migration. While the XBOX provides methods to determine the new host of a session, we recommend using FullyConnectedMesh2 because it integrates with Lobby2Client_360 and because it is cross platform. When FullyConnectedMesh2 determines loss of connectivity, it will return ID_FCM2_NEW_HOST. This is read by the plugin. All systems will then call XSessionMigrateHost, using the same host, to transparently move the room host to a new system. You will get the Notification_Console_RoomOwnerChanged callback when this occurs. Voice: The RakVoiceXBOX360 plugin, found at Samples\XBOX360\RakVoiceXBOX360, integrates with RakNet to support IPPROTO_VDP which is required by the XBOX TCRs. According to the TCRs, the first two bytes of all datagrams must contain the length of the gamedata, while the remaining data in the datagram contains voice data. RakNet's architecture does not support sending both voice and game data at once, for example, the RakPeer::Send() call has no option to also include voice data. To get around this, for normal data transmission the required define RAKNET_USE_VDP will cause SocketLayer.cpp to include the length of payload as the first two bytes of every datagram sent. And the first two bytes of every datagram is discarded, since the payload is always the length of the datagram anyway. For voice transmission, the plugin RakVoiceXBOX360 uses unencoded out of band data, directly calling into SocketLayer::SendTo_360. Out of band messages are not captured by RakPeer, but instead returned as-is. The plugin then checks for an intercepts this out of band data. Because the data format is known in advance, the plugin does not need to explicitly be told the length of the payload or the voice data. Anything not read as payload is treated as voice data, and fed to IXHV2Engine::SubmitIncomingChatData. In case it isn't clear, you cannot simply call SocketLayer::SendTo_360 by yourself with voice and game data. RakNet will internally discard game messages that have an invalid format, and RakNet's game messages are encoded in ReliabilityLayer.cpp. Voice data must be sent out band, as implemented by the plugin. |
|
|