#include "std_include.hpp" #include "kill_list.hpp" #include 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([&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([&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([&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(); }