FullyConnectedMesh2插件
在自动选择一个长期运行系统时,生成一个完整的连接网络
在端到端的游戏中需要其中一个Peer充当主机,为系统创建唯一的游戏事件。例如,这个主机发送游戏结束通知或控制AI。FullyConnectedMesh2插件可以用于在连接之后自动决定主机。
概览:
1. 调用SetConnectOnNewRemoteConnection(false, “”);方法,手动连接到其他的系统来生成一个完全连接网络拓扑。
2. 如果每一个远端连接时,一个玩家可以被接受进入游戏,调用SetAutoparticipateConnections(true);函数,否则对每一个远端系统调用AddParticipant()。
3. 使用GetHostSystem()方法或者IsHostSystem()方法查询那个Peer端是主机
4. 当收到ID_FCM2_NEW_HOST消息时,如果有必要,请做主机迁移。
SetConnectionOnNewRemoteConnection()方法,如果调用参数是true,当ID_REMOTE_NEW_INCOMMING_CONECTION消息到达ConnectionGraph2插件时在远端系统调用RakPeer::Connect()方法。然而,这种方法通常行不通,因为多数的系统都在路由后面。因此,通常需要手动连接到其他的系统。
SetAutoparticipateConnections()调用传参通常是false,因为通常在将一个玩家接受进入游戏之前需要做一些玩家有效性验证。
直到主机计算完成,否则GetHostSystem()会返回你自己的guid,GetConnectedHost()方法会返回UNSIGNED_RAKNET_GUID。一旦主机的设定完成,就会得到ID_FCM2_NEW_HOST标识消息。主机通常是使用AddParticipant()方法加入到系统的计算机中,并且它是运行时间最长的一个。如果在游戏开始时需要立即知道谁是主机,那么在获得ID_FCM2_NEW_HOST消息之前不要开始游戏。
case ID_NEW_INCOMING_CONNECTION:
case ID_CONNECTION_REQUEST_ACCEPTED:
{
fullyconnectedmesh->AddParticipant(packet->guid);
if (fullyconnectedmesh->GetConnectedHost()!=UNASSIGNED_RAKNET_GUID)
{
// 已经知道了主机是哪个计算机,因此立即连接到游戏中
AddGameParticipant(packet->guid);
}
// 否则如果不知道主机,在调用AddGameParticipant()方法之前
// 等待ID_FCM2_NEW_HOST消息到达
}
case ID_FCM2_NEW_HOST:
{
RakNet::BitStream bs(packet->data,packet->length,false);
bs.IgnoreBytes(1);
RakNetGUID oldhost;
bs.Read(oldhost);
// 如果老的主机和新的相同,那么这时第一次收到这种消息
if (oldhost==packet->guid)
{
// 因为第一次知道了主机是哪个,游戏准备开始
SignalGameStart();
// 作为游戏参与者加入系统,这个参与者前面已经加入到了FullyConnectedMesh2
// 从ID_NEW_INCOMING_CONNECTION 和 ID_CONNECTION_REQUEST_ACCEPTED消息
DataStructures::List<RakNetGUID> participantList;
fullyconnectedmesh->GetParticipantList(participantList);
for (unsigned int i=0; i < participantList.Size(); i++)
AddGameParticipant(participantList[i]);
}
}
GetParticipantList()和GetHostOrder()可以用于查找那些系统已经使用Addparticipant()方法加入的计算机的列表或顺序。
如果游戏没有立即开始连网,如果网络游戏现在是相关的,应该调用ResetHostCaculation()来初始化Host定时器。否则,用户可以单机玩游戏,连接到网络会话中,然后才会被考虑是否可以成为主机,尽管它是最后一个加入到网络会话的主机。在试图加入到网络房间或是大厅时是调用ResetHostCaculation()方法最好的时机。
读取主机:
ID_FCM2_NEW_HOST消息中编码了网络stream中的老主机的RakNetGUID。新主机地址信息写入了systemAddress以及packet的guid成员中。如果老主机和新主机是相同的,那么就没有老主机了(这是第一次主机设定计算)。
case ID_FCM2_NEW_HOST:
{
if (packet->guid==rakPeer->GetMyGUID())
printf("Got new host (ourselves)");
else
printf("Got new host %s, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
RakNet::BitStream bs(packet->data,packet->length,false);
bs.IgnoreBytes(1);
RakNetGUID oldHost;
bs.Read(oldHost);
// 如果老主机与新的不同,那么这条消息表明丢失了到主机的链接
if (oldHost!=packet->guid)
printf(". Oldhost Guid=%s\n", oldHost.ToString());
else
printf("\n");
}
break;
}
查看插件使用实例,参考Samples/FCMHost。
By 北洋小郭
转载请注明出处,请勿用于商业用途,谢谢!