本程序是一个实验RakNet RPC3 & NetworkIDManager的Demo,修改和扩充自RakNet的RPC3例子。
公共NPC基类:
CNetBNPC.h
#include <MessageIdentifiers.h>
/** Packet IDs*/
enum PACKET_ID
{
NET_PACKETID_CREATE_NPC = ID_USER_PACKET_ENUM + 1
};
namespace RakNet
{
class RPC3;
}
namespace NetSys
{
class CNetBNPC : public NetworkIDObject
{
public:
CNetBNPC(void) {}
virtual ~CNetBNPC(void){}
// Register in Client, Called by Server
virtual void sentToBattle_C(RakNet::RPC3 *rpcFromNetwork) = 0;
// Register in Server, Called by Client
virtual void callBackFromBattleField_S(RakNet::RPC3 *rpcFromNetwork) = 0;
virtual void bulletHit_S(RakNet::RPC3 *rpcFromNetwork) = 0;
};
}
#endif
服务器端:
BNPC_S.h
namespace NetSys
{
class BNPC_S : public CNetBNPC
{
public:
BNPC_S(void) {}
virtual ~BNPC_S(void){}
// Register in Client, Called by Server
virtual void sentToBattle_C(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_S : sentToBattle_C , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
// Register in Server, Called by Client
virtual void callBackFromBattleField_S(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_S : callBackFromBattleField_S , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
virtual void bulletHit_S(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_S : bulletHit_S , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
};
}
#endif
RPC3Server.cpp
int main(int argc, char* argv[])
{
printf("begin rpc3 demo/n");
RakPeerInterface* rakPeer;
SystemAddress sa = UNASSIGNED_SYSTEM_ADDRESS;
rakPeer = RakNetworkFactory::GetRakPeerInterface();
SocketDescriptor sd(8000,0);
rakPeer->Startup(10,30,&sd,1);
rakPeer->SetMaximumIncomingConnections(5);
RakNet::RPC3 * rpc3Inst = new RakNet::RPC3;
RPC3_REGISTER_FUNCTION(rpc3Inst, &NetSys::CNetBNPC::callBackFromBattleField_S );
RPC3_REGISTER_FUNCTION(rpc3Inst, &NetSys::CNetBNPC::bulletHit_S );
NetworkIDManager networkIDManager;
networkIDManager.SetIsNetworkIDAuthority(true);
rpc3Inst->SetNetworkIDManager(&networkIDManager);
rakPeer->SetNetworkIDManager(&networkIDManager);
rakPeer->AttachPlugin(rpc3Inst);
NetSys::BNPC_S * npc_s = new NetSys::BNPC_S();
npc_s->SetNetworkIDManager(&networkIDManager);
char ch;
Packet* packet = NULL;
bool bQuit = false;
while (!bQuit)
{
if (_kbhit())
{
ch = getch();
if (ch=='c' || ch=='C')
{
RakNet::BitStream bs;
bs.Write(unsigned char(NET_PACKETID_CREATE_NPC));
bs.Write(npc_s->GetNetworkID());
rakPeer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
}
if (ch=='s' || ch=='S')
{
rpc3Inst->CallCPP("&NetSys::CNetBNPC::sentToBattle_C", npc_s->GetNetworkID(), rpc3Inst);
}
if (ch=='q' || ch=='Q')
{
bQuit = true;
}
}
for (packet = rakPeer->Receive();packet;rakPeer->DeallocatePacket(packet),
packet = rakPeer->Receive())
{
switch (packet->data[0])
{
case ID_DISCONNECTION_NOTIFICATION:
printf("ID_DISCONNECTION_NOTIFICATION/n");
break;
case ID_ALREADY_CONNECTED:
printf("ID_ALREADY_CONNECTED/n");
break;
case ID_CONNECTION_ATTEMPT_FAILED:
printf("Connection attempt failed/n");
break;
case ID_NO_FREE_INCOMING_CONNECTIONS:
printf("ID_NO_FREE_INCOMING_CONNECTIONS/n");
break;
case ID_PONG:
printf("ID_PONG/n");
break;
case ID_CONNECTION_REQUEST_ACCEPTED:
// This tells the client they have connected
printf("ID_CONNECTION_REQUEST_ACCEPTED/n");
break;
case ID_NEW_INCOMING_CONNECTION:
{
printf("ID_NEW_INCOMING_CONNECTION/n");
break;
}
case ID_RPC_REMOTE_ERROR:
{
printf("ID_RPC_REMOTE_ERROR/n");
// Recipient system returned an error
switch (packet->data[1])
{
case RakNet::RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE:
printf("RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE/n");
break;
case RakNet::RPC_ERROR_OBJECT_DOES_NOT_EXIST:
printf("RPC_ERROR_OBJECT_DOES_NOT_EXIST/n");
break;
case RakNet::RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE:
printf("RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE/n");
break;
case RakNet::RPC_ERROR_FUNCTION_NOT_REGISTERED:
printf("RPC_ERROR_FUNCTION_NOT_REGISTERED/n");
break;
case RakNet::RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED:
printf("RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED/n");
break;
case RakNet::RPC_ERROR_CALLING_CPP_AS_C:
printf("RPC_ERROR_CALLING_CPP_AS_C/n");
break;
case RakNet::RPC_ERROR_CALLING_C_AS_CPP:
printf("RPC_ERROR_CALLING_C_AS_CPP/n");
break;
}
printf("Function: %s", packet->data+2);
}
}
}
RakSleep(30);
}
rakPeer->Shutdown(100,0);
RakNetworkFactory::DestroyRakPeerInterface(rakPeer);
if (npc_s)
{
delete npc_s;
}
if (rpc3Inst)
{
delete rpc3Inst;
}
printf("leave now/n");
RakSleep(1000*2);
return 0;
}
客户端:
BNPC_C.h
namespace NetSys
{
class BNPC_C : public CNetBNPC
{
public:
BNPC_C(void) {}
virtual ~BNPC_C(void){}
// Register in Client, Called by Server
virtual void sentToBattle_C(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_C : sentToBattle_C , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
// Register in Server, Called by Client
virtual void callBackFromBattleField_S(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_C : callBackFromBattleField_S , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
virtual void bulletHit_S(RakNet::RPC3 *rpcFromNetwork)
{
printf("BNPC_C : bulletHit_S , Func is called from %s /n", rpcFromNetwork->GetLastSenderAddress().ToString());
}
};
}
#endif
RPC3Client.cpp
int main(int argc, char* argv[])
{
printf("begin rpc3 demo/n");
RakPeerInterface* rakPeer;
SystemAddress sa = UNASSIGNED_SYSTEM_ADDRESS;
rakPeer = RakNetworkFactory::GetRakPeerInterface();
SocketDescriptor sd(8001,0);
rakPeer->Startup(10,30,&sd,1);
rakPeer->Connect("127.0.0.1",8000,0,0,0);
RakNet::RPC3 * rpc3Inst = new RakNet::RPC3;
RPC3_REGISTER_FUNCTION(rpc3Inst, &NetSys::CNetBNPC::sentToBattle_C );
NetworkIDManager networkIDManager;
networkIDManager.SetIsNetworkIDAuthority(false);
rpc3Inst->SetNetworkIDManager(&networkIDManager);
rakPeer->SetNetworkIDManager(&networkIDManager);
rakPeer->AttachPlugin(rpc3Inst);
Packet* packet = NULL;
bool bRet;
NetSys::BNPC_C * npc_c = 0;
char ch;
bool bQuit = false;
while (!bQuit)
{
if (_kbhit())
{
ch = getch();
if (ch=='d' || ch=='D')
{
rpc3Inst->CallCPP("&NetSys::CNetBNPC::callBackFromBattleField_S", npc_c->GetNetworkID(), rpc3Inst);
}
if (ch=='q' || ch=='Q')
{
bQuit = true;
}
}
for (packet = rakPeer->Receive();packet;rakPeer->DeallocatePacket(packet),
packet = rakPeer->Receive())
{
unsigned char msgID = packet->data[0];
if (msgID == NET_PACKETID_CREATE_NPC)
{
RakNet::BitStream bs(packet->data, packet->length, false);
// Ignore the message ID
bs.IgnoreBits(8);
NetworkID appleNetworkID;
bs.Read(appleNetworkID);
npc_c = new NetSys::BNPC_C();
npc_c->SetNetworkIDManager(&networkIDManager);
npc_c->SetNetworkID(appleNetworkID);
printf("NET_PACKETID_CREATE_NPC,NetSys::BNPC_C has been created!!!!/n");
}
switch (msgID)
{
case ID_DISCONNECTION_NOTIFICATION:
printf("ID_DISCONNECTION_NOTIFICATION/n");
break;
case ID_ALREADY_CONNECTED:
printf("ID_ALREADY_CONNECTED/n");
break;
case ID_CONNECTION_ATTEMPT_FAILED:
printf("Connection attempt failed/n");
break;
case ID_NO_FREE_INCOMING_CONNECTIONS:
printf("ID_NO_FREE_INCOMING_CONNECTIONS/n");
break;
case ID_PONG:
printf("ID_PONG/n");
break;
case ID_CONNECTION_REQUEST_ACCEPTED:
break;
case ID_NEW_INCOMING_CONNECTION:
printf("ID_NEW_INCOMING_CONNECTION/n");
break;
case ID_RPC_REMOTE_ERROR:
{
// Recipient system returned an error
switch (packet->data[1])
{
case RakNet::RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE:
printf("RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE/n");
break;
case RakNet::RPC_ERROR_OBJECT_DOES_NOT_EXIST:
printf("RPC_ERROR_OBJECT_DOES_NOT_EXIST/n");
break;
case RakNet::RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE:
printf("RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE/n");
break;
case RakNet::RPC_ERROR_FUNCTION_NOT_REGISTERED:
printf("RPC_ERROR_FUNCTION_NOT_REGISTERED/n");
break;
case RakNet::RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED:
printf("RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED/n");
break;
case RakNet::RPC_ERROR_CALLING_CPP_AS_C:
printf("RPC_ERROR_CALLING_CPP_AS_C/n");
break;
case RakNet::RPC_ERROR_CALLING_C_AS_CPP:
printf("RPC_ERROR_CALLING_C_AS_CPP/n");
break;
}
printf("Function: %s", packet->data+2);
}
case ID_USER_PACKET_ENUM:
{
printf("user data: %s/n",packet->data + 1);
break;
}
printf("case type = %d/n",packet->data[0]);
}
}
RakSleep(30);
//printf("client loop/n");
}
rakPeer->Shutdown(100,0);
RakNetworkFactory::DestroyRakPeerInterface(rakPeer);
if (npc_c)
{
delete npc_c;
}
if (rpc3Inst)
{
delete rpc3Inst;
}
printf("leave now/n");
RakSleep(1000*2);
return 0;
}