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 StringCompressor::EncodeString( const char *input, int maxCharsToWrite, RakNet::BitStream *output, int languageID ) { HuffmanEncodingTree *huffmanEncodingTree; if (huffmanEncodingTrees.Has(languageID)==false) return; huffmanEncodingTree=huffmanEncodingTrees.Get(languageID); if ( input == 0 ) { output->WriteCompressed( (unsigned short) 0 ); return; } RakNet::BitStream encodedBitStream; unsigned short stringBitLength; int charsToWrite; if ( maxCharsToWrite<=0 || ( int ) strlen( input ) < maxCharsToWrite ) charsToWrite = ( int ) strlen( input ); else charsToWrite = maxCharsToWrite - 1; huffmanEncodingTree->EncodeArray( ( unsigned char* ) input, charsToWrite, &encodedBitStream ); stringBitLength = ( unsigned short ) encodedBitStream.GetNumberOfBitsUsed(); output->WriteCompressed( stringBitLength ); output->WriteBits( encodedBitStream.GetData(), stringBitLength ); }
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 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 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__ ); }
void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.port==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.port); char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.port,(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)); } }
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 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 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()); }
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()); }
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 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); }
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 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 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 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 WorldLoop(CONNECT_INFO* cfg, Ref< UsersPool > OnlineUsers, Ref< CharactersPool> OnlineCharacters, Ref< CrossThreadQueue< string > > OutputQueue) { // Initialize the RakPeerInterface used throughout the entire server rakServer = RakNetworkFactory::GetRakPeerInterface(); // Initialize the PacketFileLogger plugin (for the logs) PacketFileLogger* msgFileHandler = NULL; if (cfg->logFile) { msgFileHandler = new PacketFileLogger(); rakServer->AttachPlugin(msgFileHandler); } // Initialize security IF user has enabled it in config.ini InitSecurity(rakServer, cfg->useEncryption); // Initialize the SocketDescriptor SocketDescriptor socketDescriptor(cfg->listenPort, 0); // If the startup of the server is successful, print it to the console // Otherwise, quit the server (as the char server is REQUIRED for the // server to function properly) if (rakServer->Startup(8, 30, &socketDescriptor, 1)) { stringstream s; s << "world started! Listening on: " << cfg->listenPort << "\n"; OutputQueue->Insert(s.str()); } else exit(2); rakServer->SetNetworkIDManager(&networkIdManager); rakServer->AttachPlugin(&replicaManager); networkIdManager.SetIsNetworkIDAuthority(true); // Attach the ReplicaManager2 replicaManager.SetAutoSerializeInScope(true); replicaManager.SetAutoParticipateNewConnections(true); replicaManager.SetAutoConstructToNewParticipants(true); // Set max incoming connections to 8 rakServer->SetMaximumIncomingConnections(8); // If msgFileHandler is not NULL, save logs of char server if (msgFileHandler != NULL) msgFileHandler->StartLog(".\\logs\\world"); // Initialize the Packet class for the packets Packet* packet; // This will be used in the saving of packets below int i = 0; ZoneId zone = NIMBUS_ISLE; // This will be used in the saving of packets below... while (!LUNIterminate) { RakSleep(30); // This sleep keeps RakNet responsive packet = rakServer->Receive(); // Recieve the packets from the server if (packet == NULL) continue; // If packet is NULL, just continue without processing anything // This will save all packets recieved from the client if running from DEBUG #ifdef DEBUG stringstream packetName; packetName << ".//Saves//World_Packet" << i << ".bin"; if (packet->data[3] != 22) { SavePacket(packetName.str(), (char*)packet->data, packet->length); i++; } #endif // Create and send packets back here according to the one we got switch (packet->data[0]) { case ID_USER_PACKET_ENUM: switch (packet->data[1]) { case GENERAL: if (packet->data[3] == 0) { // thats just a formality so far since no other numbers occured for this case auto v = OpenPacket(".\\worldTest\\init_aw2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } break; case WORLD: switch (packet->data[3]) { case CLIENT_VALIDATION: { auto usr = OnlineUsers->Find(packet->systemAddress); //this packets contains ZoneId and something else... but what? // it starts whit: 53 05 00 02 00 00 00 00 -- -- (<-ZoneId) ?? ?? ?? vector< uchar > v; /*if (usr != NULL && usr->nextcid == 2444680020) { //monkeybrown v = OpenPacket(".\\world\\monkeybrown\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1534792735) { //gruntmonkey v = OpenPacket(".\\world\\gruntmonkey\\char_aw2.bin"); } else if (usr != NULL && usr->nextcid == 1457240027) { //shafantastic v = OpenPacket(".\\world\\shastafantastic\\char_aw22.bin"); } else { //cheekymonkey v = OpenPacket(".\\world\\char_aw2.bin"); }*/ if (zone == NIMBUS_ISLE) v = OpenPacket(".\\world\\char_aw2.bin"); else if (zone == NIMBUS_STATION) { v = OpenPacket(".\\worldTest\\NS\\char_aw2.bin"); } else if (zone == LEGO_CLUB) { v = OpenPacket(".\\worldTest\\LC\\char_aw2.bin"); } //ReadCompressedLDFData(); #ifdef DEBUG if (v.size() > 0) { RakNet::BitStream bs(CleanPacket(v.data(), v.size()), v.size() - 8, false); ZoneId zid; bs.Read(zid); stringstream s; s << "\nLoading world: " << zid << endl; OutputQueue->Insert(s.str()); } else OutputQueue->Insert("\nWorld Error: can't load char_aw2.bin\n"); #endif ServerSendPacket(rakServer, v, packet->systemAddress); if (zone == NIMBUS_ISLE) { //auto character = Character::InitializeCharacter(12241); //character->WriteInitPacket(rakServer, packet->systemAddress); v = OpenPacket(".\\worldTest\\game_msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\game_msg2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } else if (zone == NIMBUS_STATION) { v = OpenPacket(".\\worldTest\\NS\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } else if (zone == LEGO_CLUB) { v = OpenPacket(".\\worldTest\\LC\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\LC\\msg2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } } break; case CLIENT_GAME_MSG: { #ifdef DEBUG vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); ulong cid = *(ulong*)t.data(); cout << "Character wants to do something using packet: " << RawDataToString(packet->data, packet->length) << endl; //cout << "\nCharacter id is doing something?: " << cid; #endif if (packet->length >= 18) { ushort gameMsg; memcpy(&gameMsg, (uchar*)packet->data + 0x10, 2); cout << "Game Message ID is: " << gameMsg << endl; auto user = OnlineUsers->Find(packet->systemAddress); HandleGameMessage(rakServer, packet->systemAddress, gameMsg, (uchar*)packet->data, packet->length, user); break; } } case CLIENT_GENERAL_CHAT_MESSAGE: { auto usr = OnlineUsers->Find(packet->systemAddress); vector<uchar> chatMsg; /*for (uchar i = 0; i <= packet->length; i++) { chatMsg.push_back(packet->data[0x0f + i++]); if (packet->data[0x0f + i + 1] == 0) { i++; break; } } chatMsg.push_back(0); string msg(chatMsg.begin(), chatMsg.end());*/ for (uchar i = 15; i < packet->length; i++) { chatMsg.push_back(packet->data[i]); } string wMsg(chatMsg.begin(), chatMsg.end()); cout << "User entered: " << wMsg.c_str() << endl; RakNet::BitStream bitStream; CreatePacketHeader(ID_USER_PACKET_ENUM, 2, 1, &bitStream); ulonglong l1 = 0; uchar l2 = 0; ushort l3 = 0; ulonglong senderID = 63515; bitStream.Write(l1); bitStream.Write(l2); bitStream.Write((uchar)(wMsg.length() * 2 + 2)); bitStream.Write(l2); bitStream.Write(l3); string x1 = ""; wstring emptyUser = StringToWString(x1, 66); bitStream.Write((char*)emptyUser.data(), sizeof(wchar_t)* emptyUser.size() / 2); bitStream.Write(senderID); bitStream.Write(l3); bitStream.Write((uchar)1); bitStream.Write((char*)wMsg.data(), sizeof(char)* wMsg.length()); rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); SavePacket("msg_response.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); /*RakNet::BitStream bitStream2; CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 12, &bitStream2); ushort u2 = 858; ulong u3 = 0; ushort u4 = 0; bitStream2.Write(u1); bitStream2.Write(u2); bitStream2.Write(u3); bitStream2.Write(u4); bitStream2.Write(wMsg.length()); bitStream2.Write(wMsg); rakServer->Send(&bitStream2, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); SavePacket("hi_msg.bin", (char*)bitStream2.GetData(), bitStream2.GetNumberOfBytesUsed());*/ } break; case CLIENT_LEVEL_LOAD_COMPLETE: { // Response: 05, 04 // The answer to this is compressed data detailing character data // also since the answer seems to consist of a split packet, does RakNet automatically split the packets if the data is too big? or do we have to do something, if yes what? // byte 08 (2 or 4 bytes long? I guess 4...) seems to define the size of the data we send, no idea what the data itself is though... auto usr = OnlineUsers->Find(packet->systemAddress); // If the user is not equal to null and next character id = below number, // Open the packets of monkeybrown and load him into a world /*if (usr != NULL && usr->nextcid == 2444680020) { cout << "\n Replying to monkeybrown\n"; auto v = OpenPacket(".\\world\\monkeybrown\\rocket_1a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1b.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\rocket_1c.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\world\\monkeybrown\\world_2a.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\monkeybrown\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 0; i < 42; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } v = OpenPacket(".\\world\\monkeybrown\\test\\world_2_1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 42; i < 210; i++) { // herpaderp stringstream fl; fl << ".\\world\\monkeybrown\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } else { // Otherwise, reply to Cheekymonkey and open his packets*/ cout << "\n Replying to Character\n"; //auto v = OpenPacket("LEGO Software.bin"); cout << "Attempting to create new char..." << endl; //if (character == 0) { //cout << "Creating new char..." << endl; //character = new Character(63450); //replicaManager.Construct(character, false, UNASSIGNED_SYSTEM_ADDRESS, true); //replicaManager.SignalSerializeNeeded(character, UNASSIGNED_SYSTEM_ADDRESS, true); //} auto v = OpenPacket(".\\world\\world_2a.bin"); if (v.size() <= 0) { cout << "World 2A contains no data!!!!" << endl; } ServerSendPacket(rakServer, v, packet->systemAddress); // test, is this the right thing to do? there's no difference in the process when they are (not) sent so far v = OpenPacket(".\\world\\world_2b.bin"); // I assume these two are sent together? ServerSendPacket(rakServer, v, packet->systemAddress); auto currentChar = OnlineCharacters->Find(packet->systemAddress); replicaManager.Construct(currentChar.Get(), false, UNASSIGNED_SYSTEM_ADDRESS, true); //replicaManager.Construct(character, false, UNASSIGNED_SYSTEM_ADDRESS, true); if (zone == NIMBUS_ISLE) { for (int i = 1; i < 5; i++) { // herpaderp stringstream fl; fl << ".\\world\\test\\world_2_" << (i + 1) << ".bin"; auto v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } //auto character = Character::InitializeCharacter(12241); //character->WriteInitPacket(rakServer, packet->systemAddress); } else if (zone == NIMBUS_STATION) { auto v = OpenPacket(".\\worldTest\\NS\\msg1.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 1; i < 10; i++) { stringstream fl; fl << ".\\worldTest\\NS\\replica\\ns_replica" << i << ".bin"; v = OpenPacket(fl.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 1; j < 10; j++) { stringstream fl2; fl2 << ".\\worldTest\\NS\\messages\\ns_message" << j << endl; v = OpenPacket(fl2.str()); ServerSendPacket(rakServer, v, packet->systemAddress); } } else if (zone == LEGO_CLUB) { cout << "Loading LEGO CLUB" << endl; for (int i = 47; i < 300; i) { stringstream packetName; packetName << ".\\..\\..\\..\\..\\Downloaded Packets\\GruntMonkey\\Lego Club - 42\\output_data\\" << i << "s.bin"; auto v = OpenPacket(packetName.str()); if (v.size() > 0) { ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 0; j < 20; j) { stringstream packetName2; packetName2 << ".\\..\\..\\..\\..\\Downloaded Packets\\GruntMonkey\\Lego Club - 42\\output_data\\" << i << "s_" << j << ".bin"; v = OpenPacket(packetName2.str()); if (v.size() > 0) { ServerSendPacket(rakServer, v, packet->systemAddress); } j++; } i++; } cout << "DONE Loading LEGO CLUB" << endl; } //} /*cout << "Loading Venture Explorer for character..." << endl; auto v = OpenPacket(".\\worldTest\\char\\char_load.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); v = OpenPacket(".\\worldTest\\char\\server_status.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); for (int i = 1; i <= 50; i++) { stringstream fileName; fileName << ".\\worldTest\\replica\\replica" << i << ".bin"; v = OpenPacket(fileName.str()); ServerSendPacket(rakServer, v, packet->systemAddress); }*/ /*for (int i = 35; i <= 789; i++) { stringstream fileName; fileName << ".\\worldTest\\replicaTest\\" << i << "s.bin"; auto v = OpenPacket(fileName.str()); if (v.data() > 0) { cout << "Sending file: " << fileName.str() << endl; ServerSendPacket(rakServer, v, packet->systemAddress); } for (int j = 2; j < 12; j++) { stringstream fileNameStr; fileNameStr << ".\\worldTest\\replicaTest\\" << i << "s_" << j << ".bin"; v = OpenPacket(fileNameStr.str()); if (v.data() > 0) { cout << "Sending file: " << fileNameStr.str() << endl; ServerSendPacket(rakServer, v, packet->systemAddress); } } }*/ } break; case CLIENT_MAIL: { auto usr = OnlineUsers->Find(packet->systemAddress); uint mailID; memcpy(&mailID, packet->data + 0x08, 4); if (mailID == 3) { FetchMailData(rakServer, packet->systemAddress, usr); } } break; case CLIENT_ROUTE_PACKET: { uchar remoteConnection; uchar packetID; memcpy(&remoteConnection, packet->data + 0x0C, 1); memcpy(&packetID, packet->data + 0x0E, 1); /*if (remoteConnection == 2 && packetID == 10) { auto character = OnlineUsers->FindChar(packet->systemAddress); character->CreateFriendsList(rakServer, packet->systemAddress, character->charObjectID); }*/ } break; case CLIENT_STRING_CHECK: { uchar requestID = packet->data[9]; cout << "Getting char moderation request with id: " << requestID << endl; RakNet::BitStream bitStream; CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 59, &bitStream); bitStream.Write((uchar)1); bitStream.Write((ushort)0); bitStream.Write(requestID); rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); } break; case 22: //user moving / update request? { auto usr = OnlineUsers->Find(packet->systemAddress); #ifdef DEBUG //OutputQueue->Insert("Received packet 22: " + RawDataToString(packet->data, packet->length) + "\n"); #endif } break; /*case LUNI_WORLD_CHAT: //user wrote a chat message { if (packet->length >= 10 && RawDataToString(packet->data + packet->length - 10, 10, true) == "730064006f0077006e00") {//virus used to be here } // dummy try vector< uchar > v(packet->length); for (uint i = 0; i < packet->length; i++) v.push_back(packet->data[i]); ServerSendPacket(rakServer, v, packet->systemAddress); }*/ break; /*case 5: { #ifdef DEBUG vector< uchar > t; for (int i = 8; i <= 11; i++) t.push_back(packet->data[i]); ulong cid = *(ulong*)t.data(); cout << "Character wants to do something using packet: " << RawDataToString(packet->data, packet->length) << endl; //cout << "\nCharacter id is doing something?: " << cid; #endif if (packet->data[0x1A] == 123 && packet->data[0x1B] == 33 & packet->data[0x1C] == 22) { cout << "Sending char to new world..." << endl; zone = NIMBUS_STATION; auto v = OpenPacket(".\\worldTest\\init_aw2.bin"); ServerSendPacket(rakServer, v, packet->systemAddress); } } break;*/ default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } break; case ID_NEW_INCOMING_CONNECTION: { #ifdef DEBUG OutputQueue->Insert("\n World is receiving a new connection...\n"); #endif //replicaManager.AddNewConnection(packet->systemAddress); /*Player *newPlayer = new Player; newPlayer->SetReplicaManager(&replicaManager); newPlayer->systemAddress = packet->systemAddress; newPlayer->LOT = 1; newPlayer->AddAutoSerializeTimer(100); newPlayer->BroadcastConstruction();*/ } break; case ID_DISCONNECTION_NOTIFICATION: { auto usr = OnlineUsers->Find(packet->systemAddress); if (OnlineUsers->Remove(packet->systemAddress)) OutputQueue->Insert("Disconnected " + usr->GetUsername() + "\n"); } //Player::DeletePlayerByAddress(packet->systemAddress); delete character; break; default: stringstream s; s << "\nworld received unknow pakcet: " << RawDataToString(packet->data, packet->length) << endl; OutputQueue->Insert(s.str()); } rakServer->DeallocatePacket(packet); } stringstream s; s << "Quitting world\n"; OutputQueue->Insert(s.str()); rakServer->Shutdown(0); RakNetworkFactory::DestroyRakPeerInterface(rakServer); }
void SendCharPacket(RakPeerInterface *rakServer, SystemAddress& systemAddress, Ref<User> usr) { RakNet::BitStream bitStream; CreatePacketHeader(ID_USER_PACKET_ENUM, 5, 6, &bitStream); if (usr == NULL) { cout << "Usr is null!!! ERROR!" << endl; } uchar charactersLength = (uchar)usr->userChars; uchar frontChar = (uchar)usr->userFrontChar; bitStream.Write(charactersLength); bitStream.Write(frontChar); ostringstream userId; userId << usr->GetID(); cout << userId.str() << endl; string userIdStr = userId.str(); // This loop perhaps is very inefficient, but it makes sure // 4 chars are loaded (or, if they don't exist, fill with 0x00) for (uint i = 0; i <= charactersLength; i++) { CharactersPacket charData = CharactersPacket(); ostringstream loopSS; loopSS << i; string loopStr = loopSS.str(); //loopSS.str(); // Connect to the database and retrieve character info auto qr = Database::Query("SELECT * FROM `characters` WHERE `id` = '" + loopStr + "' AND `accountID` = '" + userIdStr + "';"); // If the number of rows equals 0 from database (character doesn't exist), print it if (mysql_num_rows(qr) == 0) { cout << "Char " << loopStr << " doesn't exist yet."; } else { // Otherwise, fetch the data in the row auto ftc = mysql_fetch_row(qr); charData.objectID = (ulonglong)atoi(ftc[2]); // This is the character ID... ftc[1] is the user id charData.unknown1 = 0; // Dunno what this is... string sCharName = (string)ftc[3]; // This is the character name string sUnapprovedName = (string)ftc[4]; // This is the pre-defined (unapproved) name /*wstringstream swCharName; // Create a wstringstream for the char name swCharName << sCharName.c_str(); // Add the char name to it wstringstream swUnapprovedName; // Create a wstringstream for the unapproved name swUnapprovedName << sUnapprovedName.c_str(); // Add the unapproved name to it wstring wCharName = swCharName.str(); // Create a wstring from the wstringstream wstring wUnapprovedName = swUnapprovedName.str(); // Create a wstring from the wstringstream wCharName.resize(66); wUnapprovedName.resize(66);*/ wstring wCharName = StringToWString(sCharName, 66); wstring wUnapprovedName = StringToWString(sUnapprovedName, 66); charData.charName = wCharName; // This is the name of the character charData.unapprovedName = wUnapprovedName; // This is the unapproved name of the character charData.nameRejected = (uchar)atoi(ftc[5]); // This determines whether the user's name is approved charData.freeToPlay = (uchar)atoi(ftc[6]); // This determines whether the user if Free to Play charData.unknown2 = ""; charData.shirtColor = (ulong)atoi(ftc[7]); // The shirt color charData.shirtStyle = (ulong)atoi(ftc[8]); // Possibly the shirt style... ? charData.pantsColor = (ulong)atoi(ftc[9]); // The pants color charData.hairStyle = (ulong)atoi(ftc[10]); // Hair style charData.hairColor = (ulong)atoi(ftc[11]); // Hair color charData.lh = 0; (ulong)atoi(ftc[12]); // This is the left hand item? charData.rh = 0; (ulong)atoi(ftc[13]); // This is the right hand item? charData.eyebrows = (ulong)atoi(ftc[14]); // Eyebrows charData.eyes = (ulong)atoi(ftc[15]); // Eyes charData.mouth = (ulong)atoi(ftc[16]); // Mouth charData.unknown4 = 0; // Dunno what this is... charData.lastZoneId = (ulong)atoi(ftc[25]); // The last world ID the user was in... charData.mapInstance = (ushort)atoi(ftc[26]); // The map instance charData.mapClone = (ulong)atoi(ftc[27]); // The map clone charData.lastLogout = 0; // Last logout in seconds (useless until we get world server working) //charData.equippedItemsLength = CharSpecialItemsCount(charData.objectID); // The items length charData.WriteDataToBitstream(&bitStream, i); GetCharSpecialItems(charData.objectID, &bitStream); } } rakServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false); SavePacket("char_creation.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); }
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 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; const 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); DataStructures::Queue<FileToPush*> filesToPush; for (i=0; i < fileList->fileList.Size(); i++) { sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(__FILE__,__LINE__); fileToPush->fileListNode.context=fileList->fileList[i].context; fileToPush->setIndex=i; fileToPush->fileListNode.filename=fileList->fileList[i].filename; fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile; fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes; fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes; // fileToPush->systemAddress=recipient; fileToPush->setID=setID; fileToPush->packetPriority=priority; fileToPush->orderingChannel=orderingChannel; fileToPush->currentOffset=0; fileToPush->incrementalReadInterface=_incrementalReadInterface; fileToPush->chunkSize=_chunkSize; filesToPush.Push(fileToPush,__FILE__,__LINE__); } else { outBitstream.Reset(); 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; SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } if (filesToPush.IsEmpty()==false) { FileToPushRecipient *ftpr=0; filesToPushAllSameAddressMutex.Lock(); for (unsigned int i=0; i < filesToPushAllSameAddress.Size(); i++) { if (filesToPushAllSameAddress[i]->systemAddress==recipient) { ftpr=filesToPushAllSameAddress[i]; break; } } if (ftpr==0) { ftpr = RakNet::OP_NEW<FileToPushRecipient>(__FILE__,__LINE__); ftpr->systemAddress=recipient; filesToPushAllSameAddress.Push(ftpr, __FILE__,__LINE__); } while (filesToPush.IsEmpty()==false) { ftpr->filesToPush.Push(filesToPush.Pop(), __FILE__,__LINE__); } filesToPushAllSameAddressMutex.Unlock(); SendIRIToAddress(recipient); return; } } else { if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
void FileListTransfer::SendIRIToAddress(SystemAddress systemAddress) { // Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this unsigned int bytesRead; const char *dataBlocks[2]; int lengths[2]; unsigned int smallFileTotalSize=0; RakNet::BitStream outBitstream; filesToPushAllSameAddressMutex.Lock(); for (unsigned int ftpIndex=0; ftpIndex < filesToPushAllSameAddress.Size(); ftpIndex++) { FileToPushRecipient *ftpr = filesToPushAllSameAddress[ftpIndex]; if (ftpr->systemAddress==systemAddress) { FileToPush *ftp = ftpr->filesToPush.Peek(); // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(ftp->chunkSize, __FILE__, __LINE__); if (buff==0) { filesToPushAllSameAddressMutex.Unlock(); notifyOutOfMemory(__FILE__, __LINE__); return; } bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); bool done = bytesRead!=ftp->chunkSize; while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize) { // Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(ftp->fileListNode.context); outBitstream.Write(ftp->setID); stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(const char*) buff; lengths[1]=bytesRead; SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); RakNet::OP_DELETE(ftp,__FILE__,__LINE__); ftpr->filesToPush.Pop(); smallFileTotalSize+=bytesRead; done = bytesRead!=ftp->chunkSize; ftp = ftpr->filesToPush.Peek(); bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); } outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH); outBitstream.Write(ftp->fileListNode.context); outBitstream.Write(ftp->setID); stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.WriteCompressed(ftp->currentOffset); ftp->currentOffset+=bytesRead; outBitstream.WriteCompressed(bytesRead); outBitstream.Write(done); if (callback) { callback->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress); } dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(char*) buff; lengths[1]=bytesRead; //rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false); SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); if (done) { // Done RakNet::OP_DELETE(ftp,__FILE__,__LINE__); ftpr->filesToPush.Pop(); if (ftpr->filesToPush.Size()==0) { RakNet::OP_DELETE(ftpr,__FILE__,__LINE__); filesToPushAllSameAddress.RemoveAtIndexFast(ftpIndex); } } rakFree_Ex(buff, __FILE__, __LINE__ ); break; } } filesToPushAllSameAddressMutex.Unlock(); }
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 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); } }
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; }
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()); }