master-server/src/services/kill_list.cpp
2024-03-22 16:13:30 +01:00

160 lines
3.6 KiB
C++

#include "std_include.hpp"
#include "kill_list.hpp"
#include <utils/io.hpp>
constexpr auto* kill_file = "./kill.txt";
kill_list::kill_list_entry::kill_list_entry(std::string ip_address, std::string reason)
: ip_address_(std::move(ip_address)), reason_(std::move(reason))
{
}
bool kill_list::contains(const network::address& address, std::string& reason)
{
auto str_address = address.to_string(false);
return this->entries_container_.access<bool>([&str_address, &reason](const kill_list_entries& entries)
{
if (const auto itr = entries.find(str_address); itr != entries.end())
{
reason = itr->second.reason_;
return true;
}
return false;
});
}
void kill_list::add_to_kill_list(const kill_list_entry& add)
{
const auto any_change = this->entries_container_.access<bool>([&add](kill_list_entries& entries)
{
const auto existing_entry = entries.find(add.ip_address_);
if (existing_entry == entries.end() || existing_entry->second.reason_ != add.reason_)
{
console::info("Added %s to kill list (reason: %s)", add.ip_address_.data(), add.reason_.data());
entries[add.ip_address_] = add;
return true;
}
return false;
});
if (!any_change)
{
console::info("%s already in kill list, doing nothing", add.ip_address_.data());
return;
}
this->write_to_disk();
}
void kill_list::remove_from_kill_list(const network::address& remove)
{
this->remove_from_kill_list(remove.to_string());
}
void kill_list::remove_from_kill_list(const std::string& remove)
{
const auto any_change = this->entries_container_.access<bool>([&remove](kill_list_entries& entries)
{
if (entries.erase(remove))
{
console::info("Removed %s from kill list", remove.data());
return true;
}
return false;
});
if (!any_change)
{
console::info("%s not in kill list, doing nothing", remove.data());
return;
}
this->write_to_disk();
}
void kill_list::reload_from_disk()
{
std::string contents;
if (!utils::io::read_file(kill_file, &contents))
{
console::info("Could not find %s, kill list will not be loaded.", kill_file);
return;
}
std::istringstream string_stream(contents);
std::string line;
this->entries_container_.access([&string_stream, &line](kill_list_entries& entries)
{
entries.clear();
while (std::getline(string_stream, line))
{
if (line[0] == '#')
{
// comments or ignored line
continue;
}
std::string ip;
std::string comment;
const auto index = line.find(' ');
if (index != std::string::npos)
{
ip = line.substr(0, index);
comment = line.substr(index + 1);
}
else
{
ip = line;
}
if (ip.empty())
{
continue;
}
// Double line breaks from windows' \r\n
if (ip[ip.size() - 1] == '\r')
{
ip.pop_back();
}
entries.emplace(ip, kill_list_entry(ip, comment));
}
console::info("Loaded %zu kill list entries from %s", entries.size(), kill_file);
});
}
void kill_list::write_to_disk()
{
std::ostringstream stream;
this->entries_container_.access([&stream](const kill_list_entries& entries)
{
for (const auto& [ip, entry] : entries)
{
stream << entry.ip_address_ << " " << entry.reason_ << "\n";
}
if (utils::io::write_file(kill_file, stream.str(), false))
{
console::info("Wrote %s to disk (%zu entries)", kill_file, entries.size());
}
else
{
console::error("Failed to write %s!", kill_file);
}
});
}
kill_list::kill_list(server& server) : service(server)
{
this->reload_from_disk();
}