Add an Artistic Style configuration file for Odamex.

- As a test, format the new banlist source files with the configuration.

SVN r3367 (trunk)
This commit is contained in:
Alex Mayfield 2012-09-25 00:52:28 +00:00
parent 1196398c25
commit 570bd1061f
3 changed files with 348 additions and 175 deletions

9
astylerc Normal file
View file

@ -0,0 +1,9 @@
style=allman
indent=tab=4
indent-col1-comments
pad-header
unpad-paren
convert-tabs
align-pointer=type
align-reference=name
suffix=none

View file

@ -46,17 +46,22 @@ Banlist banlist;
//// IPRange //// //// IPRange ////
// Constructor // Constructor
IPRange::IPRange() { IPRange::IPRange()
for (byte i = 0;i < 4;i++) { {
for (byte i = 0; i < 4; i++)
{
this->ip[i] = (byte)0; this->ip[i] = (byte)0;
this->mask[i] = false; this->mask[i] = false;
} }
} }
// Check a given address against the ip + range in the object. // Check a given address against the ip + range in the object.
bool IPRange::check(const netadr_t& address) { bool IPRange::check(const netadr_t &address)
for (byte i = 0;i < 4;i++) { {
if (!(this->ip[i] == address.ip[i] || this->mask[i] == true)) { for (byte i = 0; i < 4; i++)
{
if (!(this->ip[i] == address.ip[i] || this->mask[i] == true))
{
return false; return false;
} }
} }
@ -65,17 +70,21 @@ bool IPRange::check(const netadr_t& address) {
} }
// Check a given string address against the ip + range in the object. // Check a given string address against the ip + range in the object.
bool IPRange::check(const std::string& address) { bool IPRange::check(const std::string &address)
{
StringTokens tokens = TokenizeString(address, "."); StringTokens tokens = TokenizeString(address, ".");
// An IP address contains 4 octets // An IP address contains 4 octets
if (tokens.size() != 4) { if (tokens.size() != 4)
{
return false; return false;
} }
for (byte i = 0;i < 4;i++) { for (byte i = 0; i < 4; i++)
{
// * means that octet is masked and we will accept any byte // * means that octet is masked and we will accept any byte
if (tokens[i].compare("*") == 0) { if (tokens[i].compare("*") == 0)
{
continue; continue;
} }
@ -83,11 +92,13 @@ bool IPRange::check(const std::string& address) {
unsigned short octet = 0; unsigned short octet = 0;
std::istringstream buffer(tokens[i]); std::istringstream buffer(tokens[i]);
buffer >> octet; buffer >> octet;
if (!buffer) { if (!buffer)
{
return false; return false;
} }
if (!(this->ip[i] == octet || this->mask[i] == true)) { if (!(this->ip[i] == octet || this->mask[i] == true))
{
return false; return false;
} }
} }
@ -96,25 +107,31 @@ bool IPRange::check(const std::string& address) {
} }
// Set the object's range to a specific address. // Set the object's range to a specific address.
void IPRange::set(const netadr_t& address) { void IPRange::set(const netadr_t &address)
for (byte i = 0;i < 4;i++) { {
for (byte i = 0; i < 4; i++)
{
this->ip[i] = address.ip[i]; this->ip[i] = address.ip[i];
this->mask[i] = false; this->mask[i] = false;
} }
} }
// Set the object's range against the given address in string form. // Set the object's range against the given address in string form.
bool IPRange::set(const std::string& input) { bool IPRange::set(const std::string &input)
{
StringTokens tokens = TokenizeString(input, "."); StringTokens tokens = TokenizeString(input, ".");
// An IP address contains 4 octets // An IP address contains 4 octets
if (tokens.size() != 4) { if (tokens.size() != 4)
{
return false; return false;
} }
for (byte i = 0;i < 4;i++) { for (byte i = 0; i < 4; i++)
{
// * means that octet is masked // * means that octet is masked
if (tokens[i].compare("*") == 0) { if (tokens[i].compare("*") == 0)
{
this->mask[i] = true; this->mask[i] = true;
continue; continue;
} }
@ -124,7 +141,8 @@ bool IPRange::set(const std::string& input) {
unsigned short octet = 0; unsigned short octet = 0;
std::istringstream buffer(tokens[i]); std::istringstream buffer(tokens[i]);
buffer >> octet; buffer >> octet;
if (!buffer) { if (!buffer)
{
return false; return false;
} }
@ -135,17 +153,23 @@ bool IPRange::set(const std::string& input) {
} }
// Return the range as a string, with stars representing masked octets. // Return the range as a string, with stars representing masked octets.
std::string IPRange::string() { std::string IPRange::string()
{
std::ostringstream buffer; std::ostringstream buffer;
for (byte i = 0;i < 4;i++) { for (byte i = 0; i < 4; i++)
if (mask[i]) { {
if (mask[i])
{
buffer << '*'; buffer << '*';
} else { }
else
{
buffer << (unsigned short)this->ip[i]; buffer << (unsigned short)this->ip[i];
} }
if (i < 3) { if (i < 3)
{
buffer << '.'; buffer << '.';
} }
} }
@ -155,12 +179,14 @@ std::string IPRange::string() {
//// Banlist //// //// Banlist ////
bool Banlist::add(const std::string& address, const time_t expire, bool Banlist::add(const std::string &address, const time_t expire,
const std::string& name, const std::string& reason) { const std::string &name, const std::string &reason)
{
Ban ban; Ban ban;
// Did we pass a valid address? // Did we pass a valid address?
if (!ban.range.set(address)) { if (!ban.range.set(address))
{
return false; return false;
} }
@ -176,10 +202,12 @@ bool Banlist::add(const std::string& address, const time_t expire,
} }
// We have a specific client that we want to add to the banlist. // We have a specific client that we want to add to the banlist.
bool Banlist::add(player_t& player, const time_t expire, bool Banlist::add(player_t &player, const time_t expire,
const std::string& reason) { const std::string &reason)
{
// Player must be valid. // Player must be valid.
if (!validplayer(player)) { if (!validplayer(player))
{
return false; return false;
} }
@ -197,11 +225,13 @@ bool Banlist::add(player_t& player, const time_t expire,
} }
// Add an exception to the banlist by address. // Add an exception to the banlist by address.
bool Banlist::add_exception(const std::string& address, const std::string& name) { bool Banlist::add_exception(const std::string &address, const std::string &name)
{
Exception exception; Exception exception;
// Did we pass a valid address? // Did we pass a valid address?
if (!exception.range.set(address)) { if (!exception.range.set(address))
{
return false; return false;
} }
@ -213,9 +243,11 @@ bool Banlist::add_exception(const std::string& address, const std::string& name)
} }
// We have a specific client that we want to add as an exception. // We have a specific client that we want to add as an exception.
bool Banlist::add_exception(player_t& player) { bool Banlist::add_exception(player_t &player)
{
// Player must be valid. // Player must be valid.
if (!validplayer(player)) { if (!validplayer(player))
{
return false; return false;
} }
@ -233,20 +265,25 @@ bool Banlist::add_exception(player_t& player) {
// Check a given address against the exception and banlist. Sets // Check a given address against the exception and banlist. Sets
// baninfo and returns true if passed address is banned, otherwise // baninfo and returns true if passed address is banned, otherwise
// returns false. // returns false.
bool Banlist::check(const netadr_t& address, Ban& baninfo) { bool Banlist::check(const netadr_t &address, Ban &baninfo)
{
// Check against exception list. // Check against exception list.
for (std::vector<Exception>::iterator it = this->exceptionlist.begin(); for (std::vector<Exception>::iterator it = this->exceptionlist.begin();
it != this->exceptionlist.end();++it) { it != this->exceptionlist.end(); ++it)
if (it->range.check(address)) { {
if (it->range.check(address))
{
return false; return false;
} }
} }
// Check against banlist. // Check against banlist.
for (std::vector<Ban>::iterator it = this->banlist.begin(); for (std::vector<Ban>::iterator it = this->banlist.begin();
it != this->banlist.end();++it) { it != this->banlist.end(); ++it)
{
if (it->range.check(address) && (it->expire == 0 || if (it->range.check(address) && (it->expire == 0 ||
it->expire > time(NULL))) { it->expire > time(NULL)))
{
baninfo = *it; baninfo = *it;
return true; return true;
} }
@ -256,14 +293,17 @@ bool Banlist::check(const netadr_t& address, Ban& baninfo) {
} }
// Return a complete list of bans. // Return a complete list of bans.
bool Banlist::query(banlist_results_t &result) { bool Banlist::query(banlist_results_t &result)
{
// No banlist? Return an error state. // No banlist? Return an error state.
if (this->banlist.empty()) { if (this->banlist.empty())
{
return false; return false;
} }
result.reserve(this->banlist.size()); result.reserve(this->banlist.size());
for (size_t i = 0;i < banlist.size();i++) { for (size_t i = 0; i < banlist.size(); i++)
{
result.push_back(banlist_result_t(i, &(this->banlist[i]))); result.push_back(banlist_result_t(i, &(this->banlist[i])));
} }
@ -272,23 +312,28 @@ bool Banlist::query(banlist_results_t &result) {
// Run a query on the banlist and return a list of all matching bans. Matches // Run a query on the banlist and return a list of all matching bans. Matches
// against IP address/range and partial name. // against IP address/range and partial name.
bool Banlist::query(const std::string &query, banlist_results_t &result) { bool Banlist::query(const std::string &query, banlist_results_t &result)
{
// No banlist? Return an error state. // No banlist? Return an error state.
if (this->banlist.empty()) { if (this->banlist.empty())
{
return false; return false;
} }
// No query? Return everything. // No query? Return everything.
if (query.empty()) { if (query.empty())
{
return this->query(result); return this->query(result);
} }
std::string pattern = "*" + (query) + "*"; std::string pattern = "*" + (query) + "*";
for (size_t i = 0;i < this->banlist.size();i++) { for (size_t i = 0; i < this->banlist.size(); i++)
{
bool f_ip = this->banlist[i].range.check(query); bool f_ip = this->banlist[i].range.check(query);
bool f_name = CheckWildcards(pattern.c_str(), bool f_name = CheckWildcards(pattern.c_str(),
this->banlist[i].name.c_str()); this->banlist[i].name.c_str());
if (f_ip || f_name) { if (f_ip || f_name)
{
result.push_back(banlist_result_t(i, &(this->banlist[i]))); result.push_back(banlist_result_t(i, &(this->banlist[i])));
} }
} }
@ -296,14 +341,17 @@ bool Banlist::query(const std::string &query, banlist_results_t &result) {
} }
// Return a complete list of exceptions. // Return a complete list of exceptions.
bool Banlist::query_exception(exceptionlist_results_t &result) { bool Banlist::query_exception(exceptionlist_results_t &result)
{
// No banlist? Return an error state. // No banlist? Return an error state.
if (this->exceptionlist.empty()) { if (this->exceptionlist.empty())
{
return false; return false;
} }
result.reserve(this->exceptionlist.size()); result.reserve(this->exceptionlist.size());
for (size_t i = 0;i < exceptionlist.size();i++) { for (size_t i = 0; i < exceptionlist.size(); i++)
{
result.push_back(exceptionlist_result_t(i, &(this->exceptionlist[i]))); result.push_back(exceptionlist_result_t(i, &(this->exceptionlist[i])));
} }
@ -313,23 +361,28 @@ bool Banlist::query_exception(exceptionlist_results_t &result) {
// Run a query on the exceptionlist and return a list of all matching // Run a query on the exceptionlist and return a list of all matching
// exceptions. Matches against IP address/range and partial name. // exceptions. Matches against IP address/range and partial name.
bool Banlist::query_exception(const std::string &query, bool Banlist::query_exception(const std::string &query,
exceptionlist_results_t &result) { exceptionlist_results_t &result)
{
// No exceptionlist? Return an error state. // No exceptionlist? Return an error state.
if (this->exceptionlist.empty()) { if (this->exceptionlist.empty())
{
return false; return false;
} }
// No query? Return everything. // No query? Return everything.
if (query.empty()) { if (query.empty())
{
return this->query_exception(result); return this->query_exception(result);
} }
std::string pattern = "*" + (query) + "*"; std::string pattern = "*" + (query) + "*";
for (size_t i = 0;i < this->exceptionlist.size();i++) { for (size_t i = 0; i < this->exceptionlist.size(); i++)
{
bool f_ip = this->exceptionlist[i].range.check(query); bool f_ip = this->exceptionlist[i].range.check(query);
bool f_name = CheckWildcards(pattern.c_str(), bool f_name = CheckWildcards(pattern.c_str(),
this->exceptionlist[i].name.c_str()); this->exceptionlist[i].name.c_str());
if (f_ip || f_name) { if (f_ip || f_name)
{
result.push_back(exceptionlist_result_t(i, &(this->exceptionlist[i]))); result.push_back(exceptionlist_result_t(i, &(this->exceptionlist[i])));
} }
} }
@ -337,14 +390,17 @@ bool Banlist::query_exception(const std::string &query,
} }
// Remove a ban from the banlist by index. // Remove a ban from the banlist by index.
bool Banlist::remove(size_t index) { bool Banlist::remove(size_t index)
{
// No banlist? Return an error state. // No banlist? Return an error state.
if (this->banlist.empty()) { if (this->banlist.empty())
{
return false; return false;
} }
// Invalid index? Return an error state. // Invalid index? Return an error state.
if (this->banlist.size() <= index) { if (this->banlist.size() <= index)
{
return false; return false;
} }
@ -353,14 +409,17 @@ bool Banlist::remove(size_t index) {
} }
// Remove a exception from the banlist by index. // Remove a exception from the banlist by index.
bool Banlist::remove_exception(size_t index) { bool Banlist::remove_exception(size_t index)
{
// No exception list? Return an error state. // No exception list? Return an error state.
if (this->exceptionlist.empty()) { if (this->exceptionlist.empty())
{
return false; return false;
} }
// Invalid index? Return an error state. // Invalid index? Return an error state.
if (this->exceptionlist.size() <= index) { if (this->exceptionlist.size() <= index)
{
return false; return false;
} }
@ -369,33 +428,40 @@ bool Banlist::remove_exception(size_t index) {
} }
// Clear the banlist. // Clear the banlist.
void Banlist::clear() { void Banlist::clear()
{
this->banlist.clear(); this->banlist.clear();
} }
// Clear the exceptionlist. // Clear the exceptionlist.
void Banlist::clear_exceptions() { void Banlist::clear_exceptions()
{
this->exceptionlist.clear(); this->exceptionlist.clear();
} }
// Fills a JSON array with bans. // Fills a JSON array with bans.
bool Banlist::json(Json::Value& json_bans) { bool Banlist::json(Json::Value &json_bans)
{
// If there are no bans, we don't want to bother any potential // If there are no bans, we don't want to bother any potential
// writeout functions. // writeout functions.
if (banlist.empty()) { if (banlist.empty())
{
return false; return false;
} }
std::string expire; std::string expire;
tm *tmp; tm* tmp;
for (size_t i = 0;i < banlist.size();i++) { for (size_t i = 0; i < banlist.size(); i++)
{
Json::Value json_ban(Json::objectValue); Json::Value json_ban(Json::objectValue);
json_ban["range"] = this->banlist[i].range.string(); json_ban["range"] = this->banlist[i].range.string();
// Expire time is optional. // Expire time is optional.
if (this->banlist[i].expire != 0) { if (this->banlist[i].expire != 0)
{
tmp = gmtime(&this->banlist[i].expire); tmp = gmtime(&this->banlist[i].expire);
if (StrFormatISOTime(expire, tmp)) { if (StrFormatISOTime(expire, tmp))
{
json_ban["expire"] = expire; json_ban["expire"] = expire;
} }
} }
@ -412,27 +478,34 @@ bool Banlist::json(Json::Value& json_bans) {
} }
// Replace the current banlist with the contents of a JSON array. // Replace the current banlist with the contents of a JSON array.
bool Banlist::json_replace(const Json::Value& json_bans) { bool Banlist::json_replace(const Json::Value &json_bans)
{
this->clear(); this->clear();
tm tmp = {0}; tm tmp = {0};
for (size_t i = 0;i < json_bans.size();i++) { for (size_t i = 0; i < json_bans.size(); i++)
{
Ban ban; Ban ban;
const Json::ArrayIndex index = Json::ArrayIndex(i); const Json::ArrayIndex index = Json::ArrayIndex(i);
if (json_bans[index]["range"] != 0) { if (json_bans[index]["range"] != 0)
{
ban.range.set(json_bans[index]["range"].asString()); ban.range.set(json_bans[index]["range"].asString());
} }
if (json_bans[index]["expire"] != 0) { if (json_bans[index]["expire"] != 0)
if (StrParseISOTime(json_bans[index]["expire"].asString(), &tmp)) { {
if (StrParseISOTime(json_bans[index]["expire"].asString(), &tmp))
{
ban.expire = timegm(&tmp); ban.expire = timegm(&tmp);
} }
} }
if (json_bans[index]["name"] != 0) { if (json_bans[index]["name"] != 0)
{
ban.name = json_bans[index]["name"].asString(); ban.name = json_bans[index]["name"].asString();
} }
if (json_bans[index]["reason"] != 0) { if (json_bans[index]["reason"] != 0)
{
ban.reason = json_bans[index]["reason"].asString(); ban.reason = json_bans[index]["reason"].asString();
} }
this->banlist.push_back(ban); this->banlist.push_back(ban);
@ -444,11 +517,13 @@ bool Banlist::json_replace(const Json::Value& json_bans) {
//// Console commands //// //// Console commands ////
// Ban bans a player by player id. // Ban bans a player by player id.
BEGIN_COMMAND (ban) { BEGIN_COMMAND(ban)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "Usage: ban <player id> [ban length] [reason].\n"); Printf(PRINT_HIGH, "Usage: ban <player id> [ban length] [reason].\n");
return; return;
} }
@ -456,32 +531,39 @@ BEGIN_COMMAND (ban) {
size_t pid; size_t pid;
std::istringstream buffer(arguments[0]); std::istringstream buffer(arguments[0]);
buffer >> pid; buffer >> pid;
if (!buffer) { if (!buffer)
{
Printf(PRINT_HIGH, "ban: need a player id.\n"); Printf(PRINT_HIGH, "ban: need a player id.\n");
return; return;
} }
player_t &player = idplayer(pid); player_t &player = idplayer(pid);
if (!validplayer(player)) { if (!validplayer(player))
{
Printf(PRINT_HIGH, "ban: %d is not a valid player id.\n", pid); Printf(PRINT_HIGH, "ban: %d is not a valid player id.\n", pid);
return; return;
} }
// If a length is specified, turn the length into an expire time. // If a length is specified, turn the length into an expire time.
time_t tim; time_t tim;
if (arguments.size() > 1) { if (arguments.size() > 1)
if (!StrToTime(arguments[1], tim)) { {
if (!StrToTime(arguments[1], tim))
{
Printf(PRINT_HIGH, "ban: invalid ban time (try a period of time like \"2 hours\" or \"permanent\")\n"); Printf(PRINT_HIGH, "ban: invalid ban time (try a period of time like \"2 hours\" or \"permanent\")\n");
return; return;
} }
} else { }
else
{
// Default is a permaban. // Default is a permaban.
tim = 0; tim = 0;
} }
// If a reason is specified, add it too. // If a reason is specified, add it too.
std::string reason; std::string reason;
if (arguments.size() > 2) { if (arguments.size() > 2)
{
// Account for people who forget their double-quotes. // Account for people who forget their double-quotes.
arguments.erase(arguments.begin(), arguments.begin() + 2); arguments.erase(arguments.begin(), arguments.begin() + 2);
reason = JoinStrings(arguments, " "); reason = JoinStrings(arguments, " ");
@ -490,14 +572,17 @@ BEGIN_COMMAND (ban) {
// Add the ban and kick the player. // Add the ban and kick the player.
banlist.add(player, tim, reason); banlist.add(player, tim, reason);
SV_KickPlayer(player, reason); SV_KickPlayer(player, reason);
} END_COMMAND (ban) }
END_COMMAND(ban)
// addban adds a ban by IP address. // addban adds a ban by IP address.
BEGIN_COMMAND (addban) { BEGIN_COMMAND(addban)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "Usage: addban <ip address or ip range> [ban length] [player name] [reason]\n"); Printf(PRINT_HIGH, "Usage: addban <ip address or ip range> [ban length] [player name] [reason]\n");
return; return;
} }
@ -506,39 +591,48 @@ BEGIN_COMMAND (addban) {
// If a length is specified, turn the length into an expire time. // If a length is specified, turn the length into an expire time.
time_t tim; time_t tim;
if (arguments.size() > 1) { if (arguments.size() > 1)
if (!StrToTime(arguments[1], tim)) { {
if (!StrToTime(arguments[1], tim))
{
Printf(PRINT_HIGH, "addban: invalid ban time (try a period of time like \"2 hours\" or \"permanent\")\n"); Printf(PRINT_HIGH, "addban: invalid ban time (try a period of time like \"2 hours\" or \"permanent\")\n");
return; return;
} }
} else { }
else
{
// Default is a permaban. // Default is a permaban.
tim = 0; tim = 0;
} }
// If the player's name is specified, add it too. // If the player's name is specified, add it too.
std::string name; std::string name;
if (arguments.size() > 2) { if (arguments.size() > 2)
{
name = arguments[2]; name = arguments[2];
} }
// If a reason is specified, add it too. // If a reason is specified, add it too.
std::string reason; std::string reason;
if (arguments.size() > 3) { if (arguments.size() > 3)
{
// Account for people who forget their double-quotes. // Account for people who forget their double-quotes.
arguments.erase(arguments.begin(), arguments.begin() + 3); arguments.erase(arguments.begin(), arguments.begin() + 3);
reason = JoinStrings(arguments, " "); reason = JoinStrings(arguments, " ");
} }
banlist.add(address, tim, name, reason); banlist.add(address, tim, name, reason);
} END_COMMAND (addban) }
END_COMMAND(addban)
// Add an exception for a player by player id. // Add an exception for a player by player id.
BEGIN_COMMAND (except) { BEGIN_COMMAND(except)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "Usage: except <player id>.\n"); Printf(PRINT_HIGH, "Usage: except <player id>.\n");
return; return;
} }
@ -546,27 +640,32 @@ BEGIN_COMMAND (except) {
size_t pid; size_t pid;
std::istringstream buffer(arguments[0]); std::istringstream buffer(arguments[0]);
buffer >> pid; buffer >> pid;
if (!buffer) { if (!buffer)
{
Printf(PRINT_HIGH, "except: need a player id.\n"); Printf(PRINT_HIGH, "except: need a player id.\n");
return; return;
} }
player_t &player = idplayer(pid); player_t &player = idplayer(pid);
if (!validplayer(player)) { if (!validplayer(player))
{
Printf(PRINT_HIGH, "except: %d is not a valid player id.\n", pid); Printf(PRINT_HIGH, "except: %d is not a valid player id.\n", pid);
return; return;
} }
// Add the exception. // Add the exception.
banlist.add_exception(player); banlist.add_exception(player);
} END_COMMAND (except) }
END_COMMAND(except)
// addexception adds an exception by IP address. // addexception adds an exception by IP address.
BEGIN_COMMAND (addexception) { BEGIN_COMMAND(addexception)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "Usage: addexception <ip address or ip range> [player name]\n"); Printf(PRINT_HIGH, "Usage: addexception <ip address or ip range> [player name]\n");
return; return;
} }
@ -575,19 +674,23 @@ BEGIN_COMMAND (addexception) {
// If the player's name is specified, add it. // If the player's name is specified, add it.
std::string name; std::string name;
if (arguments.size() > 1) { if (arguments.size() > 1)
{
name = arguments[1]; name = arguments[1];
} }
banlist.add_exception(address, name); banlist.add_exception(address, name);
} END_COMMAND (addexception) }
END_COMMAND(addexception)
// Delete a ban // Delete a ban
BEGIN_COMMAND (delban) { BEGIN_COMMAND(delban)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "Usage: delban <banlist index>\n"); Printf(PRINT_HIGH, "Usage: delban <banlist index>\n");
return; return;
} }
@ -595,22 +698,27 @@ BEGIN_COMMAND (delban) {
size_t bid; size_t bid;
std::istringstream buffer(arguments[0]); std::istringstream buffer(arguments[0]);
buffer >> bid; buffer >> bid;
if (!buffer || bid == 0) { if (!buffer || bid == 0)
{
Printf(PRINT_HIGH, "delban: banlist index must be a nonzero number.\n"); Printf(PRINT_HIGH, "delban: banlist index must be a nonzero number.\n");
return; return;
} }
if (!banlist.remove(bid - 1)) { if (!banlist.remove(bid - 1))
{
Printf(PRINT_HIGH, "delban: banlist index does not exist.\n"); Printf(PRINT_HIGH, "delban: banlist index does not exist.\n");
return; return;
} }
} END_COMMAND (delban) }
END_COMMAND(delban)
BEGIN_COMMAND (delexception) { BEGIN_COMMAND(delexception)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
// We need at least one argument. // We need at least one argument.
if (arguments.size() < 1) { if (arguments.size() < 1)
{
Printf(PRINT_HIGH, "delexception: delban <banlist index>\n"); Printf(PRINT_HIGH, "delexception: delban <banlist index>\n");
return; return;
} }
@ -618,44 +726,55 @@ BEGIN_COMMAND (delexception) {
size_t bid; size_t bid;
std::istringstream buffer(arguments[0]); std::istringstream buffer(arguments[0]);
buffer >> bid; buffer >> bid;
if (!buffer || bid == 0) { if (!buffer || bid == 0)
{
Printf(PRINT_HIGH, "delexception: exception index must be a nonzero number.\n"); Printf(PRINT_HIGH, "delexception: exception index must be a nonzero number.\n");
return; return;
} }
if (!banlist.remove_exception(bid - 1)) { if (!banlist.remove_exception(bid - 1))
{
Printf(PRINT_HIGH, "delexception: exception index does not exist.\n"); Printf(PRINT_HIGH, "delexception: exception index does not exist.\n");
return; return;
} }
} END_COMMAND (delexception) }
END_COMMAND(delexception)
BEGIN_COMMAND (banlist) { BEGIN_COMMAND(banlist)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
banlist_results_t result; banlist_results_t result;
if (!banlist.query(JoinStrings(arguments, " "), result)) { if (!banlist.query(JoinStrings(arguments, " "), result))
{
Printf(PRINT_HIGH, "banlist: banlist is empty.\n"); Printf(PRINT_HIGH, "banlist: banlist is empty.\n");
return; return;
} }
if (result.empty()) { if (result.empty())
{
Printf(PRINT_HIGH, "banlist: no results found.\n"); Printf(PRINT_HIGH, "banlist: no results found.\n");
return; return;
} }
char expire[20]; char expire[20];
tm *tmp; tm* tmp;
for (banlist_results_t::iterator it = result.begin(); for (banlist_results_t::iterator it = result.begin();
it != result.end();++it) { it != result.end(); ++it)
{
std::ostringstream buffer; std::ostringstream buffer;
buffer << it->first + 1 << ". " << it->second->range.string(); buffer << it->first + 1 << ". " << it->second->range.string();
if (it->second->expire == 0) { if (it->second->expire == 0)
{
strncpy(expire, "Permanent", 19); strncpy(expire, "Permanent", 19);
} else { }
else
{
tmp = localtime(&(it->second->expire)); tmp = localtime(&(it->second->expire));
if (!strftime(expire, 20, "%Y-%m-%d %H:%M:%S", tmp)) { if (!strftime(expire, 20, "%Y-%m-%d %H:%M:%S", tmp))
{
strncpy(expire, "???", 19); strncpy(expire, "???", 19);
} }
} }
@ -663,13 +782,19 @@ BEGIN_COMMAND (banlist) {
bool has_name = !it->second->name.empty(); bool has_name = !it->second->name.empty();
bool has_reason = !it->second->reason.empty(); bool has_reason = !it->second->reason.empty();
if (has_name || has_reason) { if (has_name || has_reason)
{
buffer << " ("; buffer << " (";
if (!has_name) { if (!has_name)
{
buffer << "\"" << it->second->reason << "\""; buffer << "\"" << it->second->reason << "\"";
} else if (!has_reason) { }
else if (!has_reason)
{
buffer << it->second->name; buffer << it->second->name;
} else { }
else
{
buffer << it->second->name << ": \"" << it->second->reason << "\""; buffer << it->second->name << ": \"" << it->second->reason << "\"";
} }
buffer << ")"; buffer << ")";
@ -677,14 +802,18 @@ BEGIN_COMMAND (banlist) {
Printf(PRINT_HIGH, "%s", buffer.str().c_str()); Printf(PRINT_HIGH, "%s", buffer.str().c_str());
} }
} END_COMMAND (banlist) }
END_COMMAND(banlist)
BEGIN_COMMAND (clearbanlist) { BEGIN_COMMAND(clearbanlist)
{
banlist.clear(); banlist.clear();
Printf(PRINT_HIGH, "clearbanlist: banlist cleared.\n"); Printf(PRINT_HIGH, "clearbanlist: banlist cleared.\n");
} END_COMMAND (clearbanlist) }
END_COMMAND(clearbanlist)
BEGIN_COMMAND (savebanlist) { BEGIN_COMMAND(savebanlist)
{
std::string banfile; std::string banfile;
if (argc > 1) if (argc > 1)
banfile = argv[1]; banfile = argv[1];
@ -692,18 +821,24 @@ BEGIN_COMMAND (savebanlist) {
banfile = sv_banfile.cstring(); banfile = sv_banfile.cstring();
Json::Value json_bans(Json::arrayValue); Json::Value json_bans(Json::arrayValue);
if (!banlist.json(json_bans)) { if (!banlist.json(json_bans))
{
Printf(PRINT_HIGH, "savebanlist: banlist is empty.\n"); Printf(PRINT_HIGH, "savebanlist: banlist is empty.\n");
return; return;
} }
if (M_WriteJSON(banfile.c_str(), json_bans, true)) { if (M_WriteJSON(banfile.c_str(), json_bans, true))
{
Printf(PRINT_HIGH, "savebanlist: banlist saved to %s.\n", banfile.c_str()); Printf(PRINT_HIGH, "savebanlist: banlist saved to %s.\n", banfile.c_str());
} else { }
else
{
Printf(PRINT_HIGH, "savebanlist: could not save banlist.\n"); Printf(PRINT_HIGH, "savebanlist: could not save banlist.\n");
} }
} END_COMMAND (savebanlist) }
END_COMMAND(savebanlist)
BEGIN_COMMAND (loadbanlist) { BEGIN_COMMAND(loadbanlist)
{
std::string banfile; std::string banfile;
if (argc > 1) if (argc > 1)
banfile = argv[1]; banfile = argv[1];
@ -711,83 +846,108 @@ BEGIN_COMMAND (loadbanlist) {
banfile = sv_banfile.cstring(); banfile = sv_banfile.cstring();
Json::Value json_bans; Json::Value json_bans;
if (!M_ReadJSON(json_bans, banfile.c_str())) { if (!M_ReadJSON(json_bans, banfile.c_str()))
{
Printf(PRINT_HIGH, "loadbanlist: could not load banlist.\n"); Printf(PRINT_HIGH, "loadbanlist: could not load banlist.\n");
return; return;
} }
banlist.json_replace(json_bans); banlist.json_replace(json_bans);
Printf(PRINT_HIGH, "loadbanlist: loaded %d bans from %s.\n", json_bans.size(), banfile.c_str()); Printf(PRINT_HIGH, "loadbanlist: loaded %d bans from %s.\n", json_bans.size(), banfile.c_str());
} END_COMMAND (loadbanlist) }
END_COMMAND(loadbanlist)
BEGIN_COMMAND (exceptionlist) { BEGIN_COMMAND(exceptionlist)
{
std::vector<std::string> arguments = VectorArgs(argc, argv); std::vector<std::string> arguments = VectorArgs(argc, argv);
exceptionlist_results_t result; exceptionlist_results_t result;
if (!banlist.query_exception(JoinStrings(arguments, " "), result)) { if (!banlist.query_exception(JoinStrings(arguments, " "), result))
{
Printf(PRINT_HIGH, "exceptionlist: exceptionlist is empty.\n"); Printf(PRINT_HIGH, "exceptionlist: exceptionlist is empty.\n");
return; return;
} }
if (result.empty()) { if (result.empty())
{
Printf(PRINT_HIGH, "exceptionlist: no results found.\n"); Printf(PRINT_HIGH, "exceptionlist: no results found.\n");
return; return;
} }
for (exceptionlist_results_t::iterator it = result.begin(); for (exceptionlist_results_t::iterator it = result.begin();
it != result.end();++it) { it != result.end(); ++it)
{
std::ostringstream buffer; std::ostringstream buffer;
buffer << it->first + 1 << ". " << it->second->range.string(); buffer << it->first + 1 << ". " << it->second->range.string();
if (!it->second->name.empty()) { if (!it->second->name.empty())
{
buffer << " (" << it->second->name << ")"; buffer << " (" << it->second->name << ")";
} }
Printf(PRINT_HIGH, "%s", buffer.str().c_str()); Printf(PRINT_HIGH, "%s", buffer.str().c_str());
} }
} END_COMMAND (exceptionlist) }
END_COMMAND(exceptionlist)
BEGIN_COMMAND (clearexceptionlist) { BEGIN_COMMAND(clearexceptionlist)
{
banlist.clear_exceptions(); banlist.clear_exceptions();
Printf(PRINT_HIGH, "clearexceptionlist: exceptionlist cleared.\n"); Printf(PRINT_HIGH, "clearexceptionlist: exceptionlist cleared.\n");
} END_COMMAND (clearexceptionlist) }
END_COMMAND(clearexceptionlist)
// Check to see if a client is on the banlist, and kick them out of the server // Check to see if a client is on the banlist, and kick them out of the server
// if they are. Returns true if the player was banned. // if they are. Returns true if the player was banned.
bool SV_BanCheck(client_t *cl, int n) { bool SV_BanCheck(client_t* cl, int n)
{
Ban ban; Ban ban;
if (!banlist.check(cl->address, ban)) { if (!banlist.check(cl->address, ban))
{
return false; return false;
} }
std::ostringstream buffer; std::ostringstream buffer;
if (ban.expire == 0) { if (ban.expire == 0)
{
buffer << "You are indefinitely banned from this server.\n"; buffer << "You are indefinitely banned from this server.\n";
} else { }
else
{
buffer << "You are banned from this server until "; buffer << "You are banned from this server until ";
char tbuffer[32]; char tbuffer[32];
if (strftime(tbuffer, 32, "%c %Z", localtime(&ban.expire))) { if (strftime(tbuffer, 32, "%c %Z", localtime(&ban.expire)))
{
buffer << tbuffer << ".\n"; buffer << tbuffer << ".\n";
} else { }
else
{
buffer << ban.expire << " seconds after midnight on January 1st, 1970.\n"; buffer << ban.expire << " seconds after midnight on January 1st, 1970.\n";
} }
} }
int name = ban.name.compare(""); int name = ban.name.compare("");
int reason = ban.reason.compare(""); int reason = ban.reason.compare("");
if (name != 0 || reason != 0) { if (name != 0 || reason != 0)
{
buffer << "The given reason was: \""; buffer << "The given reason was: \"";
if (name != 0 && reason == 0) { if (name != 0 && reason == 0)
{
buffer << ban.name; buffer << ban.name;
} else if (name == 0 && reason != 0) { }
else if (name == 0 && reason != 0)
{
buffer << ban.reason; buffer << ban.reason;
} else { }
else
{
buffer << ban.name << ": " << ban.reason; buffer << ban.name << ": " << ban.reason;
} }
buffer << "\"\n"; buffer << "\"\n";
} }
if (*(sv_email.cstring()) != 0) { if (*(sv_email.cstring()) != 0)
{
buffer << "The server host can be contacted at "; buffer << "The server host can be contacted at ";
buffer << sv_email.cstring(); buffer << sv_email.cstring();
buffer << " if you feel this ban is in error or wish to contest it."; buffer << " if you feel this ban is in error or wish to contest it.";

View file

@ -33,20 +33,22 @@
#include "d_player.h" #include "d_player.h"
#include "i_net.h" #include "i_net.h"
class IPRange { class IPRange
{
private: private:
byte ip[4]; byte ip[4];
bool mask[4]; bool mask[4];
public: public:
IPRange(void); IPRange(void);
bool check(const netadr_t& address); bool check(const netadr_t &address);
bool check(const std::string& input); bool check(const std::string &input);
void set(const netadr_t& address); void set(const netadr_t &address);
bool set(const std::string& input); bool set(const std::string &input);
std::string string(void); std::string string(void);
}; };
struct Ban { struct Ban
{
Ban(void) : expire(0) { }; Ban(void) : expire(0) { };
time_t expire; time_t expire;
std::string name; std::string name;
@ -54,7 +56,8 @@ struct Ban {
std::string reason; std::string reason;
}; };
struct Exception { struct Exception
{
std::string name; std::string name;
IPRange range; IPRange range;
}; };
@ -64,17 +67,18 @@ typedef std::vector<banlist_result_t> banlist_results_t;
typedef std::pair<size_t, Exception*> exceptionlist_result_t; typedef std::pair<size_t, Exception*> exceptionlist_result_t;
typedef std::vector<exceptionlist_result_t> exceptionlist_results_t; typedef std::vector<exceptionlist_result_t> exceptionlist_results_t;
class Banlist { class Banlist
{
public: public:
bool add(const std::string& address, const time_t expire = 0, bool add(const std::string &address, const time_t expire = 0,
const std::string& name = std::string(), const std::string &name = std::string(),
const std::string& reason = std::string()); const std::string &reason = std::string());
bool add(player_t& player, const time_t expire = 0, bool add(player_t &player, const time_t expire = 0,
const std::string& reason = std::string()); const std::string &reason = std::string());
bool add_exception(const std::string& address, bool add_exception(const std::string &address,
const std::string& name = std::string()); const std::string &name = std::string());
bool add_exception(player_t& player); bool add_exception(player_t &player);
bool check(const netadr_t& address, Ban& baninfo); bool check(const netadr_t &address, Ban &baninfo);
bool query(banlist_results_t &result); bool query(banlist_results_t &result);
bool query(const std::string &query, banlist_results_t &result); bool query(const std::string &query, banlist_results_t &result);
bool query_exception(exceptionlist_results_t &result); bool query_exception(exceptionlist_results_t &result);
@ -84,14 +88,14 @@ public:
bool remove_exception(size_t index); bool remove_exception(size_t index);
void clear(); void clear();
void clear_exceptions(); void clear_exceptions();
bool json(Json::Value& json_bans); bool json(Json::Value &json_bans);
bool json_replace(const Json::Value& json_bans); bool json_replace(const Json::Value &json_bans);
void json_exceptions(); void json_exceptions();
private: private:
std::vector<Ban> banlist; std::vector<Ban> banlist;
std::vector<Exception> exceptionlist; std::vector<Exception> exceptionlist;
}; };
bool SV_BanCheck(client_t *cl, int n); bool SV_BanCheck(client_t* cl, int n);
#endif #endif