void EncodeClassName( char *name, char *identifier ) { RakNet::BitStream bitStream; int index = 0; unsigned char byte; while ( index < MAXIMUM_CLASS_IDENTIFIER_LENGTH - 1 ) { if ( name[ index ] == 0 ) break; // This should generate a unique identifier for any realistic class name that is 5/8th the length of the actual name and weakly encrypts and compresses it if ( name[ index ] >= 'a' && name[ index ] <= 'z' ) byte = name[ index ] - 'a'; else if ( name[ index ] >= 'A' && name[ index ] <= 'Z' ) byte = name[ index ] - 'A'; else if ( name[ index ] >= '0' && name[ index ] <= '9' ) byte = name[ index ] - '0'; else byte = name[ index ] << 3; bitStream.WriteBits( ( unsigned char* ) & byte, 5 ); index++; } #ifdef _DEBUG memset( identifier, 0, MAXIMUM_CLASS_IDENTIFIER_LENGTH ); #endif identifier[ 0 ] = ( char ) ( bitStream.GetNumberOfBytesUsed() ); memcpy( identifier + 1, bitStream.GetData(), bitStream.GetNumberOfBytesUsed() ); }
void Server::UpdatePingResponse() { ECS::Entity* serverInfoEntity = m_world->GetTagManager()->GetEntityByTag("ServerInformation"); Network::ServerInformationComponent* serverInfo = m_world->GetEntityManager()->GetComponent<Network::ServerInformationComponent>(serverInfoEntity); RakNet::BitStream bs; serverInfo->Information.Serialize(true, &bs); const unsigned char* data = bs.GetData(); unsigned int size = bs.GetNumberOfBytesUsed(); m_peer->SetOfflinePingResponse((const char*)bs.GetData(), bs.GetNumberOfBytesUsed()); }
void TwoWayAuthentication::PushToUser(MessageID messageId, RakNet::RakString password, RakNet::AddressOrGUID remoteSystem) { RakNet::BitStream output; output.Write(messageId); if (password.IsEmpty()==false) output.Write(password); Packet *p = AllocatePacketUnified(output.GetNumberOfBytesUsed()); p->systemAddress=remoteSystem.systemAddress; p->systemAddress.systemIndex=(SystemIndex)-1; p->guid=remoteSystem.rakNetGuid; p->wasGeneratedLocally=true; memcpy(p->data, output.GetData(), output.GetNumberOfBytesUsed()); rakPeerInterface->PushBackPacket(p, true); }
void UploadInstanceToCloud(RakNet::CloudClient *cloudClient, RakNet::RakNetGUID serverGuid) { RakNet::CloudKey cloudKey(CLOUD_CLIENT_PRIMARY_KEY,0); RakNet::BitStream bs; bs.Write("Hello World"); // This could be anything such as player list, game name, etc. cloudClient->Post(&cloudKey, bs.GetData(), bs.GetNumberOfBytesUsed(), serverGuid); }
void Network::send_input(){ if(status=="client"){ if(game.in_progress){ if(commands_this_second<rate_commands && ++counter_commands>=(uint32_t)ceil(UPDATE_RATE/(double)rate_commands)){ counter_commands=0; commands_this_second++; RakNet::BitStream bitstream; bitstream.Write((RakNet::MessageID)ID_GAME_INPUT); bitstream.WriteCompressed((int)command_buffer.size()); for(int i=0;i<command_buffer.size();i++){ bitstream.WriteCompressed((RakNet::RakString)command_buffer[i].c_str()); } command_buffer.clear(); bitstream.WriteCompressed((int)game.command_states.size()); for(int i=0;i<game.command_states.size();i++){ bitstream.WriteCompressed((RakNet::RakString)game.command_states[i].c_str()); } stat_counter_bytes_sent+=bitstream.GetNumberOfBytesUsed(); peer->Send(&bitstream,HIGH_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_INPUT,server_id,false); } } } }
void NatTypeDetectionClient::OnTestPortRestricted(Packet *packet) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(sizeof(MessageID)); RakNet::RakString s3p4StrAddress; bsIn.Read(s3p4StrAddress); unsigned short s3p4Port; bsIn.Read(s3p4Port); DataStructures::List<RakNetSocket2* > sockets; rakPeerInterface->GetSockets(sockets); SystemAddress s3p4Addr = sockets[0]->GetBoundAddress(); s3p4Addr.FromStringExplicitPort(s3p4StrAddress.C_String(), s3p4Port); // Send off the RakNet socket to the specified address, message is unformatted // Server does this twice, so don't have to unduly worry about packetloss RakNet::BitStream bsOut; bsOut.Write((MessageID) NAT_TYPE_PORT_RESTRICTED); bsOut.Write(rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS)); // SocketLayer::SendTo_PC( sockets[0], (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), s3p4Addr, __FILE__, __LINE__ ); RNS2_SendParameters bsp; bsp.data = (char*) bsOut.GetData(); bsp.length = bsOut.GetNumberOfBytesUsed(); bsp.systemAddress=s3p4Addr; sockets[0]->Send(&bsp, _FILE_AND_LINE_); }
void Router2::SendOOBFromSpecifiedSocket(OutOfBandIdentifiers oob, SystemAddress sa, SOCKET socket) { RakNet::BitStream bs; rakPeerInterface->WriteOutOfBandHeader(&bs); bs.Write((unsigned char) oob); SocketLayer::SendTo_PC( socket, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), sa, __FILE__, __LINE__ ); }
SQLite3ServerPlugin::SQLExecThreadOutput ExecStatementThread(SQLite3ServerPlugin::SQLExecThreadInput threadInput, bool *returnOutput, void* perThreadData) { unsigned int queryId; RakNet::RakString dbIdentifier; RakNet::RakString inputStatement; RakNet::BitStream bsIn((unsigned char*) threadInput.data, threadInput.length, false); bsIn.IgnoreBytes(sizeof(MessageID)); bsIn.Read(queryId); bsIn.Read(dbIdentifier); bsIn.Read(inputStatement); // bool isRequest; // bsIn.Read(isRequest); bsIn.IgnoreBits(1); char *errorMsg; RakNet::RakString errorMsgStr; SQLite3Table outputTable; sqlite3_exec(threadInput.dbHandle, inputStatement.C_String(), PerRowCallback, &outputTable, &errorMsg); if (errorMsg) { errorMsgStr=errorMsg; sqlite3_free(errorMsg); } RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_SQLite3_EXEC); bsOut.Write(queryId); bsOut.Write(dbIdentifier); bsOut.Write(inputStatement); bsOut.Write(false); bsOut.Write(errorMsgStr); outputTable.Serialize(&bsOut); // Free input data rakFree_Ex(threadInput.data,__FILE__,__LINE__); // Copy to output data SQLite3ServerPlugin::SQLExecThreadOutput threadOutput; threadOutput.data=(char*) rakMalloc_Ex(bsOut.GetNumberOfBytesUsed(),__FILE__,__LINE__); memcpy(threadOutput.data,bsOut.GetData(),bsOut.GetNumberOfBytesUsed()); threadOutput.length=bsOut.GetNumberOfBytesUsed(); threadOutput.sender=threadInput.sender; // SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); *returnOutput=true; return threadOutput; }
void ServerInfo::writeToBitstream(RakNet::BitStream& stream) { stream.Write(activegames); stream.Write(name, sizeof(name)); stream.Write(waitingplayers); stream.Write(description, sizeof(description)); assert( stream.GetNumberOfBytesUsed() == BLOBBY_SERVER_PRESENT_PACKET_SIZE); }
void FileListTransfer::PushReference(SystemAddress systemAddress) { // Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this unsigned int i=0; unsigned int bytesRead; char *dataBlocks[2]; int lengths[2]; RakNet::BitStream outBitstream; while (i < filesToPush.Size()) { if (filesToPush[i].systemAddress==systemAddress) { outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH); outBitstream.Write(filesToPush[i].fileListNode.context); outBitstream.Write(filesToPush[i].setID); stringCompressor->EncodeString(filesToPush[i].fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(filesToPush[i].setIndex); outBitstream.WriteCompressed(filesToPush[i].fileListNode.dataLengthBytes); // Original length in bytes // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(filesToPush[i].chunkSize, __FILE__, __LINE__); if (buff==0) { notifyOutOfMemory(__FILE__, __LINE__); continue; } bytesRead=filesToPush[i].incrementalReadInterface->GetFilePart(filesToPush[i].fileListNode.fullPathToFile, filesToPush[i].currentOffset, filesToPush[i].chunkSize, buff, filesToPush[i].fileListNode.context); outBitstream.WriteCompressed(filesToPush[i].currentOffset); filesToPush[i].currentOffset+=bytesRead; outBitstream.WriteCompressed(bytesRead); bool done = bytesRead!=filesToPush[i].chunkSize; outBitstream.Write(done); if (callback) { callback->OnFilePush(filesToPush[i].fileListNode.filename, filesToPush[i].fileListNode.fileLengthBytes, filesToPush[i].currentOffset-bytesRead, bytesRead, done, filesToPush[i].systemAddress); } dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(char*) buff; lengths[1]=bytesRead; //rakPeerInterface->SendList(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false); SendListUnified(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false); if (done) { // Done RakNet::OP_DELETE_ARRAY(filesToPush[i].fileListNode.filename, __FILE__, __LINE__); filesToPush.RemoveAtIndex(i); } rakFree_Ex(buff, __FILE__, __LINE__ ); return; } else i++; } }
void Network::send_connected(){ if(status=="client"){ RakNet::BitStream bitstream; bitstream.Write((RakNet::MessageID)ID_GAME_CONNECTED); stat_counter_bytes_sent+=bitstream.GetNumberOfBytesUsed(); peer->Send(&bitstream,MEDIUM_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_CONNECTION,server_id,false); } }
void NetworkEngine::updatePingResponse() { RakNet::BitStream data; if(isLobby()) { data.Write1(); unsigned char numPlayers = (unsigned char) peer->NumberOfConnections(); data.Write(numPlayers); std::cout << "Total players: " << (unsigned int) numPlayers << std::endl; peer->SetOfflinePingResponse((char *)data.GetData(), data.GetNumberOfBytesUsed()); } else { data.Write0(); } peer->SetOfflinePingResponse((char *)data.GetData(), data.GetNumberOfBytesUsed()); }
void CloudServerHelper::OnConnectionCountChange(RakPeerInterface *rakPeer, CloudClient *cloudClient) { RakNet::BitStream bs; CloudKey cloudKey(CLOUD_SERVER_CONNECTION_COUNT_PRIMARY_KEY,0); unsigned short numberOfSystems; rakPeer->GetConnectionList(0, &numberOfSystems); bs.Write(numberOfSystems); cloudClient->Post(&cloudKey, bs.GetData(), bs.GetNumberOfBytesUsed(), rakPeer->GetMyGUID()); }
SQLLogResult SQLiteClientLoggerPlugin::SqlLog( bool isFunctionCall, const char *tableName, const char *columnNames, const char *file, const int line, const ParameterListHelper ¶meterList ) { if (recursiveCheck==true) return SQLLR_RECURSION; recursiveCheck=true; RakNet::BitStream bitStream; SerializeHeader(&bitStream, isFunctionCall, tableName, columnNames, file, line, parameterList.paramCount); // int i; //for (i=0; i < parameterList.paramCount; i++) // parameterList.parms[i].Serialize(&bitStream); if (parameterList.paramCount>=1) parameterList.p0.Serialize(&bitStream); if (parameterList.paramCount>=2) parameterList.p1.Serialize(&bitStream); if (parameterList.paramCount>=3) parameterList.p2.Serialize(&bitStream); if (parameterList.paramCount>=4) parameterList.p3.Serialize(&bitStream); if (parameterList.paramCount>=5) parameterList.p4.Serialize(&bitStream); if (parameterList.paramCount>=6) parameterList.p5.Serialize(&bitStream); if (parameterList.paramCount>=7) parameterList.p6.Serialize(&bitStream); if (parameterList.paramCount>=8) parameterList.p7.Serialize(&bitStream); if (parameterList.paramCount>=9) parameterList.p8.Serialize(&bitStream); if (parameterList.paramCount>=10) parameterList.p9.Serialize(&bitStream); if (parameterList.paramCount>=11) parameterList.p10.Serialize(&bitStream); if (parameterList.paramCount>=12) parameterList.p11.Serialize(&bitStream); if (parameterList.paramCount>=13) parameterList.p12.Serialize(&bitStream); if (parameterList.paramCount>=14) parameterList.p13.Serialize(&bitStream); if (parameterList.paramCount>=15) parameterList.p14.Serialize(&bitStream); if (memoryConstraint!=0 && tcpInterface) { if (tcpInterface->GetOutgoingDataBufferSize(serverAddress)+bitStream.GetNumberOfBytesUsed()>=memoryConstraint) { recursiveCheck=false; return SQLLR_WOULD_EXCEED_MEMORY_CONSTRAINT; } } SendUnified(&bitStream, LOW_PRIORITY, RELIABLE_ORDERED, 1, serverAddress, false); recursiveCheck=false; return SQLLR_OK; }
bool SystemAddressList::Save(const char *filename) { RakNet::BitStream temp; Serialize(&temp); FILE *fp = fopen(filename, "wb"); if (fp) { fwrite(temp.GetData(), (size_t) temp.GetNumberOfBytesUsed(), 1, fp); fclose(fp); return true; } return false; }
void Network::send_client_data(bool first_send){ if(status=="client"){ char ordering_channel=ORDERING_CHANNEL_CLIENT_DATA; if(first_send){ ordering_channel=ORDERING_CHANNEL_CONNECTION; } RakNet::BitStream bitstream; bitstream.Write((RakNet::MessageID)ID_GAME_CLIENT_DATA); bitstream.WriteCompressed(first_send); bitstream.WriteCompressed((RakNet::RakString)game.option_name.c_str()); bitstream.WriteCompressed(rate_bytes); bitstream.WriteCompressed(rate_updates); stat_counter_bytes_sent+=bitstream.GetNumberOfBytesUsed(); peer->Send(&bitstream,MEDIUM_PRIORITY,RELIABLE_ORDERED,ordering_channel,server_id,false); } }
void NatTypeDetectionClient::OnTestPortRestricted(Packet *packet) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(sizeof(MessageID)); RakNet::RakString s3p4StrAddress; bsIn.Read(s3p4StrAddress); unsigned short s3p4Port; bsIn.Read(s3p4Port); SystemAddress s3p4Addr(s3p4StrAddress.C_String(), s3p4Port); DataStructures::List<RakNetSmartPtr<RakNetSocket> > sockets; rakPeerInterface->GetSockets(sockets); // Send off the RakNet socket to the specified address, message is unformatted // Server does this twice, so don't have to unduly worry about packetloss RakNet::BitStream bsOut; bsOut.Write((MessageID) NAT_TYPE_PORT_RESTRICTED); bsOut.Write(rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS)); SocketLayer::Instance()->SendTo_PC( sockets[0]->s, (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), s3p4Addr.binaryAddress, s3p4Addr.port); }
void RakVoice::SetLoopbackMode(bool enabled) { if (enabled) { Packet p; RakNet::BitStream out; out.Write((unsigned char)ID_RAKVOICE_OPEN_CHANNEL_REQUEST); out.Write((int32_t)sampleRate); p.data=out.GetData(); p.systemAddress=UNASSIGNED_SYSTEM_ADDRESS; p.guid=UNASSIGNED_RAKNET_GUID; p.length=out.GetNumberOfBytesUsed(); OpenChannel(&p); } else { FreeChannelMemory(UNASSIGNED_RAKNET_GUID); } loopbackMode=enabled; }
void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.GetPort()==0) return; RakNet::BitStream oob; oob.Write(oobId); oob.Write(sp.sessionId); // RakAssert(sp.sessionId<100); if (oobId==ID_NAT_ESTABLISH_BIDIRECTIONAL) oob.Write(sa.GetPort()); char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.GetPort(),(const char*) oob.GetData(),oob.GetNumberOfBytesUsed()); if (natPunchthroughDebugInterface) { sa.ToString(true,ipAddressString); char guidString[128]; sp.targetGuid.ToString(guidString); if (oobId==ID_NAT_ESTABLISH_UNIDIRECTIONAL) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Sent OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.", guidString, ipAddressString)); else natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Sent OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.", guidString, ipAddressString)); } }
PluginReceiveResult NatPunchthroughClient::OnReceive(Packet *packet) { switch (packet->data[0]) { case ID_NAT_GET_MOST_RECENT_PORT: { OnGetMostRecentPort(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_NAT_PUNCHTHROUGH_FAILED: case ID_NAT_PUNCHTHROUGH_SUCCEEDED: if (packet->wasGeneratedLocally==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; break; case ID_NAT_RESPOND_BOUND_ADDRESSES: { RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(MessageID)); unsigned char boundAddressCount; bs.Read(boundAddressCount); if (boundAddressCount<2) { if (natPunchthroughDebugInterface) natPunchthroughDebugInterface->OnClientMessage("INCAPABLE_PORT_STRIDE"); hasPortStride=INCAPABLE_PORT_STRIDE; SendQueuedOpenNAT(); } SystemAddress boundAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS]; for (int i=0; i < boundAddressCount && i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++) { bs.Read(boundAddresses[i]); if (boundAddresses[i]!=packet->systemAddress) { RakNet::BitStream outgoingBs; outgoingBs.Write((MessageID)ID_NAT_PING); uint16_t externalPort = rakPeerInterface->GetExternalID(packet->systemAddress).GetPort(); outgoingBs.Write( externalPort ); rakPeerInterface->SendOutOfBand((const char*) boundAddresses[i].ToString(false),boundAddresses[i].GetPort(),(const char*) outgoingBs.GetData(),outgoingBs.GetNumberOfBytesUsed()); break; } } } break; case ID_OUT_OF_BAND_INTERNAL: if (packet->length>=2 && packet->data[1]==ID_NAT_PONG) { RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(MessageID)*2); uint16_t externalPort; bs.Read(externalPort); uint16_t externalPort2; bs.Read(externalPort2); portStride = externalPort2 - externalPort; hasPortStride=HAS_PORT_STRIDE; if (natPunchthroughDebugInterface) natPunchthroughDebugInterface->OnClientMessage(RakString("HAS_PORT_STRIDE %i. Server first external port %i. Server second external port %i.", portStride, externalPort, externalPort2)); SendQueuedOpenNAT(); return RR_STOP_PROCESSING_AND_DEALLOCATE; } else if (packet->length>=2 && (packet->data[1]==ID_NAT_ESTABLISH_UNIDIRECTIONAL || packet->data[1]==ID_NAT_ESTABLISH_BIDIRECTIONAL) && sp.nextActionTime!=0) { RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(2); uint16_t sessionId; bs.Read(sessionId); // RakAssert(sessionId<100); if (sessionId!=sp.sessionId) break; char ipAddressString[32]; packet->systemAddress.ToString(true,ipAddressString); // sp.targetGuid==packet->guid is because the internal IP addresses reported may include loopbacks not reported by RakPeer::IsLocalIP() if (packet->data[1]==ID_NAT_ESTABLISH_UNIDIRECTIONAL && sp.targetGuid==packet->guid) { if (natPunchthroughDebugInterface) { char guidString[128]; sp.targetGuid.ToString(guidString); natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Received ID_NAT_ESTABLISH_UNIDIRECTIONAL from guid %s, system address %s.", guidString, ipAddressString)); } if (sp.testMode!=SendPing::PUNCHING_FIXED_PORT) { sp.testMode=SendPing::PUNCHING_FIXED_PORT; sp.retryCount+=sp.attemptCount*pc.UDP_SENDS_PER_PORT_EXTERNAL; sp.targetAddress=packet->systemAddress; // Keeps trying until the other side gives up too, in case it is unidirectional sp.punchingFixedPortAttempts=pc.UDP_SENDS_PER_PORT_EXTERNAL*(pc.MAX_PREDICTIVE_PORT_RANGE+1); } SendOutOfBand(sp.targetAddress,ID_NAT_ESTABLISH_BIDIRECTIONAL); } else if (packet->data[1]==ID_NAT_ESTABLISH_BIDIRECTIONAL && sp.targetGuid==packet->guid) { // They send back our port unsigned short ourExternalPort; bs.Read(ourExternalPort); if (nextExternalPort==0) { nextExternalPort=ourExternalPort; } else { if (sp.testMode!=SendPing::TESTING_INTERNAL_IPS && sp.testMode!=SendPing::WAITING_FOR_INTERNAL_IPS_RESPONSE) { if (hasPortStride!=HAS_PORT_STRIDE) { portStride = ourExternalPort - nextExternalPort; hasPortStride=HAS_PORT_STRIDE; if (natPunchthroughDebugInterface) { natPunchthroughDebugInterface->OnClientMessage(RakString("Estimated port stride from incoming connection at %i", portStride)); } SendQueuedOpenNAT(); } nextExternalPort += portStride * (pc.MAX_PREDICTIVE_PORT_RANGE+1); if (natPunchthroughDebugInterface) { natPunchthroughDebugInterface->OnClientMessage(RakString("Estimated next external port %i", nextExternalPort)); } } } SendOutOfBand(packet->systemAddress,ID_NAT_ESTABLISH_BIDIRECTIONAL); // Tell the user about the success sp.targetAddress=packet->systemAddress; PushSuccess(); //UpdateGroupPunchOnNatResult(sp.facilitator, sp.targetGuid, sp.targetAddress, 1); OnReadyForNextPunchthrough(); bool removedFromFailureQueue=RemoveFromFailureQueue(); if (natPunchthroughDebugInterface) { char guidString[128]; sp.targetGuid.ToString(guidString); if (removedFromFailureQueue) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Punchthrough to guid %s, system address %s succeeded on 2nd attempt.", guidString, ipAddressString)); else natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Punchthrough to guid %s, system address %s succeeded on 1st attempt.", guidString, ipAddressString)); } } // mostRecentNewExternalPort=packet->systemAddress.GetPort(); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_NAT_ALREADY_IN_PROGRESS: { RakNet::BitStream incomingBs(packet->data, packet->length, false); incomingBs.IgnoreBytes(sizeof(MessageID)); RakNetGUID targetGuid; incomingBs.Read(targetGuid); // Don't update group, just use later message // UpdateGroupPunchOnNatResult(packet->systemAddress, targetGuid, UNASSIGNED_SYSTEM_ADDRESS, 2); if (natPunchthroughDebugInterface) { char guidString[128]; targetGuid.ToString(guidString); natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Punchthrough retry to guid %s failed due to ID_NAT_ALREADY_IN_PROGRESS. Returning failure.", guidString)); } } break; case ID_NAT_TARGET_NOT_CONNECTED: case ID_NAT_CONNECTION_TO_TARGET_LOST: case ID_NAT_TARGET_UNRESPONSIVE: { const char *reason; if (packet->data[0]==ID_NAT_TARGET_NOT_CONNECTED) reason=(char *)"ID_NAT_TARGET_NOT_CONNECTED"; else if (packet->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST) reason=(char *)"ID_NAT_CONNECTION_TO_TARGET_LOST"; else reason=(char *)"ID_NAT_TARGET_UNRESPONSIVE"; RakNet::BitStream incomingBs(packet->data, packet->length, false); incomingBs.IgnoreBytes(sizeof(MessageID)); RakNetGUID targetGuid; incomingBs.Read(targetGuid); //UpdateGroupPunchOnNatResult(packet->systemAddress, targetGuid, UNASSIGNED_SYSTEM_ADDRESS, 2); if (packet->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST || packet->data[0]==ID_NAT_TARGET_UNRESPONSIVE) { uint16_t sessionId; incomingBs.Read(sessionId); if (sessionId!=sp.sessionId) break; } unsigned int i; for (i=0; i < failedAttemptList.Size(); i++) { if (failedAttemptList[i].guid==targetGuid) { if (natPunchthroughDebugInterface) { char guidString[128]; targetGuid.ToString(guidString); natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Punchthrough retry to guid %s failed due to %s.", guidString, reason)); } // If the retry target is not connected, or loses connection, or is not responsive, then previous failures cannot be retried. // Don't need to return failed, the other messages indicate failure anyway /* Packet *p = AllocatePacketUnified(sizeof(MessageID)); p->data[0]=ID_NAT_PUNCHTHROUGH_FAILED; p->systemAddress=failedAttemptList[i].addr; p->systemAddress.systemIndex=(SystemIndex)-1; p->guid=failedAttemptList[i].guid; rakPeerInterface->PushBackPacket(p, false); */ failedAttemptList.RemoveAtIndexFast(i); break; } } if (natPunchthroughDebugInterface) { char guidString[128]; targetGuid.ToString(guidString); natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Punchthrough attempt to guid %s failed due to %s.", guidString, reason)); } // Stop trying punchthrough sp.nextActionTime=0; /* RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); RakNetGUID failedSystem; bs.Read(failedSystem); bool deletedFirst=false; unsigned int i=0; while (i < pendingOpenNAT.Size()) { if (pendingOpenNAT[i].destination==failedSystem) { if (i==0) deletedFirst=true; pendingOpenNAT.RemoveAtIndex(i); } else i++; } // Failed while in progress. Go to next in attempt queue if (deletedFirst && pendingOpenNAT.Size()) { SendPunchthrough(pendingOpenNAT[0].destination, pendingOpenNAT[0].facilitator); sp.nextActionTime=0; } */ } break; case ID_TIMESTAMP: if (packet->data[sizeof(MessageID)+sizeof(RakNet::Time)]==ID_NAT_CONNECT_AT_TIME) { OnConnectAtTime(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } break; } return RR_CONTINUE_PROCESSING; }
PluginReceiveResult NatPunchthroughServer::OnReceive(Packet *packet) { switch (packet->data[0]) { case ID_NAT_PUNCHTHROUGH_REQUEST: OnNATPunchthroughRequest(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_NAT_GET_MOST_RECENT_PORT: OnGetMostRecentPort(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_NAT_CLIENT_READY: OnClientReady(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_NAT_REQUEST_BOUND_ADDRESSES: { RakNet::BitStream outgoingBs; outgoingBs.Write((MessageID)ID_NAT_RESPOND_BOUND_ADDRESSES); if (boundAddresses[0]==UNASSIGNED_SYSTEM_ADDRESS) { DataStructures::List<RakNetSocket2* > sockets; rakPeerInterface->GetSockets(sockets); for (int i=0; i < sockets.Size() && i < MAXIMUM_NUMBER_OF_INTERNAL_IDS; i++) { boundAddresses[i]=sockets[i]->GetBoundAddress(); boundAddressCount++; } } outgoingBs.Write(boundAddressCount); for (int i=0; i < boundAddressCount; i++) { outgoingBs.Write(boundAddresses[i]); } rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_NAT_PING: { } return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_OUT_OF_BAND_INTERNAL: if (packet->length>=2 && packet->data[1]==ID_NAT_PING) { RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(MessageID)*2); uint16_t externalPort; bs.Read(externalPort); RakNet::BitStream outgoingBs; outgoingBs.Write((MessageID)ID_NAT_PONG); outgoingBs.Write(externalPort); uint16_t externalPort2 = packet->systemAddress.GetPort(); outgoingBs.Write(externalPort2); rakPeerInterface->SendOutOfBand((const char*) packet->systemAddress.ToString(false),packet->systemAddress.GetPort(),(const char*) outgoingBs.GetData(),outgoingBs.GetNumberOfBytesUsed()); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } return RR_CONTINUE_PROCESSING; }
void NatTypeDetectionServer::Update(void) { int i=0; RakNet::TimeMS time = RakNet::GetTimeMS(); RakNet::BitStream bs; SystemAddress boundAddress; // Only socket that receives messages is s3p4, to see if the external address is different than that of the connection to rakPeerInterface char data[ MAXIMUM_MTU_SIZE ]; int len; SystemAddress senderAddr; len=NatTypeRecvFrom(data, s3p4, senderAddr); // Client is asking us if this is port restricted. Only client requests of this type come in on s3p4 while (len>0 && data[0]==NAT_TYPE_PORT_RESTRICTED) { RakNet::BitStream bsIn((unsigned char*) data,len,false); RakNetGUID senderGuid; bsIn.IgnoreBytes(sizeof(MessageID)); bool readSuccess = bsIn.Read(senderGuid); RakAssert(readSuccess); if (readSuccess) { unsigned int i = GetDetectionAttemptIndex(senderGuid); if (i!=(unsigned int)-1) { bs.Reset(); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); // If different, then symmetric if (senderAddr!=natDetectionAttempts[i].systemAddress) { printf("Determined client is symmetric\n"); bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); } else { // else port restricted printf("Determined client is port restricted\n"); bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED); } rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); // Done natDetectionAttempts.RemoveAtIndexFast(i); } else { // RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0); } } else { // RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0); } len=NatTypeRecvFrom(data, s3p4, senderAddr); } while (i < (int) natDetectionAttempts.Size()) { if (time > natDetectionAttempts[i].nextStateTime) { natDetectionAttempts[i].detectionState=(NATDetectionState)((int)natDetectionAttempts[i].detectionState+1); natDetectionAttempts[i].nextStateTime=time+natDetectionAttempts[i].timeBetweenAttempts; SystemAddress saOut; unsigned char c; bs.Reset(); switch (natDetectionAttempts[i].detectionState) { case STATE_TESTING_NONE_1: case STATE_TESTING_NONE_2: c = NAT_TYPE_NONE; printf("Testing NAT_TYPE_NONE\n"); // S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again). saOut=natDetectionAttempts[i].systemAddress; saOut.SetPort(natDetectionAttempts[i].c2Port); SocketLayer::SendTo_PC( s4p5, (const char*) &c, 1, saOut, __FILE__, __LINE__ ); break; case STATE_TESTING_FULL_CONE_1: case STATE_TESTING_FULL_CONE_2: printf("Testing NAT_TYPE_FULL_CONE\n"); rakPeerInterface->WriteOutOfBandHeader(&bs); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_FULL_CONE); // S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done. (Else S2P3 potentially banned, do not use again). saOut=natDetectionAttempts[i].systemAddress; saOut.SetPort(natDetectionAttempts[i].systemAddress.GetPort()); SocketLayer::SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__ ); break; case STATE_TESTING_ADDRESS_RESTRICTED_1: case STATE_TESTING_ADDRESS_RESTRICTED_2: printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n"); rakPeerInterface->WriteOutOfBandHeader(&bs); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_ADDRESS_RESTRICTED); // S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done. saOut=natDetectionAttempts[i].systemAddress; saOut.SetPort(natDetectionAttempts[i].systemAddress.GetPort()); SocketLayer::SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__ ); break; case STATE_TESTING_PORT_RESTRICTED_1: case STATE_TESTING_PORT_RESTRICTED_2: // C1 sends to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1, then port-restricted cone nat. Done printf("Testing NAT_TYPE_PORT_RESTRICTED\n"); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_REQUEST); bs.Write(RakString::NonVariadic(s3p4Address)); bs.Write(s3p4Port); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); break; default: printf("Warning, exceeded final check STATE_TESTING_PORT_RESTRICTED_2.\nExpected that client would have sent NAT_TYPE_PORT_RESTRICTED on s3p4.\nDefaulting to Symmetric\n"); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); natDetectionAttempts.RemoveAtIndexFast(i); i--; break; } } i++; } }
void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.GetPort()==0) return; RakNet::BitStream oob; oob.Write(oobId); oob.Write(sp.sessionId); // RakAssert(sp.sessionId<100); if (oobId==ID_NAT_ESTABLISH_BIDIRECTIONAL) oob.Write(sa.GetPort()); char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.GetPort(),(const char*) oob.GetData(),oob.GetNumberOfBytesUsed()); if (natPunchthroughDebugInterface) { sa.ToString(true,ipAddressString); char guidString[128]; sp.targetGuid.ToString(guidString); // server - diff = my time // server = myTime + diff RakNet::Time clockDifferential = rakPeerInterface->GetClockDifferential(sp.facilitator); RakNet::Time serverTime = RakNet::GetTime() + clockDifferential; if (oobId==ID_NAT_ESTABLISH_UNIDIRECTIONAL) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); else natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); } }
const char *EmailSender::Send(const char *hostAddress, unsigned short hostPort, const char *sender, const char *recipient, const char *senderName, const char *recipientName, const char *subject, const char *body, FileList *attachedFiles, bool doPrintf, const char *password) { RakNet::Packet *packet; char query[1024]; TCPInterface tcpInterface; SystemAddress emailServer; if (tcpInterface.Start(0, 0)==false) return "Unknown error starting TCP"; emailServer=tcpInterface.Connect(hostAddress, hostPort,true); if (emailServer==UNASSIGNED_SYSTEM_ADDRESS) return "Failed to connect to host"; #if OPEN_SSL_CLIENT_SUPPORT==1 tcpInterface.StartSSLClient(emailServer); #endif RakNet::TimeMS timeoutTime = RakNet::GetTimeMS()+3000; packet=0; while (RakNet::GetTimeMS() < timeoutTime) { packet = tcpInterface.Receive(); if (packet) { if (doPrintf) RAKNET_DEBUG_PRINTF("%s", packet->data); break; } RakSleep(250); } if (packet==0) return "Timeout while waiting for initial data from server."; tcpInterface.Send("EHLO\r\n", 6, emailServer,false); const char *response; bool authenticate=false; #ifdef _MSC_VER #pragma warning(disable:4127) // conditional expression is constant #endif while (1) { response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0 && strcmp(response, "AUTHENTICATE")==0) { authenticate=true; break; } // Something other than continue? if (response!=0 && strcmp(response, "CONTINUE")!=0) return response; // Success? if (response==0) break; } if (authenticate) { sprintf(query, "EHLO %s\r\n", sender); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; if (password==0) return "Password needed"; char *outputData = RakNet::OP_NEW_ARRAY<char >((const int) (strlen(sender)+strlen(password)+2)*3, _FILE_AND_LINE_ ); RakNet::BitStream bs; char zero=0; bs.Write(&zero,1); bs.Write(sender,(const unsigned int)strlen(sender)); //bs.Write("*****@*****.**",(const unsigned int)strlen("*****@*****.**")); bs.Write(&zero,1); bs.Write(password,(const unsigned int)strlen(password)); bs.Write(&zero,1); //bs.Write("not.my.real.password",(const unsigned int)strlen("not.my.real.password")); Base64Encoding((const char*)bs.GetData(), bs.GetNumberOfBytesUsed(), outputData); sprintf(query, "AUTH PLAIN %s", outputData); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; } if (sender) sprintf(query, "MAIL From: <%s>\r\n", sender); else sprintf(query, "MAIL From: <>\r\n"); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; if (recipient) sprintf(query, "RCPT TO: <%s>\r\n", recipient); else sprintf(query, "RCPT TO: <>\r\n"); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; tcpInterface.Send("DATA\r\n", (unsigned int)strlen("DATA\r\n"), emailServer,false); // Wait for 354... response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; if (subject) { sprintf(query, "Subject: %s\r\n", subject); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); } if (senderName) { sprintf(query, "From: %s\r\n", senderName); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); } if (recipientName) { sprintf(query, "To: %s\r\n", recipientName); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); } const int boundarySize=60; char boundary[boundarySize+1]; int i,j; if (attachedFiles && attachedFiles->fileList.Size()) { rakNetRandom.SeedMT((unsigned int) RakNet::GetTimeMS()); // Random multipart message boundary for (i=0; i < boundarySize; i++) boundary[i]=Base64Map()[rakNetRandom.RandomMT()%64]; boundary[boundarySize]=0; } sprintf(query, "MIME-version: 1.0\r\n"); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); if (attachedFiles && attachedFiles->fileList.Size()) { sprintf(query, "Content-type: multipart/mixed; BOUNDARY=\"%s\"\r\n\r\n", boundary); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); sprintf(query, "This is a multi-part message in MIME format.\r\n\r\n--%s\r\n", boundary); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); } sprintf(query, "Content-Type: text/plain; charset=\"US-ASCII\"\r\n\r\n"); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); // Write the body of the email, doing some lame shitty shit where I have to make periods at the start of a newline have a second period. char *newBody; int bodyLength; bodyLength=(int)strlen(body); newBody = (char*) rakMalloc_Ex( bodyLength*3, _FILE_AND_LINE_ ); if (bodyLength>0) newBody[0]=body[0]; for (i=1, j=1; i < bodyLength; i++) { // Transform \n . \r \n into \n . . \r \n if (i < bodyLength-2 && body[i-1]=='\n' && body[i+0]=='.' && body[i+1]=='\r' && body[i+2]=='\n') { newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='\r'; newBody[j++]='\n'; i+=2; } // Transform \n . . \r \n into \n . . . \r \n // Having to process .. is a bug in the mail server - the spec says ONLY \r\n.\r\n should be transformed else if (i <= bodyLength-3 && body[i-1]=='\n' && body[i+0]=='.' && body[i+1]=='.' && body[i+2]=='\r' && body[i+3]=='\n') { newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='\r'; newBody[j++]='\n'; i+=3; } // Transform \n . \n into \n . . \r \n (this is a bug in the mail server - the spec says do not count \n alone but it does) else if (i < bodyLength-1 && body[i-1]=='\n' && body[i+0]=='.' && body[i+1]=='\n') { newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='\r'; newBody[j++]='\n'; i+=1; } // Transform \n . . \n into \n . . . \r \n (this is a bug in the mail server - the spec says do not count \n alone but it does) // In fact having to process .. is a bug too - because the spec says ONLY \r\n.\r\n should be transformed else if (i <= bodyLength-2 && body[i-1]=='\n' && body[i+0]=='.' && body[i+1]=='.' && body[i+2]=='\n') { newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='.'; newBody[j++]='\r'; newBody[j++]='\n'; i+=2; } else newBody[j++]=body[i]; } newBody[j++]='\r'; newBody[j++]='\n'; tcpInterface.Send(newBody, j, emailServer,false); rakFree_Ex(newBody, _FILE_AND_LINE_ ); int outputOffset; // What a pain in the rear. I have to map the binary to printable characters using 6 bits per character. if (attachedFiles && attachedFiles->fileList.Size()) { for (i=0; i < (int) attachedFiles->fileList.Size(); i++) { // Write boundary sprintf(query, "\r\n--%s\r\n", boundary); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); sprintf(query, "Content-Type: APPLICATION/Octet-Stream; SizeOnDisk=%i; name=\"%s\"\r\nContent-Transfer-Encoding: BASE64\r\nContent-Description: %s\r\n\r\n", attachedFiles->fileList[i].dataLengthBytes, attachedFiles->fileList[i].filename.C_String(), attachedFiles->fileList[i].filename.C_String()); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); newBody = (char*) rakMalloc_Ex( (size_t) (attachedFiles->fileList[i].dataLengthBytes*3)/2, _FILE_AND_LINE_ ); outputOffset=Base64Encoding(attachedFiles->fileList[i].data, (int) attachedFiles->fileList[i].dataLengthBytes, newBody); // Send the base64 mapped file. tcpInterface.Send(newBody, outputOffset, emailServer,false); rakFree_Ex(newBody, _FILE_AND_LINE_ ); } // Write last boundary sprintf(query, "\r\n--%s--\r\n", boundary); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); } sprintf(query, "\r\n.\r\n"); tcpInterface.Send(query, (unsigned int)strlen(query), emailServer,false); response=GetResponse(&tcpInterface, emailServer, doPrintf); if (response!=0) return response; tcpInterface.Send("QUIT\r\n", (unsigned int)strlen("QUIT\r\n"), emailServer,false); RakSleep(30); if (doPrintf) { packet = tcpInterface.Receive(); while (packet) { RAKNET_DEBUG_PRINTF("%s", packet->data); packet = tcpInterface.Receive(); } } tcpInterface.Stop(); return 0; // Success }
void ReplicaObject::writeToPacket(RakNet::BitStream * packet, REPLICA_PACKET_TYPE packetType){ if (packetType == REPLICA_PACKET_TYPE::REPLICA_CONSTRUCTION_PACKET){ packet->Write(this->objid); packet->Write(this->LOT); packet->Write((unsigned char)this->name.size()); for (unsigned int k = 0; k < this->name.size(); k++){ packet->Write(this->name.at(k)); } packet->Write(3025001UL); //packet->Write(0UL); // time_since_created_on_server (possibly) packet->Write(false); // Compressed info... to be added later packet->Write(trigger_id); // trigger_id packet->Write((bool)(spawnerObjID > 0)); if (spawnerObjID > 0) { std::cout << "Writing spawnerObjID" << std::endl; packet->Write(spawnerObjID); } // spawnerObjID packet->Write((bool)(spawner_node_id >= 0)); if (spawner_node_id >= 0) { std::cout << "Writing spawner_node_id" << std::endl; packet->Write(spawner_node_id); } // spawnerNodeID packet->Write((bool)(floatData >= 0.0)); if (floatData >= 0.0) { std::cout << "Writing floatData" << std::endl; packet->Write(floatData); } // Unknown floatData packet->Write((bool)(objectWorldState >= 0)); if (objectWorldState >= 0) { std::cout << "Writing objectWorldState" << std::endl; packet->Write(objectWorldState); } // objectWorldState packet->Write(this->gmlevel > 0); if (this->gmlevel > 0){ std::cout << "Writing gmlevel" << std::endl; packet->Write(this->gmlevel); } // gmlevel } packet->Write(true); packet->Write(false); packet->Write(false); for (std::vector<ReplicaComponent *>::iterator it = components.begin(); it != components.end(); ++it){ (*it)->writeToPacket(packet, packetType); } if (packetType == REPLICA_PACKET_TYPE::REPLICA_CONSTRUCTION_PACKET) { /*RakNet::BitStream bs; bs.Write((char)0x24); bs.Write((bool)true); bs.Write((short)280); bs.Write(packet); std::stringstream ss; ss << "ReplicaPacket_" << i << ".bin"; i++; SavePacket(ss.str(), (char*)bs.GetData(), bs.GetNumberOfBytesUsed());*/ RakNet::BitStream bs; bs.Write((char)0x27); bs.Write((short)48608); bs.Write(false); bs.Write(false); bs.Write(false); bs.Write(false); bs.Write(false); bs.Write(false); bs.Write(false); bs.Write(true); bs.Write((long)1); bs.Write((long long)1152921504606847070); std::stringstream ss; ss << "ReplicaPacket_" << i << ".bin"; i++; SavePacket(ss.str(), (char*)bs.GetData(), bs.GetNumberOfBytesUsed()); } }
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; }
// 0=failed, 1=success, 2=ignore void NatPunchthroughClient::UpdateGroupPunchOnNatResult(SystemAddress facilitator, RakNetGUID targetSystem, SystemAddress targetSystemAddress, int result) { GroupPunchRequest *gpr; unsigned long i,j,k; i=0; while (i < groupPunchRequests.Size()) { gpr = groupPunchRequests[i]; if (gpr->facilitator==facilitator) { j=0; while (j < gpr->pendingList.Size()) { if (gpr->pendingList[j]==targetSystem) { if (result==0) { gpr->failedList.Push(targetSystem, _FILE_AND_LINE_); } else if (result==1) { gpr->passedListGuid.Push(targetSystem, _FILE_AND_LINE_); gpr->passedListAddress.Push(targetSystemAddress, _FILE_AND_LINE_); } else { gpr->ignoredList.Push(targetSystem, _FILE_AND_LINE_); } gpr->pendingList.RemoveAtIndex(j); } else j++; } } if (gpr->pendingList.Size()==0) { RakNet::BitStream output; if (gpr->failedList.Size()==0) { output.Write(ID_NAT_GROUP_PUNCH_SUCCEEDED); } else { output.Write(ID_NAT_GROUP_PUNCH_FAILED); } output.WriteCasted<unsigned char>(gpr->passedListGuid.Size()); for (k=0; k < gpr->passedListGuid.Size(); k++) { output.Write(gpr->passedListGuid[k]); output.Write(gpr->passedListAddress[k]); } output.WriteCasted<unsigned char>(gpr->ignoredList.Size()); for (k=0; k < gpr->ignoredList.Size(); k++) { output.Write(gpr->ignoredList[k]); } output.WriteCasted<unsigned char>(gpr->failedList.Size()); for (k=0; k < gpr->failedList.Size(); k++) { output.Write(gpr->failedList[k]); } Packet *p = AllocatePacketUnified(output.GetNumberOfBytesUsed()); p->systemAddress=gpr->facilitator; p->systemAddress.systemIndex=(SystemIndex)-1; p->guid=rakPeerInterface->GetGuidFromSystemAddress(gpr->facilitator); p->wasGeneratedLocally=true; memcpy(p->data, output.GetData(), output.GetNumberOfBytesUsed()); rakPeerInterface->PushBackPacket(p, true); groupPunchRequests.RemoveAtIndex(i); RakNet::OP_DELETE(gpr, _FILE_AND_LINE_); } else i++; } }
void CConsole::SendRules(char* queryData, SOCKET socket, const sockaddr_in* to, int tolen) { const char* varName; char varValue[1024]; std::map<std::string, consoleVarStruct*>::iterator itor; uint16_t svrRuleCount = 0; for (itor = varMap.begin(); itor != varMap.end(); itor++) if (itor->second->varFlags & CONSOLE_VARFLAG_RULE) svrRuleCount++; uint16_t rulesLen = 13 + (svrRuleCount * 62); #ifndef _USE_BITSTREAMS char* dataBuf = new char[rulesLen]; char* dataPtr = dataBuf; memcpy(dataBuf, queryData, 11); dataBuf += 11; #else RakNet::BitStream rules; rules.Write((char*)queryData, 11); rules.Write(svrRuleCount); #endif #ifndef _USE_BITSTREAMS memcpy(dataBuf, &svrRuleCount, sizeof(uint16_t)); dataBuf += sizeof(uint16_t); #endif uint8_t varNameLen; for (itor = varMap.begin(); itor != varMap.end(); itor++) { if (itor->second->varFlags & 4) { varName = itor->first.c_str(); switch (itor->second->varType) { case CONSOLE_VARTYPE_FLOAT: sprintf(varValue, "%f", *(float*)itor->second->varValue); break; case CONSOLE_VARTYPE_INT: sprintf(varValue, "%d", *(int*)itor->second->varValue); break; case CONSOLE_VARTYPE_BOOL: sprintf(varValue, "%d", *(bool*)itor->second->varValue); break; case CONSOLE_VARTYPE_STRING: strcpy(varValue, (char*)itor->second->varValue); break; } varNameLen = strlen(varName); #ifdef _USE_BITSTREAMS rules.Write(varNameLen); rules.Write(varName, varNameLen); #else memcpy(dataBuf, &varNameLen, sizeof(uint8_t)); dataBuf += sizeof(uint8_t); memcpy(dataBuf, varName, varNameLen); dataBuf += varNameLen; #endif varNameLen = strlen(varValue); #ifdef _USE_BITSTREAMS rules.Write(varNameLen); rules.Write(varValue, varNameLen); #else memcpy(dataBuf, &varNameLen, sizeof(uint8_t)); dataBuf += sizeof(uint8_t); memcpy(dataBuf, varValue, varNameLen); dataBuf += varNameLen; #endif } } #ifdef _USE_BITSTREAMS sendto(socket, (char*)rules.GetData(), rules.GetNumberOfBytesUsed(), 0, (sockaddr*)to, tolen); #else sendto(socket, dataPtr, (int)(dataBuf - dataPtr), 0, (sockaddr*)to, tolen); delete [] dataPtr; #endif }
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize) { (void) compressData; if (callback) fileList->SetCallback(callback); unsigned int i, totalLength; RakNet::BitStream outBitstream; bool sendReference; char *dataBlocks[2]; int lengths[2]; totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { const FileListNode &fileListNode = fileList->fileList[i]; totalLength+=fileListNode.fileLengthBytes; } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); for (i=0; i < fileList->fileList.Size(); i++) { outBitstream.Reset(); sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { StoreForPush(fileList->fileList[i].context, setID, fileList->fileList[i].filename, fileList->fileList[i].fullPathToFile, i, fileList->fileList[i].fileLengthBytes, fileList->fileList[i].dataLengthBytes, recipient, priority, orderingChannel, _incrementalReadInterface, _chunkSize); continue; } outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=fileList->fileList[i].data; lengths[1]=fileList->fileList[i].dataLengthBytes; if (rakPeer) rakPeer->SendList(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } else { if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
void SendStatusPacket(RakPeerInterface *rakServer, const SystemAddress& systemAddress, UserSuccess loginStatus, string redirectIpAddress, ushort redirectPort, ushort extraDataLength) { RakNet::BitStream bitStream; // Create the bitStream // Always create the packet header CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 0, &bitStream); LoginStatusPacket loginStatusPacket; // Set the loginStatus loginStatusPacket.loginStatus = loginStatus; // Set Talk_Like_A_Pirate_String loginStatusPacket.talkLikeAPirate = "Talk_Like_A_Pirate"; loginStatusPacket.unknownString = ""; // Set client version loginStatusPacket.clientVersion1 = 1; loginStatusPacket.clientVersion2 = 10; loginStatusPacket.clientVersion3 = 64; // This is unknown data... loginStatusPacket.unknown = "_"; time_t t = time(NULL); unsigned int addr = systemAddress.binaryAddress; long long a = (long long)t * (long long)addr; std::string hash = md5(std::to_string(a)); std::wstring key = StringToWString(hash, 33); // Get the user key loginStatusPacket.userKey = key; //loginStatusPacket.userKey = "0 9 4 e 7 0 1 a c 3 b 5 5 2 0 b 4 7 8 9 5 b 3 1 8 5 7 b f 1 c 3 "; // Set chat IPs/Port and the other IP loginStatusPacket.chatIp = "192.168.0.20"; //TODO: make dynamic loginStatusPacket.chatPort = 2003; loginStatusPacket.anotherIp = "192.168.0.20"; loginStatusPacket.possibleGuid = "00000000-0000-0000-0000-000000000000"; loginStatusPacket.zeroLong = 0; // Set localization loginStatusPacket.localizationChar[0] = 0x55; loginStatusPacket.localizationChar[1] = 0x53; loginStatusPacket.localizationChar[2] = 0x00; // Subscribed? loginStatusPacket.firstLoginSubscription = 1; loginStatusPacket.subscribed = 0; loginStatusPacket.zeroLongLong = 0; loginStatusPacket.redirectIp = redirectIpAddress; loginStatusPacket.redirectPort = redirectPort; // Sett the error msg and the error msg length // This message only shows loginStatusPacket.errorMsg = ""; loginStatusPacket.errorMsgLength = loginStatusPacket.errorMsg.length(); // Set the extraBytesLength to the one the user defined loginStatusPacket.extraBytesLength = extraDataLength; // ---- CREATE BITSTREAM ---- // // Write the connectionId to bitStream bitStream.Write(loginStatusPacket.loginStatus); // Write the "Talk_Like_A_Pirate" string to bitStream WriteStringToBitStream(loginStatusPacket.talkLikeAPirate.c_str(), 18, 33, &bitStream); // Write 7 blocks of data (length: 33) to bitStream // In the original login_status_ok.bin, these sometimes ended in // bytes other than 0x00, but losing that doesn't seem to have much of an effect... yet. for (int i = 0; i < 7; i++) { WriteStringToBitStream(loginStatusPacket.unknownString.c_str(), 0, 33, &bitStream); } // Write the clientVersion to bitStream (all 3 parts) bitStream.Write(loginStatusPacket.clientVersion1); bitStream.Write(loginStatusPacket.clientVersion2); bitStream.Write(loginStatusPacket.clientVersion3); // Write the userKey, redirectIp, and chatIp to bitStream //WriteStringToBitStream(loginStatusPacket.userKey.c_str(), 66, 66, &bitStream); PacketTools::WriteToPacket(&bitStream, loginStatusPacket.userKey, 33); WriteStringToBitStream(loginStatusPacket.redirectIp.c_str(), sizeof(loginStatusPacket.redirectIp), 33, &bitStream); WriteStringToBitStream(loginStatusPacket.chatIp.c_str(), sizeof(loginStatusPacket.chatIp), 33, &bitStream); // Write the redirectPort and the chatPort to bitStream bitStream.Write(loginStatusPacket.redirectPort); bitStream.Write(loginStatusPacket.chatPort); // Write seperate ip(?) and possibleGuid to bitStream WriteStringToBitStream(loginStatusPacket.anotherIp.c_str(), sizeof(loginStatusPacket.anotherIp), 33, &bitStream); WriteStringToBitStream(loginStatusPacket.possibleGuid.c_str(), 37, 37, &bitStream); // Write the zeroShort to the errorMsgLength to the bitStream bitStream.Write(loginStatusPacket.zeroLong); bitStream.Write(loginStatusPacket.localizationChar[0]); bitStream.Write(loginStatusPacket.localizationChar[1]); bitStream.Write(loginStatusPacket.localizationChar[2]); bitStream.Write(loginStatusPacket.firstLoginSubscription); bitStream.Write(loginStatusPacket.subscribed); bitStream.Write(loginStatusPacket.zeroLongLong); bitStream.Write(loginStatusPacket.errorMsgLength); // Write the error msg string to the bitStream WriteStringToBitStream(loginStatusPacket.errorMsg.c_str(), loginStatusPacket.errorMsgLength, 0, &bitStream); // Add extra bytes length bitStream.Write(loginStatusPacket.extraBytesLength); // Create extra packet data (even if not success, doesn't appear to // Do anything at the moment...) CreateExtraPacketDataSuccess(&bitStream); rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false); SavePacketOverwrite("test_login.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); }