[RCon]: Properly fix rare crash (#861)

This commit is contained in:
Edo 2023-03-21 18:14:11 +00:00 committed by GitHub
parent 61173b3d9b
commit ed9fc9aa7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 54 deletions

View File

@ -143,6 +143,63 @@ namespace Components
} }
} }
void RCon::RconExecuter(const Network::Address& address, std::string data)
{
Utils::String::Trim(data);
const auto pos = data.find_first_of(' ');
if (pos == std::string::npos)
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon request from {}\n", address.getString());
return;
}
auto password = data.substr(0, pos);
auto command = data.substr(pos + 1);
// B3 sends the password inside quotes :S
if (!password.empty() && password[0] == '"' && password.back() == '"')
{
password.pop_back();
password.erase(password.begin());
}
const auto svPassword = RconPassword.get<std::string>();
if (svPassword.empty())
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "RCon request from {} dropped. No password set!\n", address.getString());
return;
}
if (svPassword != password)
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon password sent from {}\n", address.getString());
return;
}
static std::string outputBuffer;
outputBuffer.clear();
#ifndef _DEBUG
if (RconLogRequests.get<bool>())
#endif
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "Executing RCon request from {}: {}\n", address.getString(), command);
}
Logger::PipeOutput([](const std::string& output)
{
outputBuffer.append(output);
});
Command::Execute(command, true);
Logger::PipeOutput(nullptr);
Network::SendCommand(address, "print", outputBuffer);
outputBuffer.clear();
}
RCon::RCon() RCon::RCon()
{ {
Events::OnSVInit(AddCommands); Events::OnSVInit(AddCommands);
@ -213,61 +270,11 @@ namespace Components
RateLimitCleanup(time); RateLimitCleanup(time);
std::string data_ = data; auto rconData = data;
Utils::String::Trim(data_); Scheduler::Once([address, s = std::move(rconData)]
const auto pos = data.find_first_of(' ');
if (pos == std::string::npos)
{ {
Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon request from {}\n", address.getString()); RconExecuter(address, s);
return; }, Scheduler::Pipeline::MAIN);
}
auto password = data.substr(0, pos);
auto command = data.substr(pos + 1);
// B3 sends the password inside quotes :S
if (!password.empty() && password[0] == '"' && password.back() == '"')
{
password.pop_back();
password.erase(password.begin());
}
const auto svPassword = RconPassword.get<std::string>();
if (svPassword.empty())
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "RCon request from {} dropped. No password set!\n", address.getString());
return;
}
if (svPassword != password)
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "Invalid RCon password sent from {}\n", address.getString());
return;
}
static std::string outputBuffer;
outputBuffer.clear();
#ifndef DEBUG
if (RconLogRequests.get<bool>())
#endif
{
Logger::Print(Game::CON_CHANNEL_NETWORK, "Executing RCon request from {}: {}\n", address.getString(), command);
}
Logger::PipeOutput([](const std::string& output)
{
outputBuffer.append(output);
});
Command::Execute(command, true);
Logger::PipeOutput(nullptr);
Network::SendCommand(address, "print", outputBuffer);
outputBuffer.clear();
}); });
Network::OnClientPacket("rconRequest", [](const Network::Address& address, [[maybe_unused]] const std::string& data) Network::OnClientPacket("rconRequest", [](const Network::Address& address, [[maybe_unused]] const std::string& data)

View File

@ -47,5 +47,7 @@ namespace Components
static bool IsRateLimitCheckDisabled(); static bool IsRateLimitCheckDisabled();
static bool RateLimitCheck(const Network::Address& address, int time); static bool RateLimitCheck(const Network::Address& address, int time);
static void RateLimitCleanup(int time); static void RateLimitCleanup(int time);
static void RconExecuter(const Network::Address& address, std::string data);
}; };
} }