void ConnectionGraph2::AddParticipant(const SystemAddress &systemAddress, RakNetGUID rakNetGUID) { // Relay the new connection to other systems. RakNet::BitStream bs; bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); bs.Write((uint32_t)1); bs.Write(systemAddress); bs.Write(rakNetGUID); bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(rakNetGUID)); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true); // Send everyone to the new guy DataStructures::List<SystemAddress> addresses; DataStructures::List<RakNetGUID> guids; rakPeerInterface->GetSystemList(addresses, guids); bs.Reset(); bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); BitSize_t writeOffset = bs.GetWriteOffset(); bs.Write((uint32_t) addresses.Size()); unsigned int i; uint32_t count=0; for (i=0; i < addresses.Size(); i++) { if (addresses[i]==systemAddress) continue; bs.Write(addresses[i]); bs.Write(guids[i]); bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(guids[i])); count++; } if (count>0) { BitSize_t writeOffset2 = bs.GetWriteOffset(); bs.SetWriteOffset(writeOffset); bs.Write(count); bs.SetWriteOffset(writeOffset2); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false); } bool objectExists; unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists); if (objectExists==false) { RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(_FILE_AND_LINE_); remoteSystem->guid=rakNetGUID; remoteSystems.InsertAtIndex(remoteSystem,ii,_FILE_AND_LINE_); } }
void ConnectionGraph2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming) { (void) isIncoming; // Send all existing systems to new connection RakNet::BitStream bs; bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); bs.Write((unsigned int)1); bs.Write(systemAddress); bs.Write(rakNetGUID); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true); // Send everyone to the new guy DataStructures::List<SystemAddress> addresses; DataStructures::List<RakNetGUID> guids; rakPeerInterface->GetSystemList(addresses, guids); bs.Reset(); bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); BitSize_t writeOffset = bs.GetWriteOffset(); bs.Write((unsigned int) addresses.Size()); unsigned int i; unsigned int count=0; for (i=0; i < addresses.Size(); i++) { if (addresses[i]==systemAddress) continue; bs.Write(addresses[i]); bs.Write(guids[i]); count++; } if (count>0) { BitSize_t writeOffset2 = bs.GetWriteOffset(); bs.SetWriteOffset(writeOffset); bs.Write(count); bs.SetWriteOffset(writeOffset2); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false); } RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(__FILE__,__LINE__); remoteSystem->guid=rakNetGUID; remoteSystems.Insert(rakNetGUID,remoteSystem,true,__FILE__,__LINE__); }
void RPC3::OnRPC3Call(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes) { RakNet::BitStream bs(data,lengthInBytes,false); DataStructures::StringKeyedHashIndex functionIndex; LocalRPCFunction *lrpcf; bool hasParameterCount=false; char parameterCount; NetworkIDObject *networkIdObject; NetworkID networkId; bool hasNetworkId=false; // bool hasFunctionIndex=false; // unsigned int functionIndex; BitSize_t bitsOnStack; char strIdentifier[512]; incomingExtraData.Reset(); bs.Read(parameterCount); bs.Read(hasNetworkId); if (hasNetworkId) { bool readSuccess = bs.Read(networkId); RakAssert(readSuccess); RakAssert(networkId!=UNASSIGNED_NETWORK_ID); if (networkIdManager==0 && (networkIdManager=rakPeerInterface->GetNetworkIDManager())==0) { // Failed - Tried to call object member, however, networkIDManager system was never registered SendError(systemAddress, RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE, ""); return; } networkIdObject = (NetworkIDObject*) networkIdManager->GET_OBJECT_FROM_ID(networkId); if (networkIdObject==0) { // Failed - Tried to call object member, object does not exist (deleted?) SendError(systemAddress, RPC_ERROR_OBJECT_DOES_NOT_EXIST, ""); return; } } else { networkIdObject=0; } bool isCall; bs.Read(isCall); bs.AlignReadToByteBoundary(); // bs.Read(hasFunctionIndex); // if (hasFunctionIndex) // bs.ReadCompressed(functionIndex); // else stringCompressor->DecodeString(strIdentifier,512,&bs,0); bs.ReadCompressed(bitsOnStack); RakNet::BitStream serializedParameters; if (bitsOnStack>0) { serializedParameters.AddBitsAndReallocate(bitsOnStack); bs.ReadAlignedBytes(serializedParameters.GetData(), BITS_TO_BYTES(bitsOnStack)); serializedParameters.SetWriteOffset(bitsOnStack); } // if (hasFunctionIndex) // { // if ( // (isCall==true && functionIndex>localFunctions.Size()) || // (isCall==false && functionIndex>localSlots.Size()) // ) // { // // Failed - other system specified a totally invalid index // // Possible causes: Bugs, attempts to crash the system, requested function not registered // SendError(systemAddress, RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE, ""); // return; // } // } // else { // Find the registered function with this str if (isCall) { // for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++) // { // bool isObjectMember = boost::fusion::get<0>(localFunctions[functionIndex].functionPointer); // // boost::function<_RPC3::InvokeResultCodes (_RPC3::InvokeArgs)> functionPtr = boost::fusion::get<0>(localFunctions[functionIndex].functionPointer); // // if (isObjectMember == (networkIdObject!=0) && // strcmp(localFunctions[functionIndex].identifier.C_String(), strIdentifier)==0) // { // // SEND RPC MAPPING // RakNet::BitStream outgoingBitstream; // outgoingBitstream.Write((MessageID)ID_AUTO_RPC_REMOTE_INDEX); // outgoingBitstream.Write(hasNetworkId); // outgoingBitstream.WriteCompressed(functionIndex); // stringCompressor->EncodeString(strIdentifier,512,&outgoingBitstream,0); // outgoingBitstream.Write(isCall); // SendUnified(&outgoingBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false); // break; // } // } functionIndex = localFunctions.GetIndexOf(strIdentifier); if (functionIndex.IsInvalid()) { SendError(systemAddress, RPC_ERROR_FUNCTION_NOT_REGISTERED, strIdentifier); return; } lrpcf = localFunctions.ItemAtIndex(functionIndex); bool isObjectMember = boost::fusion::get<0>(lrpcf->functionPointer); if (isObjectMember==true && networkIdObject==0) { // Failed - Calling C++ function as C function SendError(systemAddress, RPC_ERROR_CALLING_CPP_AS_C, strIdentifier); return; } if (isObjectMember==false && networkIdObject!=0) { // Failed - Calling C function as C++ function SendError(systemAddress, RPC_ERROR_CALLING_C_AS_CPP, strIdentifier); return; } } else { functionIndex = localSlots.GetIndexOf(strIdentifier); if (functionIndex.IsInvalid()) { SendError(systemAddress, RPC_ERROR_FUNCTION_NOT_REGISTERED, strIdentifier); return; } } } if (isCall) { bool isObjectMember = boost::fusion::get<0>(lrpcf->functionPointer); boost::function<_RPC3::InvokeResultCodes (_RPC3::InvokeArgs)> functionPtr = boost::fusion::get<1>(lrpcf->functionPointer); // int arity = boost::fusion::get<2>(localFunctions[functionIndex].functionPointer); // if (isObjectMember) // arity--; // this pointer if (functionPtr==0) { // Failed - Function was previously registered, but isn't registered any longer SendError(systemAddress, RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED, strIdentifier); return; } // Boost doesn't support this for class members // if (arity!=parameterCount) // { // // Failed - The number of parameters that this function has was explicitly specified, and does not match up. // SendError(systemAddress, RPC_ERROR_INCORRECT_NUMBER_OF_PARAMETERS, localFunctions[functionIndex].identifier); // return; // } _RPC3::InvokeArgs functionArgs; functionArgs.bitStream=&serializedParameters; functionArgs.networkIDManager=networkIdManager; functionArgs.caller=this; functionArgs.thisPtr=networkIdObject; // serializedParameters.PrintBits(); _RPC3::InvokeResultCodes res2 = functionPtr(functionArgs); } else { InvokeSignal(functionIndex, &serializedParameters, false); } }
bool RPC3::SendCallOrSignal(RakString uniqueIdentifier, char parameterCount, RakNet::BitStream *serializedParameters, bool isCall) { SystemAddress systemAddr; // unsigned int outerIndex; // unsigned int innerIndex; if (uniqueIdentifier.IsEmpty()) return false; RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); bs.Write(parameterCount); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID && isCall) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } bs.Write(isCall); // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); if (outgoingBroadcast) { unsigned systemIndex; for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++) { systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex); if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress) { // if (GetRemoteFunctionIndex(systemAddr, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); // Start writing again after ID_AUTO_RPC_CALL bs.SetWriteOffset(writeOffset); } } } else { systemAddr = outgoingSystemAddress; if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS) { // if (GetRemoteFunctionIndex(systemAddr, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }
PluginReceiveResult Router::OnReceive(Packet *packet) { if (packet->data[0]==ID_ROUTE_AND_MULTICAST || (packet->length>5 && packet->data[0]==ID_TIMESTAMP && packet->data[5]==ID_ROUTE_AND_MULTICAST)) { #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i got routed message from %i\n", peer->GetExternalID(packet->systemAddress).port, packet->systemAddress.port); #endif RakNetTime timestamp; PacketPriority priority; PacketReliability reliability; unsigned char orderingChannel; SystemAddress originalSender; RakNet::BitStream out; BitSize_t outStartingOffset; unsigned int payloadBitLength; unsigned payloadWriteByteOffset; RakNet::BitStream incomingBitstream(packet->data, packet->length, false); incomingBitstream.IgnoreBits(8); if (packet->data[0]==ID_TIMESTAMP) { incomingBitstream.Read(timestamp); out.Write((MessageID)ID_TIMESTAMP); out.Write(timestamp); incomingBitstream.IgnoreBits(8); } // Read the send parameters unsigned char c; incomingBitstream.ReadCompressed(c); priority=(PacketPriority)c; incomingBitstream.ReadCompressed(c); reliability=(PacketReliability)c; incomingBitstream.ReadCompressed(orderingChannel); incomingBitstream.Read(payloadBitLength); out.Write((MessageID)ID_ROUTE_AND_MULTICAST); out.WriteCompressed((unsigned char)priority); out.WriteCompressed((unsigned char)reliability); out.WriteCompressed((unsigned char)orderingChannel); out.Write(payloadBitLength); out.AlignWriteToByteBoundary(); incomingBitstream.AlignReadToByteBoundary(); payloadWriteByteOffset=(unsigned int) BITS_TO_BYTES(out.GetWriteOffset()); out.Write(&incomingBitstream, payloadBitLength); // This write also does a read on incomingBitStream if (restrictByType) { RakNet::BitStream t(out.GetData()+payloadWriteByteOffset, sizeof(unsigned char), false); MessageID messageID; t.Read(messageID); if (allowedTypes.HasData(messageID)==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; // Don't route restricted types } incomingBitstream.Read(originalSender); out.Write(originalSender); outStartingOffset=out.GetWriteOffset(); // Deserialize the root bool hasData=false; SystemAddress recipient; unsigned short numberOfChildren; incomingBitstream.Read(hasData); incomingBitstream.Read(recipient); // This should be our own address if (incomingBitstream.ReadCompressed(numberOfChildren)==false) { #ifdef _DEBUG RakAssert(0); #endif return RR_STOP_PROCESSING_AND_DEALLOCATE; } unsigned childIndex; bool childHasData=false; SystemAddress childRecipient; unsigned short childNumberOfChildren; SystemAddress immediateRecipient; immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS; int pendingNodeCount=0; for (childIndex=0; childIndex < numberOfChildren; childIndex++) { while (pendingNodeCount!=-1) { // Copy out the serialized subtree for this child incomingBitstream.Read(childHasData); incomingBitstream.Read(childRecipient); if (!incomingBitstream.ReadCompressed(childNumberOfChildren)) return RR_STOP_PROCESSING_AND_DEALLOCATE; if (immediateRecipient==UNASSIGNED_SYSTEM_ADDRESS) { immediateRecipient=childRecipient; } pendingNodeCount+=childNumberOfChildren-1; out.Write(childHasData); out.Write(childRecipient); out.WriteCompressed(childNumberOfChildren); } #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i routing to %i\n", peer->GetExternalID(packet->systemAddress).port, immediateRecipient.port); #endif // Send what we got so far SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false); // Restart writing the per recipient data out.SetWriteOffset(outStartingOffset); // Reread the top level node immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS; pendingNodeCount=0; } // Write the user payload to the packet struct if this is a destination and change the sender and return true if (hasData) { #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i returning payload to user\n", peer->GetExternalID(packet->systemAddress).port); #endif if (packet->data[0]==ID_TIMESTAMP ) { memcpy( packet->data + sizeof(RakNetTime)+sizeof(unsigned char), out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) ); packet->bitSize=BYTES_TO_BITS(sizeof(RakNetTime)+sizeof(unsigned char))+payloadBitLength; } else { memcpy( packet->data, out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) ); packet->bitSize=payloadBitLength; } packet->length=(unsigned int) BITS_TO_BYTES(packet->bitSize); packet->systemAddress.systemIndex=(SystemIndex)-1; packet->systemAddress=originalSender; return RR_CONTINUE_PROCESSING; } // Absorb return RR_STOP_PROCESSING_AND_DEALLOCATE; } return RR_CONTINUE_PROCESSING; }
void AutoRPC::OnRPCUnknownRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes, RakNetTime timestamp) { char inputStack[ARPC_MAX_STACK_SIZE]; NetworkID networkId; bool hasNetworkId=false; unsigned int functionIndex; unsigned int bytesOnStack; int numberOfBitsUsed; char parameterCount; bool hasParameterCount=false; RakNet::BitStream extraData; RakNet::BitStream bs(data,lengthInBytes,false); bs.Read(hasParameterCount); if (hasParameterCount) bs.Read(parameterCount); bs.ReadCompressed(functionIndex); bs.ReadCompressed(numberOfBitsUsed); extraData.AddBitsAndReallocate(numberOfBitsUsed); bs.ReadBits(extraData.GetData(), numberOfBitsUsed, false); extraData.SetWriteOffset(numberOfBitsUsed); bs.Read(hasNetworkId); if (hasNetworkId) bs.Read(networkId); bs.ReadCompressed(bytesOnStack); bs.ReadAlignedBytes((unsigned char*) inputStack, bytesOnStack); unsigned outerIndex; if (remoteFunctions.Has(systemAddress)) { outerIndex = remoteFunctions.GetIndexAtKey(systemAddress); DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[outerIndex]; unsigned i; for (i=0; i < theList->Size(); i++) { if (theList->operator [](i).functionIndex==functionIndex) { RakNet::BitStream out; // Recover by resending the RPC with the function identifier string this time if (timestamp!=0) { out.Write((MessageID)ID_TIMESTAMP); out.Write(timestamp); } out.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { out.Write(true); out.Write(parameterCount); } else { out.Write(false); } out.WriteCompressed(numberOfBitsUsed); out.Write(&extraData); out.Write(hasNetworkId); if (hasNetworkId) out.Write(networkId); out.AlignWriteToByteBoundary(); out.Write(false); stringCompressor->EncodeString(theList->operator [](i).identifier.uniqueIdentifier, 512, &out, 0); out.WriteCompressed(bytesOnStack); out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack); SendUnified(&out, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddress, false); return; } } } // Failed to recover, inform the user Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)); RakNet::BitStream bs2(p->data, sizeof(MessageID)+sizeof(unsigned char), false); bs2.SetWriteOffset(0); bs2.Write((MessageID)ID_RPC_REMOTE_ERROR); bs2.Write((unsigned char)RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED); stringCompressor->EncodeString("",256,&bs,0); p->systemAddress=systemAddress; rakPeerInterface->PushBackPacket(p, false); }
bool AutoRPC::SendCall(const char *uniqueIdentifier, const char *stack, unsigned int bytesOnStack, char parameterCount) { SystemAddress systemAddr; RPCIdentifier identifier; unsigned int outerIndex; unsigned int innerIndex; if (uniqueIdentifier==0) return false; identifier.uniqueIdentifier=(char*) uniqueIdentifier; identifier.isObjectMember=(outgoingNetworkID!=UNASSIGNED_NETWORK_ID); RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { bs.Write(true); bs.Write(parameterCount); } else { bs.Write(false); } bs.WriteCompressed(outgoingExtraData.GetNumberOfBitsUsed()); bs.Write(&outgoingExtraData); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); SystemAddress outgoingSystemAddress; if (outgoingSystemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID) outgoingSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(outgoingSystemIdentifier.rakNetGuid); else outgoingSystemAddress = outgoingSystemIdentifier.systemAddress; if (outgoingBroadcast) { unsigned systemIndex; for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++) { systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex); if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); // Start writing again after ID_AUTO_RPC_CALL bs.SetWriteOffset(writeOffset); } } } else { systemAddr = outgoingSystemAddress; if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }