![]() |
The NetworkIDObject class allows you to refer to objects in a common fashion over different computers NetworkIDObject is tightly coupled with NetworkIDManager, which is responsible for providing the unique NetworkID value each NetworkIDObject object has. You must
also call SetNetworkIDManager on the RakPeerInterface instance you are using.
As a server: // With global scope NetworkIDManager serverNetworkIDManager; int main(void) { // ....Code to initialize the server RakPeerInterface instance serverNetworkIDManager.SetIsNetworkIDAuthority(true); peer->SetNetworkIDManager(&serverNetworkIDManager); // ... Other code } In this case, since the server is the network authority, IDs are automatically assigned, so GetNetworkID() will always work and you should not call SetNetworkID(). When the server creates a new NetworkIDObject object, the clients must know about it. Note that you must do that yourself. It’s not done automatically. So you would generally do this in the server: // ----------- In some common header file, used in both the Server and Client. // Define our custom message to let the clients know we have created a NetworkIDObject object enum { ID_MYOBJECT_CREATED = ID_USER_PACKET_ENUM }; // Must derive from NetworkIDObject class MyObject : public NetworkIDObject { //...... }; // --------------------- MyObject* CreateServerSideObject(void){ // Create the object MyObject *myObject = new MyObject; // MyObject inherits from NetworkIDObject myObject->SetNetworkIDManager(&serverNetworkIDManager); NetworkID networkID = myObject->GetNetworkID(); // Let all connected clients know about the object, by constructing // a simple packet with the NetworkID value of the object. RakNet::BitStream bs; bs.Write(unsigned char(ID_MYOBJECT_CREATED)); bs.Write(apple->GetNetworkID()); peer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true); // Broadcast to all clients return myObject; }When the client gets the packet with the NetworkID value, you do something like this: // Global scope. // You should call SetIsNetworkIDAuthority(false) before using it. NetworkIDManager clientNetworkIDManager; MyObject* CreateClientSideObject(Packet *p) { assert(p->data[0]==ID_MYOBJECT_CREATED); RakNet::BitStream bs(p->data, p->length, false); bs.IgnoreBits(8); // Ignore the packet ID NetworkID networkID; bs.Read(networkID); MyObject *myObject = new MyObject; // MyObject inherits from NetworkIDObject myObject->SetNetworkIDManager(&clientNetworkIDManager); // Set to the NetworkID we got from the server myObject->SetNetworkID(networkID); return myObject; } int main(void) { // ... Initialize, and do something until you receive the packet with the NetworkID if (packet->data[0]==ID_MYOBJECT_CREATED){ object = CreateClientSideObject(packet); } // ... }As a client: IDs are never assigned, you must get them from the server. If you create or want to create an object, you must program things in such a way that the server will return a packet to you telling you what the ID is of the object you just created. If the server creates an object (or another client did and the server tells you about it, which is the same thing) then you can just assign IDs as usual. The easiest way to handle creation of objects on the client is to ask the server for the object and only create the object when the server replies. Send something like ID_REQUEST_CREATE_OBJECT or whatever. You can then program the server to create the object and reply to the sender of this packet (or all clients) with the ID encoded into the packet (just like we did above). On the server: // ... Code to receive packets if (packet->data[0]==ID_REQUEST_CREATE_OBJECT){ // Create the object, and let all clients know about it. // You might want to change CreateServerSideObject to reply only to the system that requested the object. object = CreateServerSideMyObject(packet); } The CreateServerSideObject function we created above, creates the object on the Server, and informs all the clients. Peer to peer: 1. In RakNetTypes.h, in the structure NetworkID, there is a static member peerToPeerMode. Set this to true. Doing so will expand the NetworkID structure to include both the originating system, and the numerical object identifier. By default, the originating system is not written to save bandwidth, because usually there is only one such system (the server) 2. In NetworkIDManager.h, undefine NETWORK_ID_USE_PTR_TABLE. This is an optimization for when you only have a numerical object identifier. When active. it uses a pointer table 65536 elements long to look up pointers by ID. This is not possible to do when peerToPeerMode is true. You may also want to comment this out in the unlikely event that you have more than 65536 objects instantiated at the same time (not ever). Programming Tip Other notes Comment out NETWORK_ID_USE_PTR_TABLE in NetworkIDManager.h if you will have more than 65536 objects instantiated at the same time. It is OK to have more than 65536 objects ever, because the code checks for identifiers already in use. You just cannot have more than this at the same time. Should this happen, the code will assert as well. Other functions |
![]() |
Index |