void MessageFilter::SetSystemFilterSet(AddressOrGUID addressOrGUID, int filterSetID) { // Allocate this filter set if it doesn't exist. RakAssert(addressOrGUID.IsUndefined()==false); // bool objectExists; // unsigned index = systemList.GetIndexFromKey(addressOrGUID, &objectExists); // if (objectExists==false) DataStructures::HashIndex index = systemList.GetIndexOf(addressOrGUID); if (index.IsInvalid()) { if (filterSetID<0) return; FilteredSystem filteredSystem; filteredSystem.filter = GetFilterSetByID(filterSetID); // filteredSystem.addressOrGUID=addressOrGUID; filteredSystem.timeEnteredThisSet=RakNet::GetTimeMS(); // systemList.Insert(addressOrGUID, filteredSystem, true, _FILE_AND_LINE_); systemList.Push(addressOrGUID,filteredSystem,_FILE_AND_LINE_); } else { if (filterSetID>=0) { FilterSet *filterSet = GetFilterSetByID(filterSetID); systemList.ItemAtIndex(index).timeEnteredThisSet=RakNet::GetTimeMS(); systemList.ItemAtIndex(index).filter=filterSet; } else { systemList.RemoveAtIndex(index, _FILE_AND_LINE_); } } }
bool RPC4::RegisterFunction(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet )) { DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID); if (skhi.IsInvalid()==false) return false; registeredNonblockingFunctions.Push(uniqueID,functionPointer,_FILE_AND_LINE_); return true; }
void RPC3::InvokeSignal(DataStructures::HashIndex functionIndex, RakNet::BitStream *serializedParameters, bool temporarilySetUSA) { if (functionIndex.IsInvalid()) return; SystemAddress lastIncomingAddress=incomingSystemAddress; if (temporarilySetUSA) incomingSystemAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS; interruptSignal=false; LocalSlot *localSlot = localSlots.ItemAtIndex(functionIndex); unsigned int i; _RPC3::InvokeArgs functionArgs; functionArgs.bitStream=serializedParameters; functionArgs.networkIDManager=networkIdManager; functionArgs.caller=this; i=0; while (i < localSlot->slotObjects.Size()) { if (localSlot->slotObjects[i].associatedObject!=UNASSIGNED_NETWORK_ID) { functionArgs.thisPtr = networkIdManager->GET_OBJECT_FROM_ID<NetworkIDObject*>(localSlot->slotObjects[i].associatedObject); if (functionArgs.thisPtr==0) { localSlot->slotObjects.RemoveAtIndex(i); continue; } } else functionArgs.thisPtr=0; functionArgs.bitStream->ResetReadPointer(); bool isObjectMember = boost::fusion::get<0>(localSlot->slotObjects[i].functionPointer); boost::function<_RPC3::InvokeResultCodes (_RPC3::InvokeArgs)> functionPtr = boost::fusion::get<1>(localSlot->slotObjects[i].functionPointer); if (functionPtr==0) { if (temporarilySetUSA==false) { // Failed - Function was previously registered, but isn't registered any longer SendError(lastIncomingAddress, RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED, localSlots.KeyAtIndex(functionIndex).C_String()); } return; } _RPC3::InvokeResultCodes res2 = functionPtr(functionArgs); // Not threadsafe if (interruptSignal==true) break; i++; } if (temporarilySetUSA) incomingSystemAddress=lastIncomingAddress; }
bool RPC4::UnregisterSlot(const char* sharedIdentifier) { DataStructures::HashIndex hi = localSlots.GetIndexOf(sharedIdentifier); if (hi.IsInvalid()==false) { LocalSlot *ls = localSlots.ItemAtIndex(hi); RakNet::OP_DELETE(ls, _FILE_AND_LINE_); localSlots.RemoveAtIndex(hi, _FILE_AND_LINE_); return true; } return false; }
PluginReceiveResult TwoWayAuthentication::OnHashedNonceAndPassword(Packet *packet) { SLNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); char remoteHashedNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; unsigned short requestId; bsIn.Read(requestId); SLNet::RakString passwordIdentifier; bsIn.Read(passwordIdentifier); bsIn.ReadAlignedBytes((unsigned char *) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); // Look up used nonce from requestId char usedNonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; if (nonceGenerator.GetNonceById(usedNonce, requestId, packet, true)==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; DataStructures::HashIndex skhi = passwords.GetIndexOf(passwordIdentifier.C_String()); if (skhi.IsInvalid()==false) { char hashedThisNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; Hash(usedNonce, passwords.ItemAtIndex(skhi), hashedThisNonceAndPw); if (memcmp(hashedThisNonceAndPw, remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH)==0) { // Pass SLNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS); bsOut.WriteAlignedBytes((const unsigned char*) usedNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); bsOut.WriteAlignedBytes((const unsigned char*) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); bsOut.Write(passwordIdentifier); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); // Incoming success, modify packet header to tell user PushToUser(ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS, passwordIdentifier, packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } // Incoming failure, modify arrived packet header to tell user packet->data[0]=(MessageID) ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE; SLNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE); bsOut.WriteAlignedBytes((const unsigned char*) usedNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); bsOut.WriteAlignedBytes((const unsigned char*) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); bsOut.Write(passwordIdentifier); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); return RR_CONTINUE_PROCESSING; }
int MessageFilter::GetSystemFilterSet(AddressOrGUID systemAddress) { // bool objectExists; // unsigned index = systemList.GetIndexFromKey(systemAddress, &objectExists); // if (objectExists==false) // return -1; // else // return systemList[index].filter->filterSetID; DataStructures::HashIndex index = systemList.GetIndexOf(systemAddress); if (index.IsInvalid()) return -1; else return systemList.ItemAtIndex(index).filter->filterSetID; }
StatisticsHistory::SHErrorCode StatisticsHistory::GetHistoryForKey(uint64_t objectId, RakString key, StatisticsHistory::TimeAndValueQueue **values, Time curTime) const { if (values == 0) return SH_INVALID_PARAMETER; unsigned int idx = GetObjectIndex(objectId); if (idx == (unsigned int) -1) return SH_UKNOWN_OBJECT; TrackedObject *to = objects[idx]; DataStructures::HashIndex hi = to->dataQueues.GetIndexOf(key); if (hi.IsInvalid()) return SH_UKNOWN_KEY; *values = to->dataQueues.ItemAtIndex(hi); (*values)->CullExpiredValues(curTime); return SH_OK; }
void RPC4::RegisterSlot(const char *sharedIdentifier, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ), int callPriority) { LocalSlotObject lso(nextSlotRegistrationCount++, callPriority, functionPointer); DataStructures::HashIndex idx = GetLocalSlotIndex(sharedIdentifier); LocalSlot *localSlot; if (idx.IsInvalid()) { localSlot = RakNet::OP_NEW<LocalSlot>(_FILE_AND_LINE_); localSlots.Push(sharedIdentifier, localSlot,_FILE_AND_LINE_); } else { localSlot=localSlots.ItemAtIndex(idx); } localSlot->slotObjects.Insert(lso,lso,true,_FILE_AND_LINE_); }
void StatisticsHistory::AddValueByIndex(unsigned int index, RakString key, SHValueType val, Time curTime, bool combineEqualTimes) { TimeAndValueQueue *queue; TrackedObject *to = objects[index]; DataStructures::HashIndex hi = to->dataQueues.GetIndexOf(key); if (hi.IsInvalid()) { queue = RakNet::OP_NEW<TimeAndValueQueue>(_FILE_AND_LINE_); queue->key=key; queue->timeToTrackValues = timeToTrack; to->dataQueues.Push(key, queue, _FILE_AND_LINE_); } else { queue = to->dataQueues.ItemAtIndex(hi); } TimeAndValue tav; if (combineEqualTimes==true && queue->values.Size()>0 && queue->values.PeekTail().time==curTime) { tav = queue->values.PopTail(); queue->recentSum -= tav.val; queue->recentSumOfSquares -= tav.val * tav.val; queue->longTermSum -= tav.val; queue->longTermCount = queue->longTermCount - 1; } else { tav.val=0.0; tav.time=curTime; } tav.val+=val; queue->values.Push(tav, _FILE_AND_LINE_); queue->recentSum += tav.val; queue->recentSumOfSquares += tav.val * tav.val; queue->longTermSum += tav.val; queue->longTermCount = queue->longTermCount + 1; if (queue->longTermLowest > tav.val) queue->longTermLowest = tav.val; if (queue->longTermHighest < tav.val) queue->longTermHighest = tav.val; }
void StatisticsHistory::MergeAllObjectsOnKey(RakString key, TimeAndValueQueue *tavqOutput, SHDataCategory dataCategory) const { tavqOutput->Clear(); Time curTime = GetTime(); // Find every object with this key for (unsigned int idx=0; idx < objects.Size(); idx++) { TrackedObject *to = objects[idx]; DataStructures::HashIndex hi = to->dataQueues.GetIndexOf(key); if (hi.IsInvalid()==false) { TimeAndValueQueue *tavqInput = to->dataQueues.ItemAtIndex(hi); tavqInput->CullExpiredValues(curTime); TimeAndValueQueue::MergeSets(tavqOutput, dataCategory, tavqInput, dataCategory, tavqOutput); } } }
void TwoWayAuthentication::OnNonceReply(Packet *packet) { SLNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); char thierNonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; unsigned short requestId; bsIn.Read(requestId); bsIn.ReadAlignedBytes((unsigned char *) thierNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); // Lookup one of the negotiations for this guid/system address AddressOrGUID aog(packet); unsigned int i; for (i=0; i < outgoingChallenges.Size(); i++) { if (outgoingChallenges[i].remoteSystem==aog && outgoingChallenges[i].sentHash==false) { outgoingChallenges[i].sentHash=true; // Get the password for this identifier DataStructures::HashIndex skhi = passwords.GetIndexOf(outgoingChallenges[i].identifier.C_String()); if (skhi.IsInvalid()==false) { SLNet::RakString password = passwords.ItemAtIndex(skhi); // Hash their nonce with password and reply char hashedNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; Hash(thierNonce, password, hashedNonceAndPw); // Send SLNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_NEGOTIATION); bsOut.Write((MessageID)ID_HASHED_NONCE_AND_PASSWORD); bsOut.Write(requestId); bsOut.Write(outgoingChallenges[i].identifier); // Identifier helps the other system lookup the password quickly. bsOut.WriteAlignedBytes((const unsigned char*) hashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); } return; } } }
void RPC4::Signal(const char *sharedIdentifier, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, bool invokeLocal) { RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_SIGNAL); out.WriteCompressed(sharedIdentifier); if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast); if (invokeLocal) { DataStructures::HashIndex functionIndex; functionIndex = localSlots.GetIndexOf(sharedIdentifier); if (functionIndex.IsInvalid()) return; Packet p; p.guid=rakPeerInterface->GetMyGUID(); p.systemAddress=rakPeerInterface->GetMyBoundAddress(0); p.wasGeneratedLocally=true; RakNet::BitStream *bsptr, bstemp; if (bitStream) { bitStream->ResetReadPointer(); p.length=bitStream->GetNumberOfBytesUsed(); p.bitSize=bitStream->GetNumberOfBitsUsed(); bsptr=bitStream; } else { p.length=0; p.bitSize=0; bsptr=&bstemp; } InvokeSignal(functionIndex, bsptr, &p); } }
bool TwoWayAuthentication::Challenge(VENet::VEString identifier, AddressOrGUID remoteSystem) { DataStructures::HashIndex skhi = passwords.GetIndexOf(identifier.C_String()); if (skhi.IsInvalid()) return false; VENet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_NEGOTIATION); bsOut.Write((MessageID)ID_NONCE_REQUEST); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,remoteSystem,false); PendingChallenge pc; pc.identifier=identifier; pc.remoteSystem=remoteSystem; pc.time=VENet::GetTime(); pc.sentHash=false; outgoingChallenges.Push(pc,_FILE_AND_LINE_); return true; }
void RPC4::InvokeSignal(DataStructures::HashIndex functionIndex, RakNet::BitStream *serializedParameters, Packet *packet) { if (functionIndex.IsInvalid()) return; interruptSignal=false; LocalSlot *localSlot = localSlots.ItemAtIndex(functionIndex); unsigned int i; i=0; while (i < localSlot->slotObjects.Size()) { localSlot->slotObjects[i].functionPointer(serializedParameters, packet); // Not threadsafe if (interruptSignal==true) break; serializedParameters->ResetReadPointer(); i++; } }
void TwoWayAuthentication::OnPasswordResult(Packet *packet) { VENet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*1); char usedNonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; bsIn.ReadAlignedBytes((unsigned char *)usedNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); char hashedNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; bsIn.ReadAlignedBytes((unsigned char *)hashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); VENet::VEString passwordIdentifier; bsIn.Read(passwordIdentifier); DataStructures::HashIndex skhi = passwords.GetIndexOf(passwordIdentifier.C_String()); if (skhi.IsInvalid()==false) { VENet::VEString password = passwords.ItemAtIndex(skhi); char testHash[HASHED_NONCE_AND_PW_LENGTH]; Hash(usedNonce, password, testHash); if (memcmp(testHash,hashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH)==0) { // Lookup the outgoing challenge and remove it from the list unsigned int i; AddressOrGUID aog(packet); for (i=0; i < outgoingChallenges.Size(); i++) { if (outgoingChallenges[i].identifier==passwordIdentifier && outgoingChallenges[i].remoteSystem==aog && outgoingChallenges[i].sentHash==true) { outgoingChallenges.RemoveAtIndex(i); PushToUser(packet->data[0], passwordIdentifier, packet); return; } } } } }
void RPC3::OnRPC3Call(const SystemAddress &systemAddress, unsigned char *data, unsigned int lengthInBytes) { RakNet::BitStream bs(data,lengthInBytes,false); DataStructures::HashIndex 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) { // Failed - Tried to call object member, however, networkIDManager system was never registered SendError(systemAddress, RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE, ""); return; } networkIdObject = networkIdManager->GET_OBJECT_FROM_ID<NetworkIDObject*>(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::Instance()->DecodeString(strIdentifier,512,&bs,0); bs.ReadCompressed(bitsOnStack); RakNet::BitStream serializedParameters; if (bitsOnStack>0) { serializedParameters.AddBitsAndReallocate(bitsOnStack); // BITS_TO_BYTES is correct, why did I change this? 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::Instance()->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); } }
PluginReceiveResult RPC4::OnReceive(Packet *packet) { if (packet->data[0]==ID_RPC_PLUGIN) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(2); if (packet->data[1]==ID_RPC4_CALL) { RakNet::RakString functionName; bsIn.ReadCompressed(functionName); bool isBlocking; bsIn.Read(isBlocking); if (isBlocking==false) { DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(functionName.C_String()); if (skhi.IsInvalid()) { RakNet::BitStream bsOut; bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR); bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); return RR_STOP_PROCESSING_AND_DEALLOCATE; } void ( *fp ) ( RakNet::BitStream *, Packet * ); fp = registeredNonblockingFunctions.ItemAtIndex(skhi); bsIn.AlignReadToByteBoundary(); fp(&bsIn,packet); } else { DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(functionName.C_String()); if (skhi.IsInvalid()) { RakNet::BitStream bsOut; bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR); bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); return RR_STOP_PROCESSING_AND_DEALLOCATE; } void ( *fp ) ( RakNet::BitStream *, RakNet::BitStream *, Packet * ); fp = registeredBlockingFunctions.ItemAtIndex(skhi); RakNet::BitStream returnData; bsIn.AlignReadToByteBoundary(); fp(&bsIn, &returnData, packet); RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_RETURN); returnData.ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(returnData); SendUnified(&out,IMMEDIATE_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); } } else { RakAssert(packet->data[1]==ID_RPC4_RETURN); blockingReturnValue.Reset(); blockingReturnValue.Read(bsIn); gotBlockingReturnValue=true; } return RR_STOP_PROCESSING_AND_DEALLOCATE; } bool objectExists; unsigned int index, index2; index = localCallbacks.GetIndexFromKey(packet->data[0],&objectExists); if (objectExists) { LocalCallback *lc; lc = localCallbacks[index]; for (index2=0; index2 < lc->functions.Size(); index2++) { RakNet::BitStream bsIn(packet->data, packet->length, false); DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(lc->functions[index2].C_String()); if (skhi.IsInvalid()==false) { void ( *fp ) ( RakNet::BitStream *, Packet * ); fp = registeredNonblockingFunctions.ItemAtIndex(skhi); bsIn.AlignReadToByteBoundary(); fp(&bsIn,packet); } } } return RR_CONTINUE_PROCESSING; }
void RPC4::CallLoopback( const char* uniqueID, RakNet::BitStream * bitStream ) { Packet *p=0; DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID); if (skhi.IsInvalid()==true) { if (rakPeerInterface) p=AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p=packetizedTCP->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1); #endif if (rakPeerInterface) p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p->guid=UNASSIGNED_RAKNET_GUID; #endif p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS; p->systemAddress.systemIndex=(SystemIndex)-1; p->data[0]=ID_RPC_REMOTE_ERROR; p->data[1]=RPC_ERROR_FUNCTION_NOT_REGISTERED; strcpy((char*) p->data+2, uniqueID); PushBackPacketUnified(p,false); return; } RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_CALL); out.WriteCompressed(uniqueID); out.Write(false); // nonblocking if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } if (rakPeerInterface) p=AllocatePacketUnified(out.GetNumberOfBytesUsed()); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p=packetizedTCP->AllocatePacket(out.GetNumberOfBytesUsed()); #endif if (rakPeerInterface) p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p->guid=UNASSIGNED_RAKNET_GUID; #endif p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS; p->systemAddress.systemIndex=(SystemIndex)-1; memcpy(p->data,out.GetData(),out.GetNumberOfBytesUsed()); PushBackPacketUnified(p,false); return; }
bool RPC3::IsFunctionRegistered(const char *uniqueIdentifier) { DataStructures::HashIndex i = GetLocalFunctionIndex(uniqueIdentifier); return i.IsInvalid()==false; }
PluginReceiveResult MessageFilter::OnReceive(Packet *packet) { DataStructures::HashIndex index; unsigned char messageId; switch (packet->data[0]) { case ID_NEW_INCOMING_CONNECTION: case ID_CONNECTION_REQUEST_ACCEPTED: case ID_CONNECTION_LOST: case ID_DISCONNECTION_NOTIFICATION: case ID_CONNECTION_ATTEMPT_FAILED: case ID_NO_FREE_INCOMING_CONNECTIONS: case ID_IP_RECENTLY_CONNECTED: case ID_CONNECTION_BANNED: case ID_INVALID_PASSWORD: case ID_UNCONNECTED_PONG: case ID_ALREADY_CONNECTED: case ID_ADVERTISE_SYSTEM: case ID_REMOTE_DISCONNECTION_NOTIFICATION: case ID_REMOTE_CONNECTION_LOST: case ID_REMOTE_NEW_INCOMING_CONNECTION: case ID_DOWNLOAD_PROGRESS: break; default: if (packet->data[0]==ID_TIMESTAMP) { if (packet->length<sizeof(MessageID) + sizeof(RakNet::TimeMS)) return RR_STOP_PROCESSING_AND_DEALLOCATE; // Invalid message messageId=packet->data[sizeof(MessageID) + sizeof(RakNet::TimeMS)]; } else messageId=packet->data[0]; // If this system is filtered, check if this message is allowed. If not allowed, return RR_STOP_PROCESSING_AND_DEALLOCATE // index = systemList.GetIndexFromKey(packet->addressOrGUID, &objectExists); index = systemList.GetIndexOf(packet); if (index.IsInvalid()) break; if (systemList.ItemAtIndex(index).filter->allowedIDs[messageId]==false) { OnInvalidMessage(systemList.ItemAtIndex(index).filter, packet, packet->data[0]); return RR_STOP_PROCESSING_AND_DEALLOCATE; } if (packet->data[0]==ID_RPC_PLUGIN) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(2); RakNet::RakString functionName; bsIn.ReadCompressed(functionName); if (systemList.ItemAtIndex(index).filter->allowedRPC4.HasData(functionName)==false) { OnInvalidMessage(systemList.ItemAtIndex(index).filter, packet, packet->data[0]); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } break; } return RR_CONTINUE_PROCESSING; }