mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
* Adapt codebase to new class to reduce rune-like code. * Fixed several bugs where the global CClient pointer was used instead of the instance in question to issue bans and display information about a certain client in CBanSystem and Pylon. * Upgraded CBanSystem and Pylon to use IPv6 instead (including IPv4 mapped IPv6 addresses). This breaks all existing banlist files! All bans have to be re-issued or the existing file has to be updated to use IPv4 mapped IPv6 addresses and renamed to 'banlist.json', and moved to the root of the 'platform' folder.
245 lines
8.0 KiB
C++
245 lines
8.0 KiB
C++
//=====================================================================================//
|
|
//
|
|
// Purpose: Implementation of the CBanSystem class.
|
|
//
|
|
// $NoKeywords: $
|
|
//=====================================================================================//
|
|
|
|
#include "core/stdafx.h"
|
|
#include "engine/net.h"
|
|
#include "engine/sys_utils.h"
|
|
#include "engine/baseclient.h"
|
|
#include "public/include/bansystem.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CBanSystem::CBanSystem(void)
|
|
{
|
|
Load();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::operator[](std::pair<std::string, std::int64_t> pair)
|
|
{
|
|
AddEntry(pair.first, pair.second);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: loads and parses the banlist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::Load(void)
|
|
{
|
|
std::filesystem::path path = std::filesystem::current_path() /= "platform\\banlist.json";
|
|
|
|
nlohmann::json jsIn;
|
|
std::ifstream banFile(path, std::ios::in);
|
|
|
|
int nTotalBans = 0;
|
|
|
|
if (banFile.good() && banFile) // Check if it parsed.
|
|
{
|
|
banFile >> jsIn; // Into json.
|
|
banFile.close();
|
|
|
|
if (!jsIn.is_null()) // Check if json is valid
|
|
{
|
|
if (!jsIn["totalBans"].is_null())
|
|
{
|
|
nTotalBans = jsIn["totalBans"].get<int>();
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < nTotalBans; i++)
|
|
{
|
|
nlohmann::json jsEntry = jsIn[std::to_string(i).c_str()]; // Get Entry for current ban.
|
|
if (jsEntry.is_null()) // Check if entry is valid.
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::int64_t nOriginID = jsEntry["originID"].get<std::int64_t>(); // Get originID field from entry.
|
|
std::string svIpAddress = jsEntry["ipAddress"].get<std::string>(); // Get ipAddress field from entry.
|
|
|
|
vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID));
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: saves the banlist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::Save(void) const
|
|
{
|
|
nlohmann::json jsOut;
|
|
|
|
for (int i = 0; i < vsvBanList.size(); i++)
|
|
{
|
|
jsOut["totalBans"] = vsvBanList.size(); // Populate totalBans field.
|
|
jsOut[std::to_string(i).c_str()]["ipAddress"] = vsvBanList[i].first; // Populate ipAddress field for this entry.
|
|
jsOut[std::to_string(i).c_str()]["originID"] = vsvBanList[i].second; // Populate originID field for this entry.
|
|
}
|
|
|
|
std::filesystem::path path = std::filesystem::current_path() /= "platform\\banlist.json";
|
|
std::ofstream outFile(path, std::ios::out | std::ios::trunc); // Write config file..
|
|
|
|
outFile << jsOut.dump(4); // Dump it into config file..
|
|
outFile.close(); // Close the file handle.
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: adds a banned player entry to the banlist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::AddEntry(std::string svIpAddress, std::int64_t nOriginID)
|
|
{
|
|
if (!svIpAddress.empty() && nOriginID > 0) // Check if args are valid.
|
|
{
|
|
auto it = std::find(vsvBanList.begin(), vsvBanList.end(), std::make_pair(svIpAddress, nOriginID)); // Check if we have this entry already.
|
|
if (it == vsvBanList.end()) // We don't have that entry?
|
|
{
|
|
vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID)); // Add it.
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: deletes an entry in the banlist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::DeleteEntry(std::string svIpAddress, std::int64_t nOriginID)
|
|
{
|
|
for (int i = 0; i < vsvBanList.size(); i++) // Loop through vector.
|
|
{
|
|
if (svIpAddress.compare(vsvBanList[i].first) == NULL || nOriginID == vsvBanList[i].second) // Do any entries match our vector?
|
|
{
|
|
vsvBanList.erase(vsvBanList.begin() + i); // If so erase that vector element.
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: adds a connect refuse entry to the refuselist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::AddConnectionRefuse(std::string svError, std::int64_t nOriginID)
|
|
{
|
|
if (vsvrefuseList.empty())
|
|
{
|
|
vsvrefuseList.push_back(std::make_pair(svError, nOriginID));
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector.
|
|
{
|
|
if (vsvrefuseList[i].second != nOriginID) // Do any entries match our vector?
|
|
{
|
|
vsvrefuseList.push_back(std::make_pair(svError, nOriginID)); // Push it back into the vector.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: deletes an entry in the refuselist
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::DeleteConnectionRefuse(std::int64_t nOriginID)
|
|
{
|
|
for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector.
|
|
{
|
|
if (vsvrefuseList[i].second == nOriginID) // Do any entries match our vector?
|
|
{
|
|
vsvrefuseList.erase(vsvrefuseList.begin() + i); // If so erase that vector element.
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: checks if specified ip address or necleus id is banned
|
|
// Input : svIpAddress -
|
|
// nOriginID -
|
|
// Output : true if banned, false if not banned
|
|
//-----------------------------------------------------------------------------
|
|
bool CBanSystem::IsBanned(std::string svIpAddress, std::int64_t nOriginID) const
|
|
{
|
|
for (int i = 0; i < vsvBanList.size(); i++)
|
|
{
|
|
std::string ipAddress = vsvBanList[i].first; // Get first pair entry.
|
|
std::int64_t originID = vsvBanList[i].second; // Get second pair entry.
|
|
|
|
if (ipAddress.empty()) // Check if ip is empty.
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (originID <= 0) // Is originID below 0?
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (ipAddress.compare(svIpAddress) == NULL) // Do they match?
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (nOriginID == originID) // Do they match?
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Check refuse list and kill netchan connection.
|
|
//-----------------------------------------------------------------------------
|
|
void CBanSystem::BanListCheck(void)
|
|
{
|
|
if (IsRefuseListValid())
|
|
{
|
|
for (int i = 0; i < vsvrefuseList.size(); i++)
|
|
{
|
|
for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances.
|
|
{
|
|
CBaseClient* pClient = g_pClient->GetClient(c);
|
|
CNetChan* pNetChan = pClient->GetNetChan();
|
|
|
|
if (!pClient || !pNetChan)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pClient->GetOriginID() != vsvrefuseList[i].second) // See if NucleusID matches entry.
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::string svIpAddress = pNetChan->GetAddress();
|
|
|
|
Warning(eDLL_T::SERVER, "Connection rejected for '%s' ('%lld' is banned from this Server!)\n", svIpAddress.c_str(), pClient->GetOriginID());
|
|
AddEntry(svIpAddress, pClient->GetOriginID()); // Add local entry to reserve a non needed request.
|
|
Save(); // Save banlist to file.
|
|
NET_DisconnectClient(pClient, c, vsvrefuseList[i].first.c_str(), 0, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: checks if refuselist is valid
|
|
//-----------------------------------------------------------------------------
|
|
bool CBanSystem::IsRefuseListValid(void) const
|
|
{
|
|
return !vsvrefuseList.empty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: checks if banlist is valid
|
|
//-----------------------------------------------------------------------------
|
|
bool CBanSystem::IsBanListValid(void) const
|
|
{
|
|
return !vsvBanList.empty();
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
CBanSystem* g_pBanSystem = new CBanSystem();
|