void CLocalPlayer::DoDeathCheck() { // Have we not yet processed the death and is the local player dead? if(!CLocalPlayer::m_bIsDead && IsDead()) { // Get the kill info EntityId playerId = INVALID_ENTITY_ID; EntityId vehicleId = INVALID_ENTITY_ID; EntityId weaponId = INVALID_ENTITY_ID; GetKillInfo(&playerId, &vehicleId,&weaponId); CLogFile::Printf("HandleDeath(LocalPlayer, %d, %d, %d)", playerId, vehicleId, weaponId); g_pCore->GetChat()->Outputf(false, "HandleDeath(LocalPlayer, %d, %d, %d)", playerId, vehicleId, weaponId); // Send the death notification to the server BitStream bsSend; bsSend.WriteCompressed(playerId); bsSend.WriteCompressed(vehicleId); bsSend.WriteCompressed(weaponId); g_pCore->GetNetworkManager()->Call(GET_RPC_CODEX(RPC_PLAYER_DEATH), &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, true); // Mark ourselves as dead CLocalPlayer::m_bIsDead = true; // Delete the object CIVScript::DeleteObject(&m_pObj); // Reset vehicle entry/exit flags SetExitFlag(true); ResetVehicleEnterExit(); // Get current day time so we don't have to set the time always.. CGameFunction::GetTime(&m_iRespawnTime[0], &m_iRespawnTime[1]); } }
void RelayPlugin::OnJoinGroupRequestFromClient(Packet *packet) { BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); RakString groupName; bsIn.ReadCompressed(groupName); RelayPlugin::RP_Group *groupJoined = JoinGroup(packet->guid, groupName); BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); if (groupJoined) { bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_SUCCESS); bsOut.WriteCasted<uint16_t>(groupJoined->usersInRoom.Size()); for (unsigned int i=0; i < groupJoined->usersInRoom.Size(); i++) { bsOut.WriteCompressed(groupJoined->usersInRoom[i].str); } } else { bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_FAILURE); } SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false); }
void RelayPlugin::SendMessageToRoom(StrAndGuidAndRoom **strAndGuidSender, BitStream* message) { if ((*strAndGuidSender)->currentRoom.IsEmpty()) return; for (unsigned int i=0; i < chatRooms.Size(); i++) { if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_GROUP_MSG_FROM_SERVER); message->ResetReadPointer(); bsOut.WriteCompressed((*strAndGuidSender)->str); bsOut.AlignWriteToByteBoundary(); bsOut.Write(message); RP_Group *room = chatRooms[i]; for (unsigned int i=0; i < room->usersInRoom.Size(); i++) { if (room->usersInRoom[i].guid!=(*strAndGuidSender)->guid) SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false); } break; } } }
void RelayPlugin::AddParticipantRequestFromClient(const RakString &key, const RakNetGUID &relayPluginServerGuid) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_REQUEST_FROM_CLIENT); bsOut.WriteCompressed(key); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false); }
void RelayPlugin::JoinGroupRequest(const RakNetGUID &relayPluginServerGuid, RakString groupName) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_REQUEST_FROM_CLIENT); bsOut.WriteCompressed(groupName); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false); }
// Send a message to a server running RelayPlugin, to forward a message to the system identified by \a key void RelayPlugin::SendToParticipant(const RakNetGUID &relayPluginServerGuid, const RakString &key, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_SERVER_FROM_CLIENT); bsOut.WriteCasted<unsigned char>(priority); bsOut.WriteCasted<unsigned char>(reliability); bsOut.Write(orderingChannel); bsOut.WriteCompressed(key); bsOut.Write(bitStream); SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false); }
void RelayPlugin::NotifyUsersInRoom(RP_Group *room, int msg, const RakString& message) { for (unsigned int i=0; i < room->usersInRoom.Size(); i++) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(msg); bsOut.WriteCompressed(message); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false); } }
void RelayPlugin::SendChatRoomsList(RakNetGUID target) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REPLY_FROM_SERVER); bsOut.WriteCasted<uint16_t>(chatRooms.Size()); for (unsigned int i=0; i < chatRooms.Size(); i++) { bsOut.WriteCompressed(chatRooms[i]->roomName); bsOut.WriteCasted<uint16_t>(chatRooms[i]->usersInRoom.Size()); } SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false); }
void AutoPatcher::OnAutopatcherRequestFiles( Packet *packet ) { assert( rakPeerInterface || rakClientInterface || rakServerInterface ); BitStream serializedFileDescriptor( ( char* ) packet->data, packet->length, false ); BitStream outputBitStream; DownloadableFileDescriptor dfd; unsigned int numberOfFilesRequested; unsigned index, downloadableFilesIndex; unsigned char packetID; // Holds a copy of the pointers. Don't deallocate them! BasicDataStructures::List<DownloadableFileDescriptor*> sendList; // Ignore ID_AUTOPATCHER_REQUEST_FILES serializedFileDescriptor.IgnoreBits( sizeof( unsigned char ) * 8 ); if ( serializedFileDescriptor.ReadCompressed( numberOfFilesRequested ) == false ) { // Invalid packet format. Should never get this unless it's a bug or someone is hacking #ifdef _DEBUG assert( 0 ); #endif return ; } // Go through all the files requested in the packet. // If we allow download of it, add the descriptor to a send list which we // serialize and send back to the sender telling them what files they will get. // This is necessary because it is possible that cheaters will request files // not in the list or that files will be removed from downloadable status after an initial // successful request for it for ( index = 0; index < numberOfFilesRequested; index++ ) { dfd.Clear(); if ( dfd.DeserializeHeader( &serializedFileDescriptor ) == false ) { assert( 0 ); // Error in packet header. Should only get this from hackers or bugs return ; } for ( downloadableFilesIndex = 0; downloadableFilesIndex < downloadableFiles.size(); downloadableFilesIndex++ ) { if ( strcmp( downloadableFiles[ downloadableFilesIndex ] ->filename, dfd.filename ) == 0 ) { // Record that we are going to send this file to system requesting it sendList.insert( downloadableFiles[ downloadableFilesIndex ] ); break; } } } packetID = ID_AUTOPATCHER_SET_DOWNLOAD_LIST; // Serialize the list of files we will send outputBitStream.Write( packetID ); outputBitStream.WriteCompressed( sendList.size() ); for ( index = 0; index < sendList.size(); index++ ) sendList[ index ] ->SerializeHeader( &outputBitStream ); // Send the list of files if ( rakServerInterface ) rakServerInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else if ( rakPeerInterface ) rakPeerInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else rakClientInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream ); // The next step is to send the actual files. We already know what files need to be sent - // The files specified by the descriptors in sendList. packetID = ID_AUTOPATCHER_WRITE_FILE; for ( index = 0; index < sendList.size(); index++ ) { // We used outputBitStream earlier so don't forget to reset it outputBitStream.Reset(); outputBitStream.Write( packetID ); sendList[ index ] ->SerializeHeader( &outputBitStream ); sendList[ index ] ->SerializeFileData( &outputBitStream ); if ( rakServerInterface ) rakServerInterface->Send( &outputBitStream, LOW_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else if ( rakPeerInterface ) rakPeerInterface->Send( &outputBitStream, LOW_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else rakClientInterface->Send( &outputBitStream, LOW_PRIORITY, RELIABLE_ORDERED, orderingStream ); } }
void AutoPatcher::OnAutopatcherFileList( Packet *packet, bool onlyAcceptFilesIfRequested ) { BitStream serializedFileDescriptor( ( char* ) packet->data, packet->length, false ); BitStream outputBitStream; DownloadableFileDescriptor *dfd; char *filePath; char SHA1Code[ SHA1_LENGTH ]; bool allocatedFilePath; unsigned int numberOfDownloadableFiles; unsigned index; unsigned char packetID; assert( rakPeerInterface || rakClientInterface || rakServerInterface ); assert( packet ); if ( onlyAcceptFilesIfRequested && downloadableFilesRequested == false ) return ; if ( packet == 0 ) return ; downloadableFilesRequested = false; // Ignore ID_AUTOPATCHER_FILE_LIST serializedFileDescriptor.IgnoreBits( sizeof( unsigned char ) * 8 ); if ( serializedFileDescriptor.ReadCompressed( numberOfDownloadableFiles ) == false ) { // Invalid packet format. Should never get this unless it's a bug or someone is hacking #ifdef _DEBUG assert( 0 ); #endif return ; } dfd = 0; for ( index = 0; index < numberOfDownloadableFiles; index++ ) { if ( dfd == 0 ) dfd = new DownloadableFileDescriptor; else dfd->Clear(); if ( dfd->DeserializeHeader( &serializedFileDescriptor ) == false ) { assert( 0 ); // Error in packet header. Should only get this from hackers or bugs delete dfd; for ( index = 0; index < downloadingFiles.size(); index++ ) delete downloadingFiles[ index ]; downloadingFiles.clear(); return ; } if ( dfd->DeserializeSHA1( &serializedFileDescriptor ) == false ) { assert( 0 ); // Error in packet header. Should only get this from hackers or bugs delete dfd; for ( index = 0; index < downloadingFiles.size(); index++ ) delete downloadingFiles[ index ]; downloadingFiles.clear(); return ; } // Check to see if we have the file specified in the file descriptor. // If we don't have it, or the SHA1 doesn't match, then request to download it if ( downloadPrefix ) { filePath = new char[ strlen( downloadPrefix ) + strlen( dfd->filename ) + 1 ]; strcpy( filePath, downloadPrefix ); strcat( filePath, dfd->filename ); allocatedFilePath = true; } else { filePath = dfd->filename; allocatedFilePath = false; } // Just a guess - if the server uses a different compressionBoundary // then it will be a wrong guess dfd->fileDataIsCompressed = dfd->fileLength >= compressionBoundary ? true : false; if ( GenerateSHA1( filePath, SHA1Code ) == false || memcmp( SHA1Code, dfd->SHA1Code, SHA1_LENGTH * sizeof( char ) ) != 0 ) { // Don't have the file, or SHA1 doesn't match. // Add dfd to the list of files to download downloadingFiles.insert( dfd ); dfd = 0; } if ( allocatedFilePath ) delete [] filePath; } if ( dfd ) delete dfd; // At this point downloadingFiles is probably what we will get back, in that order. // However, if the server rejects to send something then it will be changed by a later packet. if ( downloadingFiles.size() > 0 ) { packetID = ID_AUTOPATCHER_REQUEST_FILES; outputBitStream.Write( packetID ); outputBitStream.WriteCompressed( downloadingFiles.size() ); for ( index = 0; index < downloadingFiles.size(); index++ ) downloadingFiles[ index ] ->SerializeHeader( &outputBitStream ); if ( rakServerInterface ) rakServerInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else if ( rakPeerInterface ) rakPeerInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream, packet->playerId, false ); else rakClientInterface->Send( &outputBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, orderingStream ); } }
PluginReceiveResult RelayPlugin::OnReceive(Packet *packet) { if (packet->data[0]==ID_RELAY_PLUGIN) { switch (packet->data[1]) { case RPE_MESSAGE_TO_SERVER_FROM_CLIENT: { BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); PacketPriority priority; PacketReliability reliability; char orderingChannel; unsigned char cIn; bsIn.Read(cIn); priority = (PacketPriority) cIn; bsIn.Read(cIn); reliability = (PacketReliability) cIn; bsIn.Read(orderingChannel); RakString key; bsIn.ReadCompressed(key); BitStream bsData; bsIn.Read(&bsData); StrAndGuidAndRoom **strAndGuid = strToGuidHash.Peek(key); StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid); if (strAndGuid && strAndGuidSender) { BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_CLIENT_FROM_SERVER); bsOut.WriteCompressed( (*strAndGuidSender)->str ); bsOut.AlignWriteToByteBoundary(); bsOut.Write(bsData); SendUnified(&bsOut, priority, reliability, orderingChannel, (*strAndGuid)->guid, false); } return RR_STOP_PROCESSING_AND_DEALLOCATE; } case RPE_ADD_CLIENT_REQUEST_FROM_CLIENT: { BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); RakString key; bsIn.ReadCompressed(key); BitStream bsOut; bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN); if (acceptAddParticipantRequests) bsOut.WriteCasted<MessageID>(AddParticipantOnServer(key, packet->guid)); else bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_NOT_ALLOWED); bsOut.WriteCompressed(key); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); return RR_STOP_PROCESSING_AND_DEALLOCATE; } case RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT: { RemoveParticipantOnServer(packet->guid); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case RPE_GROUP_MESSAGE_FROM_CLIENT: { OnGroupMessageFromClient(packet); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case RPE_JOIN_GROUP_REQUEST_FROM_CLIENT: { OnJoinGroupRequestFromClient(packet); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT: { OnLeaveGroupRequestFromClient(packet); } return RR_STOP_PROCESSING_AND_DEALLOCATE; case RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT: { SendChatRoomsList(packet->guid); } return RR_STOP_PROCESSING_AND_DEALLOCATE; } } return RR_CONTINUE_PROCESSING; }
int main(void) { printf("Tests the RelayPlugin as a server.\n"); printf("Difficulty: Beginner\n\n"); char str[64], str2[64]; RakNet::RakPeerInterface *peer=RakNet::RakPeerInterface::GetInstance(); RelayPlugin *relayPlugin = RelayPlugin::GetInstance(); peer->AttachPlugin(relayPlugin); // Get our input char ip[64], serverPort[30], listenPort[30]; puts("Enter the port to listen on"); Gets(listenPort,sizeof(listenPort)); if (listenPort[0]==0) strcpy(listenPort, "1234"); relayPlugin->SetAcceptAddParticipantRequests(true); // Connecting the client is very simple. 0 means we don't care about // a connectionValidationInteger, and false for low priority threads RakNet::SocketDescriptor socketDescriptor(atoi(listenPort),0); socketDescriptor.socketFamily=AF_INET; peer->Startup(8,&socketDescriptor, 1); peer->SetMaximumIncomingConnections(8); peer->SetOccasionalPing(true); puts("Enter IP to connect to, or enter for none"); Gets(ip, sizeof(ip)); peer->AllowConnectionResponseIPMigration(false); if (ip[0]) { puts("Enter the port to connect to"); Gets(serverPort,sizeof(serverPort)); if (serverPort[0]==0) strcpy(serverPort, "1234"); RakNet::ConnectionAttemptResult car = peer->Connect(ip, atoi(serverPort), 0, 0); RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED); } peer->SetTimeoutTime(30000, UNASSIGNED_SYSTEM_ADDRESS); peer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString(str); printf("My GUID is %s\n", str); printf("(A)ddParticipantRequestFromClient\n"); printf("(R)emoveParticipantRequestFromClient\n"); printf("SendTo(P)articipant\n"); printf("(S)endGroupMessage\n"); printf("(J)oinGroupRequest\n"); printf("(L)eaveGroup\n"); printf("(G)etGroupList\n"); printf("(Q)uit\n"); char name[128]; while (1) { if (kbhit()) { char ch = getch(); if (ch=='a' || ch=='A') { printf("Enter name of participant: "); Gets(name, sizeof(name)); if (name[0]) { relayPlugin->AddParticipantRequestFromClient(name,peer->GetGUIDFromIndex(0)); printf("Done\n"); } else { printf("Operation aborted\n"); } } else if (ch=='r' || ch=='R') { relayPlugin->RemoveParticipantRequestFromClient(peer->GetGUIDFromIndex(0)); printf("Done\n"); } else if (ch=='p' || ch=='P') { char name[128]; printf("Enter name of participant: "); Gets(name, sizeof(name)); if (name[0]) { printf("Enter message to send: "); char msg[256]; Gets(msg, sizeof(msg)); RakString msgRs = msg; BitStream msgBs; msgBs.WriteCompressed(msgRs); relayPlugin->SendToParticipant(peer->GetGUIDFromIndex(0), name, &msgBs, HIGH_PRIORITY, RELIABLE_ORDERED, 0 ); printf("Done\n"); } else { printf("Operation aborted\n"); } } else if (ch=='s' || ch=='S') { printf("Enter message to send: "); char msg[256]; Gets(msg, sizeof(msg)); RakString msgRs = msg; BitStream msgBs; msgBs.Write(msgRs); relayPlugin->SendGroupMessage(peer->GetGUIDFromIndex(0), &msgBs, HIGH_PRIORITY, RELIABLE_ORDERED, 0 ); printf("Done\n"); } else if (ch=='j' || ch=='J') { printf("Enter group name to join: "); char msg[256]; Gets(msg, sizeof(msg)); relayPlugin->JoinGroupRequest(peer->GetGUIDFromIndex(0), msg); printf("Done\n"); } else if (ch=='l' || ch=='l') { relayPlugin->LeaveGroup(peer->GetGUIDFromIndex(0)); printf("Done\n"); } else if (ch=='g' || ch=='G') { relayPlugin->GetGroupList(peer->GetGUIDFromIndex(0)); printf("Done\n"); } else if (ch=='q') { break; } } Packet *packet; for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive()) { packet->guid.ToString(str); packet->systemAddress.ToString(true,str2); if (packet->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION from %s on %s\n", str, str2); } else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s on %s\n", str, str2); } else if (packet->data[0]==ID_CONNECTION_LOST) { printf("ID_CONNECTION_LOST from %s on %s\n", str, str2); } else if (packet->data[0]==ID_RELAY_PLUGIN) { BitStream msgRs; RakString senderRs; BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)); RelayPluginEnums rpe; bsIn.ReadCasted<MessageID>(rpe); switch (rpe) { case RPE_MESSAGE_TO_CLIENT_FROM_SERVER: { RakString senderName; bsIn.ReadCompressed(senderName); bsIn.AlignReadToByteBoundary(); RakString dataInAsStr; bsIn.ReadCompressed(dataInAsStr); printf("RPE_MESSAGE_TO_CLIENT_FROM_SERVER from %s, data=%s\n", senderName.C_String(), dataInAsStr.C_String()); } break; case RPE_ADD_CLIENT_NOT_ALLOWED: { RakString senderName; bsIn.ReadCompressed(senderName); printf("RPE_ADD_CLIENT_NOT_ALLOWED for %s\n", senderName.C_String()); } break; case RPE_ADD_CLIENT_TARGET_NOT_CONNECTED: { RakString senderName; bsIn.ReadCompressed(senderName); printf("RPE_ADD_CLIENT_TARGET_NOT_CONNECTED for %s\n", senderName.C_String()); } break; case RPE_ADD_CLIENT_NAME_ALREADY_IN_USE: { RakString senderName; bsIn.ReadCompressed(senderName); printf("RPE_ADD_CLIENT_NAME_ALREADY_IN_USE for %s\n", senderName.C_String()); } break; case RPE_ADD_CLIENT_SUCCESS: { RakString senderName; bsIn.ReadCompressed(senderName); printf("RPE_ADD_CLIENT_SUCCESS for %s\n", senderName.C_String()); } break; case RPE_USER_ENTERED_ROOM: { RakString whichUser; bsIn.ReadCompressed(whichUser); printf("RPE_USER_ENTERED_ROOM user=%s\n", whichUser.C_String()); } break; case RPE_USER_LEFT_ROOM: { RakString whichUser; bsIn.ReadCompressed(whichUser); printf("RPE_USER_LEFT_ROOM user=%s\n", whichUser.C_String()); } break; case RPE_GROUP_MSG_FROM_SERVER: { RakString senderName; bsIn.ReadCompressed(senderName); bsIn.AlignReadToByteBoundary(); RakString dataInAsStr; bsIn.Read(dataInAsStr); printf("RPE_GROUP_MSG_FROM_SERVER from %s, data=%s\n", senderName.C_String(), dataInAsStr.C_String()); } break; case RPE_GET_GROUP_LIST_REPLY_FROM_SERVER: { uint16_t chatRoomsSize, usersInRoomSize; bsIn.Read(chatRoomsSize); RakString roomName; printf("RPE_GET_GROUP_LIST_REPLY_FROM_SERVER %i rooms\n", chatRoomsSize); for (uint16_t chatRoomsIdx=0; chatRoomsIdx < chatRoomsSize; chatRoomsIdx++) { bsIn.ReadCompressed(roomName); bsIn.Read(usersInRoomSize); printf("%i. %s %i users\n", chatRoomsIdx+1, roomName.C_String(), usersInRoomSize); } } break; default: { RakAssert(0); } } } } RakSleep(30); } return 1; }
void MasterServer::HandleQuery(Packet *packet) { DataStructures::List<GameServer*> serversWithKeysList; char ruleIdentifier[256]; unsigned index, serverIndex; int key; bool queryAll; BitStream outputBitStream; BitStream compressedString(packet->data, packet->length, false); compressedString.IgnoreBits(8*sizeof(unsigned char)); queryAll=true; while (compressedString.GetNumberOfUnreadBits()>0) { // Generate a list of the indices of the servers that have one or more of the specified keys. stringCompressor->DecodeString(ruleIdentifier, 256, &compressedString); if (ruleIdentifier[0]==0) // If we fail to read the first string, queryAll remains true. break; queryAll=false; if (IsReservedRuleIdentifier(ruleIdentifier)) continue; for (index=0; index < gameServerList.serverList.Size(); index++) { if (gameServerList.serverList[index]->connectionIdentifier==UNASSIGNED_PLAYER_ID) continue; if (gameServerList.serverList[index]->FindKey(ruleIdentifier)) { serverIndex=serversWithKeysList.GetIndexOf(gameServerList.serverList[index]); if (serverIndex==MAX_UNSIGNED_LONG) { gameServerList.serverList[index]->numberOfKeysFound=1; serversWithKeysList.Insert(gameServerList.serverList[index]); } else { serversWithKeysList[serverIndex]->numberOfKeysFound++; } } } } // Write the packet id if (queryAll) outputBitStream.Write((unsigned char) ID_MASTER_SERVER_SET_SERVER); else outputBitStream.Write((unsigned char) ID_MASTER_SERVER_UPDATE_SERVER); if (queryAll) { // Write the number of servers outputBitStream.WriteCompressed((unsigned short)gameServerList.serverList.Size()); for (index=0; index < gameServerList.serverList.Size(); index++) { // Write the whole server SerializeServer(gameServerList.serverList[index], &outputBitStream); } } else { compressedString.ResetReadPointer(); compressedString.IgnoreBits(8*sizeof(unsigned char)); // Write the number of servers with requested keys outputBitStream.WriteCompressed((unsigned short)serversWithKeysList.Size()); // For each server, write the header which consists of the IP/PORT. // Then go through the list of requested keys and write those for (index=0; index < serversWithKeysList.Size(); index++) { SerializePlayerID(&(serversWithKeysList[index]->connectionIdentifier), &outputBitStream); outputBitStream.WriteCompressed((unsigned short)serversWithKeysList[index]->numberOfKeysFound); while (compressedString.GetNumberOfUnreadBits()>0) { // Generate a list of the indices of the servers that have one or more of the specified keys. stringCompressor->DecodeString(ruleIdentifier, 256, &compressedString); if (ruleIdentifier[0]==0) break; if (IsReservedRuleIdentifier(ruleIdentifier)) continue; serversWithKeysList[index]->FindKey(ruleIdentifier); key=serversWithKeysList[index]->keyIndex; if (key>=0) SerializeRule(serversWithKeysList[index]->serverRules[key], &outputBitStream); } } } rakPeer->Send(&outputBitStream, MEDIUM_PRIORITY, RELIABLE, 0, packet->playerId, false); }