本程序是一个实验RakNet RPC3 & NetworkIDManager的Demo,修改和扩充自RakNet的RPC3例子。
公共NPC基类:
CNetBNPC.h
#ifndef ___NET_Common_CNetBNPC_H__ #define ___NET_Common_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
#ifndef ___NET_Common_BNPC_S_H__ #define ___NET_Common_BNPC_S_H__ #include "CNetBNPC.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
#include <RPC3/RPC3.h> #include <RakPeerInterface.h> #include <stdio.h> #include <RakSleep.h> #include <NetworkIDManager.h> #include <RakNetworkFactory.h> #include <MessageIdentifiers.h> #include <string> #include <RakString.h> #include <Kbhit.h> #include "BNPC_S.h" using namespace std; using namespace RakNet; 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
#ifndef ___NET_Common_BNPC_C_H__ #define ___NET_Common_BNPC_C_H__ #include "CNetBNPC.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
#include <RPC3/RPC3.h> #include <RakPeerInterface.h> #include <stdio.h> #include <RakSleep.h> #include <NetworkIDManager.h> #include <RakNetworkFactory.h> #include <MessageIdentifiers.h> #include <string> #include <RakString.h> #include <BitStream.h> #include <Kbhit.h> #include "BNPC_C.h" using namespace std; using namespace RakNet; 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; }