diff options
Diffstat (limited to 'NorthstarDLL/bansystem.cpp')
-rw-r--r-- | NorthstarDLL/bansystem.cpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/NorthstarDLL/bansystem.cpp b/NorthstarDLL/bansystem.cpp new file mode 100644 index 00000000..08115998 --- /dev/null +++ b/NorthstarDLL/bansystem.cpp @@ -0,0 +1,107 @@ +#pragma once +#include "pch.h" +#include "bansystem.h" +#include "serverauthentication.h" +#include "concommand.h" +#include "miscserverscript.h" +#include "configurables.h" + +#include <filesystem> + +const char* BANLIST_PATH_SUFFIX = "/banlist.txt"; + +ServerBanSystem* g_ServerBanSystem; + +void ServerBanSystem::OpenBanlist() +{ + std::ifstream enabledModsStream(GetNorthstarPrefix() + "/banlist.txt"); + std::stringstream enabledModsStringStream; + + if (!enabledModsStream.fail()) + { + std::string line; + while (std::getline(enabledModsStream, line)) + m_vBannedUids.push_back(strtoll(line.c_str(), nullptr, 10)); + + enabledModsStream.close(); + } + + // open write stream for banlist + m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::app); +} + +void ServerBanSystem::ClearBanlist() +{ + m_vBannedUids.clear(); + + // reopen the file, don't provide std::ofstream::app so it clears on open + m_sBanlistStream.close(); + m_sBanlistStream.open(GetNorthstarPrefix() + "/banlist.txt", std::ofstream::out | std::ofstream::binary); +} + +void ServerBanSystem::BanUID(uint64_t uid) +{ + m_vBannedUids.push_back(uid); + m_sBanlistStream << std::to_string(uid) << std::endl; + spdlog::info("{} was banned", uid); +} + +void ServerBanSystem::UnbanUID(uint64_t uid) +{ + auto findResult = std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid); + if (findResult == m_vBannedUids.end()) + return; + + m_vBannedUids.erase(findResult); + spdlog::info("{} was unbanned", uid); + // todo: this needs to erase from the banlist file + // atm unsure how to do this aside from just clearing and fully rewriting the file +} + +bool ServerBanSystem::IsUIDAllowed(uint64_t uid) +{ + return std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid) == m_vBannedUids.end(); +} + +void ConCommand_ban(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + // assuming maxplayers 32 + for (int i = 0; i < 32; i++) + { + void* player = GetPlayerByIndex(i); + + if (!strcmp((char*)player + 0x16, args.Arg(1)) || !strcmp((char*)player + 0xF500, args.Arg(1))) + { + g_ServerBanSystem->BanUID(strtoll((char*)player + 0xF500, nullptr, 10)); + CBaseClient__Disconnect(player, 1, "Banned from server"); + break; + } + } +} + +void ConCommand_unban(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + // assumedly the player being unbanned here wasn't already connected, so don't need to iterate over players or anything + g_ServerBanSystem->UnbanUID(strtoll(args.Arg(1), nullptr, 10)); +} + +void ConCommand_clearbanlist(const CCommand& args) +{ + g_ServerBanSystem->ClearBanlist(); +} + +ON_DLL_LOAD_RELIESON("engine.dll", BanSystem, ConCommand, [](HMODULE baseAddress) +{ + g_ServerBanSystem = new ServerBanSystem; + g_ServerBanSystem->OpenBanlist(); + + RegisterConCommand("ban", ConCommand_ban, "bans a given player by uid or name", FCVAR_GAMEDLL); + RegisterConCommand("unban", ConCommand_unban, "unbans a given player by uid", FCVAR_NONE); + RegisterConCommand("clearbanlist", ConCommand_clearbanlist, "clears all uids on the banlist", FCVAR_NONE); +})
\ No newline at end of file |