| 82 | } |
| 83 | |
| 84 | bool ServerQueryThread::processPacket(HostAddressWithPort const& address, char const* data, size_t length) { |
| 85 | uint8_t* buf = (uint8_t*)data; |
| 86 | if (length < 5 || buf[0] != 0xff || buf[1] != 0xff || buf[2] != 0xff || buf[3] != 0xff) { |
| 87 | // short packet or missing header |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | // Process packet |
| 92 | switch (buf[4]) { |
| 93 | case A2S_INFO_REQUEST: { |
| 94 | // We use -6 and not -5 as the string should be NULL terminated |
| 95 | // but instead of the std::string constructor stopping at the NULL |
| 96 | // it includes it :( |
| 97 | std::string str((const char*)(buf + 5), length - 6); |
| 98 | if (str.compare(A2S_INFO_REQUEST_STRING) != 0) { |
| 99 | // Invalid request |
| 100 | return false; |
| 101 | } |
| 102 | |
| 103 | m_generalResponse.clear(); |
| 104 | m_generalResponse << A2S_HEAD_INT << A2S_INFO_REPLY << A2S_VERSION << m_serverName << serverWorldNames() |
| 105 | << GAME_DIR << GAME_DESC << A2S_APPID // Should be SteamAppId but this isn't a short :( |
| 106 | << serverPlayerCount() << m_maxPlayers << (uint8_t)0x00 // bots |
| 107 | << A2S_TYPE_DEDICATED // dedicated |
| 108 | #ifdef STAR_SYSTEM_FAMILY_WINDOWS |
| 109 | << A2S_ENV_WINDOWS // os |
| 110 | #elif defined(STAR_SYSTEM_MACOS) |
| 111 | << A2S_ENV_MAC // os |
| 112 | #else |
| 113 | << A2S_ENV_LINUX // os |
| 114 | #endif |
| 115 | << serverPassworded() << A2S_VAC_OFF // secure |
| 116 | << StarVersionString << A2S_EDF_PORT // EDF |
| 117 | << m_serverPort; |
| 118 | |
| 119 | sendTo(address, &m_generalResponse); |
| 120 | return true; |
| 121 | } |
| 122 | case A2S_CHALLENGE_REQUEST: |
| 123 | sendChallenge(address); |
| 124 | return true; |
| 125 | |
| 126 | case A2S_PLAYER_REQUEST: |
| 127 | if (challengeRequest(address, data, length)) |
| 128 | return true; |
| 129 | |
| 130 | if (!validChallenge(address, data, length)) |
| 131 | return false; |
| 132 | |
| 133 | buildPlayerResponse(); |
| 134 | sendTo(address, &m_playersResponse); |
| 135 | return true; |
| 136 | |
| 137 | case A2S_RULES_REQUEST: |
| 138 | if (challengeRequest(address, data, length)) |
| 139 | return true; |
| 140 | |
| 141 | if (!validChallenge(address, data, length)) |