[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()
{
Events::OnSVInit(AddCommands);
@ -213,61 +270,11 @@ namespace Components
RateLimitCleanup(time);
std::string data_ = data;
Utils::String::Trim(data_);
const auto pos = data.find_first_of(' ');
if (pos == std::string::npos)
auto rconData = data;
Scheduler::Once([address, s = std::move(rconData)]
{
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();
RconExecuter(address, s);
}, Scheduler::Pipeline::MAIN);
});
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 RateLimitCheck(const Network::Address& address, int time);
static void RateLimitCleanup(int time);
static void RconExecuter(const Network::Address& address, std::string data);
};
}