diff --git a/Jupiter b/Jupiter index 5338777..5b83899 160000 --- a/Jupiter +++ b/Jupiter @@ -1 +1 @@ -Subproject commit 5338777b91ca98bfcd4aea3620a69071d42701f0 +Subproject commit 5b83899a03642d18deb6a85dabfb1afd8d76422e diff --git a/Release/Bot.lib b/Release/Bot.lib index ca176ee..9b08312 100644 Binary files a/Release/Bot.lib and b/Release/Bot.lib differ diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib index 46f8691..fb64588 100644 Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ diff --git a/RenX.Commands/RenX_Commands.cpp b/RenX.Commands/RenX_Commands.cpp index c4e0de9..dc7bebb 100644 --- a/RenX.Commands/RenX_Commands.cpp +++ b/RenX.Commands/RenX_Commands.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -48,12 +48,6 @@ inline void onDie(RenX::Server *server, const RenX::PlayerInfo *player) server->kickPlayer(player, Jupiter::StringS::empty); } -bool RenX_CommandsPlugin::RenX_OnBan(RenX::Server *server, const RenX::PlayerInfo *player, Jupiter::StringType &data) -{ - data = player->varData.get(this->getName(), STRING_LITERAL_AS_REFERENCE("banner")); - return !data.isEmpty(); -} - void RenX_CommandsPlugin::RenX_OnSuicide(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &) { onDie(server, player); @@ -1122,43 +1116,38 @@ void BanSearchIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString default: case 0: // ANY return isMatch(1) || isMatch(2) || isMatch(3) || isMatch(4); - case 1: // IP + case 1: // ALL + return true; + case 2: // IP return entry->ip == params.asUnsignedInt(); - case 2: // RDNS + case 3: // RDNS return entry->rdns.equals(params); - case 3: // STEAM + case 4: // STEAM return entry->steamid == params.asUnsignedLongLong(); - case 4: // NAME + case 5: // NAME return entry->name.equalsi(params); - case 5: // BANNER + case 6: // BANNER return entry->varData.get(pluginInstance.getName()).equalsi(params); - case 6: // ACTIVE - if (params.asBool()) // Got tired of seeing a compiler warning. - return entry->active == 1; - else - return entry->active == 0; - case 7: // ALL - return true; + case 7: // ACTIVE + return params.asBool() == entry->is_active(); } }; unsigned int type; Jupiter::ReferenceString type_str = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); - if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("ip"))) + if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("all")) || type_str.equals('*')) type = 1; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("rdns"))) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("ip"))) type = 2; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("steam"))) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("rdns"))) type = 3; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("name"))) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("steam"))) type = 4; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("banner"))) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("name"))) type = 5; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("active"))) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("banner"))) type = 6; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("any"))) - type = 0; - else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("all")) || type_str.equals('*')) + else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("active"))) type = 7; else { @@ -1167,17 +1156,43 @@ void BanSearchIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString } Jupiter::String out(256); + Jupiter::String types(64); char timeStr[256]; for (size_t i = 0; i != entries.size(); i++) { entry = entries.get(i); if (isMatch(type)) { - Jupiter::StringS ip_str = Jupiter::Socket::ntop4(entry->ip); + Jupiter::StringS &ip_str = Jupiter::Socket::ntop4(entry->ip); const Jupiter::ReadableString &banner = entry->varData.get(pluginInstance.getName()); strftime(timeStr, sizeof(timeStr), "%b %d %Y; Time: %H:%M:%S", localtime(&(entry->timestamp))); - out.format("ID: %lu; Status: %sactive; Date: %s; IP: %.*s; Steam: %llu; Name: %.*s%s", i, entry->active ? "" : "in", timeStr, ip_str.size(), ip_str.ptr(), entry->steamid, entry->name.size(), entry->name.ptr(), banner.isEmpty() ? "" : "; Banner: "); - out.concat(banner); + + if ((entry->flags & 0x7F) == 0) + types = " NULL;"_jrs; + else + { + types.erase(); + if (entry->is_type_game()) + types += " game"_jrs; + if (entry->is_type_chat()) + types += " chat"_jrs; + if (entry->is_type_bot()) + types += " bot"_jrs; + if (entry->is_type_vote()) + types += " vote"_jrs; + if (entry->is_type_mine()) + types += " mine"_jrs; + if (entry->is_type_ladder()) + types += " ladder"_jrs; + if (entry->is_type_alert()) + types += " alert"_jrs; + types += ";"_jrs; + } + + out.format("ID: %lu (%sactive); Date: %s; IP: %.*s/%u; Steam: %llu; Types:%.*s Name: %.*s; Banner: %.*s", + i, entry->is_active() ? "" : "in", timeStr, ip_str.size(), ip_str.ptr(), entry->prefix_length, entry->steamid, types.size(), types.ptr(), + entry->name.size(), entry->name.ptr(), banner.size(), banner.ptr()); + if (entry->rdns.isNotEmpty()) { out.concat("; RDNS: "_jrs); @@ -1883,8 +1898,7 @@ void TempBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString & player = server->getPlayerByPartName(name); if (player != nullptr) { - player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick); - server->banPlayer(player, reason, pluginInstance.getTBanTime()); + server->banPlayer(player, banner, reason, pluginInstance.getTBanTime()); kicks++; } } @@ -1941,8 +1955,7 @@ void KickBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString & player = server->getPlayerByPartName(name); if (player != nullptr) { - player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick); - server->banPlayer(player, reason); + server->banPlayer(player, banner, reason); kicks++; } } @@ -2519,37 +2532,29 @@ void ModRequestGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *play Jupiter::IRC::Client::Channel *channel; unsigned int channelCount; unsigned int messageCount = 0; - int type; Jupiter::String &fmtName = RenX::getFormattedPlayerName(player); Jupiter::StringL msg = Jupiter::StringL::Format(IRCCOLOR "12[Moderator Request] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR "07 has requested assistance in-game; please look in ", fmtName.size(), fmtName.ptr()); Jupiter::StringS msg2 = Jupiter::StringS::Format(IRCCOLOR "12[Moderator Request] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR "07 has requested assistance in-game!" IRCCOLOR, fmtName.size(), fmtName.ptr()); for (unsigned int a = 0; a < serverCount; a++) { server = serverManager->getServer(a); - if (server != nullptr) + channelCount = server->getChannelCount(); + for (unsigned int b = 0; b < channelCount; b++) { - channelCount = server->getChannelCount(); - for (unsigned int b = 0; b < channelCount; b++) + channel = server->getChannel(b); + if (source->isLogChanType(channel->getType())) { - channel = server->getChannel(b); - if (channel != nullptr) + server->sendMessage(channel->getName(), msg2); + msg += channel->getName(); + for (unsigned int c = 0; c < channel->getUserCount(); c++) { - type = channel->getType(); - if (source->isLogChanType(type)) + if (channel->getUserPrefix(c) != 0 && channel->getUser(c)->getNickname().equals(server->getNickname()) == false) { - server->sendMessage(channel->getName(), msg2); - msg += channel->getName(); - for (unsigned int c = 0; c < channel->getUserCount(); c++) - { - if (channel->getUserPrefix(c) != 0 && channel->getUser(c)->getNickname().equals(server->getNickname()) == false) - { - server->sendMessage(channel->getUser(c)->getUser()->getNickname(), msg); - messageCount++; - } - } - msg -= channel->getName().size(); + server->sendMessage(channel->getUser(c)->getUser()->getNickname(), msg); + messageCount++; } } + msg -= channel->getName().size(); } } } @@ -2807,8 +2812,7 @@ void TempBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not ban higher level moderators.")); else { - target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name); - source->banPlayer(target, reason, pluginInstance.getTBanTime()); + source->banPlayer(target, player->name, reason, pluginInstance.getTBanTime()); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been temporarily banned and kicked from the game.")); } } @@ -2850,8 +2854,7 @@ void KickBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not ban higher level moderators.")); else { - target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name); - source->banPlayer(target, reason); + source->banPlayer(target, player->name, reason); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been banned and kicked from the game.")); } } diff --git a/RenX.Commands/RenX_Commands.h b/RenX.Commands/RenX_Commands.h index fed419a..a790a1c 100644 --- a/RenX.Commands/RenX_Commands.h +++ b/RenX.Commands/RenX_Commands.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,8 +27,6 @@ class RenX_CommandsPlugin : public RenX::Plugin { public: // RenX::Plugin - bool RenX_OnBan(RenX::Server *server, const RenX::PlayerInfo *player, Jupiter::StringType &data); - void RenX_OnSuicide(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &damageType) override; void RenX_OnKill(RenX::Server *server, const RenX::PlayerInfo *player, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &damageType) override; void RenX_OnDie(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &damageType) override; diff --git a/RenX.Core/RenX_BanDatabase.cpp b/RenX.Core/RenX_BanDatabase.cpp index aec8fdc..851a209 100644 --- a/RenX.Core/RenX_BanDatabase.cpp +++ b/RenX.Core/RenX_BanDatabase.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,170 +30,74 @@ RenX::BanDatabase _banDatabase; RenX::BanDatabase *RenX::banDatabase = &_banDatabase; RenX::BanDatabase &RenX::defaultBanDatabase = _banDatabase; -const Jupiter::ReferenceString DEFAULT_REASON = "(No reason information provided)"; -const uint8_t write_version = 2U; - -bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname) +void RenX::BanDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) { - RenX::BanDatabase::filename = fname; - FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "rb"); - if (file != nullptr) - { - RenX::BanDatabase::version = fgetc(file); - while (!feof(file)) - if (fgetc(file) == '\n') - break; - Jupiter::String rdns(128); - Jupiter::String playerName(16); - Jupiter::String key(32); - Jupiter::String value(32); - Jupiter::String reason(128); - if (RenX::BanDatabase::version == 0) - reason = DEFAULT_REASON; - Entry *entry; - int c; - while (!feof(file)) - { - entry = new Entry(); - fgetpos(file, &entry->pos); - fread(&entry->active, 1, 1, file); - fread(&entry->timestamp, sizeof(time_t), 1, file); - fread(&entry->length, sizeof(time_t), 1, file); - fread(&entry->steamid, sizeof(uint64_t), 1, file); - fread(&entry->ip, sizeof(uint32_t), 1, file); - if (feof(file)) - { - delete entry; - break; - } - - // load rdns - if (RenX::BanDatabase::version >= 2) - { - rdns.truncate(rdns.size()); - c = fgetc(file); - while (c != '\n' && c != '\0') - { - if (c == EOF) - { - fprintf(stderr, "ERROR: Unexpected EOF in %s at %lu", RenX::BanDatabase::filename.c_str(), ftell(file)); - break; - } - rdns += c; - c = fgetc(file); - } - entry->rdns = rdns; - } - - // load name - playerName.truncate(playerName.size()); - c = fgetc(file); - while (c != '\n' && c != '\0') - { - if (c == EOF) - { - fprintf(stderr, "ERROR: Unexpected EOF in %s at %lu", RenX::BanDatabase::filename.c_str(), ftell(file)); - break; - } - playerName += c; - c = fgetc(file); - } - entry->name = playerName; - - // load reason - if (RenX::BanDatabase::version >= 1) - { - reason.truncate(reason.size()); - c = fgetc(file); - while (c != '\n' && c != '\0') - { - if (c == EOF) - { - fprintf(stderr, "ERROR: Unexpected EOF in %s at %lu", RenX::BanDatabase::filename.c_str(), ftell(file)); - break; - } - reason += c; - c = fgetc(file); - } - } - entry->reason = reason; - - // load variable data - while (c == '\0') - { - key.truncate(key.size()); - value.truncate(value.size()); + if (RenX::BanDatabase::read_version < 3U) + return; // incompatible database version + + RenX::BanDatabase::Entry *entry = new RenX::BanDatabase::Entry(); + entry->pos = pos; + + // Read data from buffer to entry + entry->flags = buffer.pop(); + entry->timestamp = buffer.pop(); + entry->length = buffer.pop(); + entry->steamid = buffer.pop(); + entry->ip = buffer.pop(); + entry->prefix_length = buffer.pop(); + entry->rdns = buffer.pop(); + entry->name = buffer.pop(); + entry->banner = buffer.pop(); + entry->reason = buffer.pop(); + + // Read varData from buffer to entry + for (size_t varData_entries = buffer.pop(); varData_entries != 0; --varData_entries) + entry->varData.set(buffer.pop(), buffer.pop()); +} - // load key - c = fgetc(file); - while (c != '\0' && c != EOF) - { - key += c; - c = fgetc(file); - } - if (c == EOF) - { - fprintf(stderr, "ERROR: Unexpected EOF in %s at %lu", RenX::BanDatabase::filename.c_str(), ftell(file)); - break; - } +void RenX::BanDatabase::process_header(FILE *file) +{ + int chr = fgetc(file); + if (chr != EOF) + RenX::BanDatabase::read_version = chr; +} - // load value - c = fgetc(file); - while (c != '\n' && c != '\0' && c != EOF) - { - value += c; - c = fgetc(file); - } - if (c == EOF) - { - fprintf(stderr, "ERROR: Unexpected EOF in %s at %lu", RenX::BanDatabase::filename.c_str(), ftell(file)); - break; - } +void RenX::BanDatabase::create_header(FILE *file) +{ + fputc(RenX::BanDatabase::write_version, file); +} - entry->varData.set(key, value); - } - entries.add(entry); - } - fclose(file); - if (RenX::BanDatabase::version != write_version) +void RenX::BanDatabase::process_file_finish(FILE *file) +{ + if (RenX::BanDatabase::read_version < 3) + { + if (freopen(RenX::BanDatabase::filename.c_str(), "wb", file) == nullptr) + puts("FATAL ERROR: UNABLE TO REMOVE UNSUPPORTED BAN DATABASE FILE VERSION"); + else { - file = fopen(RenX::BanDatabase::filename.c_str(), "wb"); - if (file != nullptr) - { - fputc(write_version, file); - fputc('\n', file); - size_t index = 0; - while (index != RenX::BanDatabase::entries.size()) - RenX::BanDatabase::write(RenX::BanDatabase::entries.get(++index), file); - fclose(file); - fprintf(stdout, "Updated BanDatabase file \"%s\" from version %d to %d." ENDL, RenX::BanDatabase::filename.c_str(), RenX::BanDatabase::version, write_version); - } - else - fprintf(stdout, "CRITICAL ERROR: BanDatabase file \"%s\" failed to update from version %d to %d." ENDL, RenX::BanDatabase::filename.c_str(), RenX::BanDatabase::version, write_version); - RenX::BanDatabase::version = write_version; + puts("Warning: Unsupported ban database file version. The database will be removed and rewritten."); + this->create_header(file); + RenX::BanDatabase::read_version = RenX::BanDatabase::write_version; } - return true; } - else +} + +void RenX::BanDatabase::upgrade_database() +{ + FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "wb"); + if (file != nullptr) { - RenX::BanDatabase::version = write_version; - file = fopen(RenX::BanDatabase::filename.c_str(), "ab"); - if (file != nullptr) - { - fputc(RenX::BanDatabase::version, file); - fputc('\n', file); - fclose(file); - return true; - } - return false; + this->create_header(file); + for (size_t index = 0; RenX::BanDatabase::entries.size(); ++index) + RenX::BanDatabase::write(RenX::BanDatabase::entries.get(index), file); + + fclose(file); } } void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry) { - if (RenX::BanDatabase::version != write_version) - "CRITICAL ERROR: COULD NOT WRITE BAN ENTRY TO BAN DATABASE (VERSION MISMATCH)"_jrs.print(stdout); - FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "ab"); + FILE *file = fopen(filename.c_str(), "ab"); if (file != nullptr) { RenX::BanDatabase::write(entry, file); @@ -203,40 +107,50 @@ void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry) void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry, FILE *file) { + Jupiter::DataBuffer buffer; fgetpos(file, &entry->pos); - fwrite(&entry->active, 1, 1, file); - fwrite(&entry->timestamp, sizeof(time_t), 1, file); - fwrite(&entry->length, sizeof(time_t), 1, file); - fwrite(&entry->steamid, sizeof(uint64_t), 1, file); - fwrite(&entry->ip, sizeof(uint32_t), 1, file); - fwrite(entry->rdns.ptr(), sizeof(char), entry->rdns.size(), file); - fputc('\0', file); - fwrite(entry->name.ptr(), sizeof(char), entry->name.size(), file); - fputc('\0', file); - fwrite(entry->reason.ptr(), sizeof(char), entry->reason.size(), file); - for (size_t index = 0; index != entry->varData.size(); ++index) + // push data from entry to buffer + buffer.push(entry->flags); + buffer.push(entry->timestamp); + buffer.push(entry->length); + buffer.push(entry->steamid); + buffer.push(entry->ip); + buffer.push(entry->prefix_length); + buffer.push(entry->rdns); + buffer.push(entry->name); + buffer.push(entry->banner); + buffer.push(entry->reason); + + // push varData from entry to buffer + size_t varData_entries = entry->varData.size(); + buffer.push(varData_entries); + + Jupiter::INIFile::Section::KeyValuePair *pair; + while (varData_entries != 0) { - const Jupiter::INIFile::Section::KeyValuePair *pair = entry->varData.getPair(index); - fputc('\0', file); - fwrite(pair->getKey().ptr(), sizeof(char), pair->getKey().size(), file); - fputc('\0', file); - fwrite(pair->getValue().ptr(), sizeof(char), pair->getValue().size(), file); + pair = entry->varData.getPair(--varData_entries); + buffer.push(pair->getKey()); + buffer.push(pair->getValue()); } - fputc('\n', file); + // push buffer to file + buffer.push_to(file); } -void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length) +void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, time_t length, uint8_t flags) { Entry *entry = new Entry(); - entry->active = 1; + entry->set_active(); + entry->flags |= flags; entry->timestamp = time(0); entry->length = length; entry->steamid = player->steamid; entry->ip = player->ip32; + entry->prefix_length = 32U; entry->rdns = player->rdns; entry->name = player->name; + entry->banner = banner; entry->reason = reason; // add plugin data @@ -244,7 +158,26 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player Jupiter::ArrayList &xPlugins = *RenX::getCore()->getPlugins(); for (size_t i = 0; i < xPlugins.size(); i++) if (xPlugins.get(i)->RenX_OnBan(server, player, pluginData)) - entry->varData.set(xPlugins.get(i)->getName(), pluginData); + entry->varData.set(xPlugins.get(i)->getName(), pluginData); + + entries.add(entry); + RenX::BanDatabase::write(entry); +} + +void RenX::BanDatabase::add(const Jupiter::ReadableString &name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &rdns, Jupiter::ReadableString &banner, Jupiter::ReadableString &reason, time_t length, uint8_t flags) +{ + Entry *entry = new Entry(); + entry->set_active(); + entry->flags |= flags; + entry->timestamp = time(0); + entry->length = length; + entry->steamid = steamid; + entry->ip = ip; + entry->prefix_length = prefix_length; + entry->rdns = rdns; + entry->name = name; + entry->banner = banner; + entry->reason = reason; entries.add(entry); RenX::BanDatabase::write(entry); @@ -253,14 +186,14 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player bool RenX::BanDatabase::deactivate(size_t index) { RenX::BanDatabase::Entry *entry = RenX::BanDatabase::entries.get(index); - if (entry->active) + if (entry->is_active()) { - entry->active = 0; + entry->unset_active(); FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "r+b"); if (file != nullptr) { fsetpos(file, &entry->pos); - fputc(entry->active, file); + fputc(entry->flags, file); fclose(file); } return true; @@ -270,7 +203,7 @@ bool RenX::BanDatabase::deactivate(size_t index) uint8_t RenX::BanDatabase::getVersion() const { - return RenX::BanDatabase::version; + return RenX::BanDatabase::write_version; } const Jupiter::ReadableString &RenX::BanDatabase::getFileName() const @@ -285,7 +218,8 @@ const Jupiter::ArrayList &RenX::BanDatabase::getEntrie RenX::BanDatabase::BanDatabase() { - RenX::BanDatabase::load(Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("RenX"), STRING_LITERAL_AS_REFERENCE("BanDB"), STRING_LITERAL_AS_REFERENCE("Bans.db"))); + RenX::BanDatabase::filename = Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("RenX"), STRING_LITERAL_AS_REFERENCE("BanDB"), STRING_LITERAL_AS_REFERENCE("Bans.db")); + this->process_file(filename); } RenX::BanDatabase::~BanDatabase() diff --git a/RenX.Core/RenX_BanDatabase.h b/RenX.Core/RenX_BanDatabase.h index 49057de..a82b079 100644 --- a/RenX.Core/RenX_BanDatabase.h +++ b/RenX.Core/RenX_BanDatabase.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,6 +21,7 @@ #include #include +#include "Jupiter/Database.h" #include "Jupiter/String.h" #include "Jupiter/CString.h" #include "Jupiter/ArrayList.h" @@ -39,8 +40,39 @@ namespace RenX /** * @brief Represents the local ban database. */ - class RENX_API BanDatabase + class RENX_API BanDatabase : public Jupiter::Database { + public: // Jupiter::Database + /** + * @brief Processes a chunk of data in a database. + * + * @param buffer Buffer to process + * @param file File being processed + * @param pos position that the buffer starts at in the file + */ + void process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) override; + + /** + * @brief Processes the header for a database. + * + * @param file File being processed + */ + void process_header(FILE *file) override; + + /** + * @brief Generates a header for a database. + * + * @param file File being created + */ + void create_header(FILE *file) override; + + /** + * @brief Called when process_file() is successfully completed. + * + * @param file File being processed + */ + void process_file_finish(FILE *file) override; + public: /** * @brief Represents a Ban entry in the database. @@ -48,44 +80,94 @@ namespace RenX struct RENX_API Entry { fpos_t pos; /** Position of the entry in the database */ - unsigned char active; /** 1 if the ban is active, 0 otherwise */ + uint8_t flags /** Flags affecting this ban entry (0 = Active, 1 = Game, 2 = Chat, 3 = Command, 4 = Vote, 5 = Mine, 6 = Ladder, 7 = Alert Mods) */ = 0x00; time_t timestamp /** Time the ban was created */; time_t length /** Duration of the ban; 0 if permanent */; uint64_t steamid /** SteamID of the banned player */; uint32_t ip /** IPv4 address of the banned player */; + uint8_t prefix_length /** Prefix length for the IPv4 address block */; Jupiter::StringS rdns /** RDNS of the banned player */; Jupiter::StringS name /** Name of the banned player */; + Jupiter::StringS banner /** Name of the user who initiated the ban */; Jupiter::StringS reason /** Reason the player was banned */; Jupiter::INIFile::Section varData; /** Variable entry data */ + + static const uint8_t FLAG_ACTIVE = 0x80; + static const uint8_t FLAG_TYPE_GAME = 0x40; + static const uint8_t FLAG_TYPE_CHAT = 0x20; + static const uint8_t FLAG_TYPE_BOT = 0x10; + static const uint8_t FLAG_TYPE_VOTE = 0x08; + static const uint8_t FLAG_TYPE_MINE = 0x04; + static const uint8_t FLAG_TYPE_LADDER = 0x02; + static const uint8_t FLAG_TYPE_ALERT = 0x01; + + inline bool is_active() { return (flags & FLAG_ACTIVE) != 0; }; + inline bool is_type_game() { return (flags & FLAG_TYPE_GAME) != 0; }; + inline bool is_type_chat() { return (flags & FLAG_TYPE_CHAT) != 0; }; + inline bool is_type_bot() { return (flags & FLAG_TYPE_BOT) != 0; }; + inline bool is_type_vote() { return (flags & FLAG_TYPE_VOTE) != 0; }; + inline bool is_type_mine() { return (flags & FLAG_TYPE_MINE) != 0; }; + inline bool is_type_ladder() { return (flags & FLAG_TYPE_LADDER) != 0; }; + inline bool is_type_alert() { return (flags & FLAG_TYPE_ALERT) != 0; }; + inline bool is_type_global() { return ~(flags | 0x01) == 0; }; + + inline void set_active() { flags |= FLAG_ACTIVE; }; + inline void set_type_game() { flags |= FLAG_TYPE_GAME; }; + inline void set_type_chat() { flags |= FLAG_TYPE_CHAT; }; + inline void set_type_bot() { flags |= FLAG_TYPE_BOT; }; + inline void set_type_vote() { flags |= FLAG_TYPE_VOTE; }; + inline void set_type_mine() { flags |= FLAG_TYPE_MINE; }; + inline void set_type_ladder() { flags |= FLAG_TYPE_LADDER; }; + inline void set_type_alert() { flags |= FLAG_TYPE_ALERT; }; + inline void set_type_global() { flags = 0xFF; }; + + inline void unset_active() { flags &= ~FLAG_ACTIVE; }; + inline void unset_type_game() { flags &= ~FLAG_TYPE_GAME; }; + inline void unset_type_chat() { flags &= ~FLAG_TYPE_CHAT; }; + inline void unset_type_bot() { flags &= ~FLAG_TYPE_BOT; }; + inline void unset_type_vote() { flags &= ~FLAG_TYPE_VOTE; }; + inline void unset_type_mine() { flags &= ~FLAG_TYPE_MINE; }; + inline void unset_type_ladder() { flags &= ~FLAG_TYPE_LADDER; }; + inline void unset_type_alert() { flags &= ~FLAG_TYPE_ALERT; }; + inline void unset_type_global() { flags = 0x00; }; }; /** - * @brief Loads a file into the ban system. - * Note: This will generate a database file if none is found. + * @brief Adds a ban entry for a player and immediately writes it to the database. * - * @param fname String containing the name of the file to load - * @return True on success, false otherwise. + * @param server Server the player is playing in + * @param player Data of the player to be banned + * @param length Duration of the ban */ - bool load(const Jupiter::ReadableString &fname); + void add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, time_t length, uint8_t flags = RenX::BanDatabase::Entry::FLAG_TYPE_GAME); /** - * @brief Adds a ban entry for a player and immediately writes it to the database. + * @brief Adds a ban entry for a set of player information and immediately writes it to the database. * - * @param server Server the player is playing in - * @param player Data of the player to be banned + * @param name Name of the player to ban + * @param ip IPv4 address of the player to ban + * @param steamid SteamID of the player to ban + * @param rdns RDNS of the player to ban + * @param banner Person implementing the ban + * @param reason Reason the player is getting banned * @param length Duration of the ban */ - void add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length); + void add(const Jupiter::ReadableString &name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &rdns, Jupiter::ReadableString &banner, Jupiter::ReadableString &reason, time_t length, uint8_t flags = RenX::BanDatabase::Entry::FLAG_TYPE_GAME); /** - * @brief Writes a ban file to the database. + * @brief Upgrades the ban database to the current write_version. + */ + void upgrade_database(); + + /** + * @brief Writes a ban entry to the database. * * @param entry Entry to write to the database. */ void write(Entry *entry); /** - * @brief Writes a ban file to the database. + * @brief Writes a ban entry to the database. * * @param entry Entry to write to the database. * @param file FILE stream to write to. @@ -125,7 +207,10 @@ namespace RenX ~BanDatabase(); private: - uint8_t version; + /** Database version */ + const uint8_t write_version = 3U; + uint8_t read_version = write_version; + Jupiter::CStringS filename; Jupiter::ArrayList entries; }; diff --git a/RenX.Core/RenX_PlayerInfo.h b/RenX.Core/RenX_PlayerInfo.h index 5b4bbf1..d01f511 100644 --- a/RenX.Core/RenX_PlayerInfo.h +++ b/RenX.Core/RenX_PlayerInfo.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -53,6 +53,7 @@ namespace RenX Jupiter::StringS vehicle; uint64_t steamid = 0; uint32_t ip32 = 0; + uint8_t ban_flags = 0; TeamType team = TeamType::Other; int id = 0; bool isBot = false; diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp index 50bbede..c11833d 100644 --- a/RenX.Core/RenX_Server.cpp +++ b/RenX.Core/RenX_Server.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,7 @@ */ #include +#include #include "Jupiter/INIFile.h" #include "Jupiter/String.h" #include "ServerManager.h" @@ -378,7 +379,7 @@ void RenX::Server::forceKickPlayer(const RenX::PlayerInfo *player, const Jupiter RenX::Server::forceKickPlayer(player->id, reason); } -void RenX::Server::banPlayer(int id, const Jupiter::ReadableString &reason) +void RenX::Server::banPlayer(int id, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason) { if (RenX::Server::rconBan) RenX::Server::sock.send(Jupiter::StringS::Format("ckickban pid%d %.*s\n", id, reason.size(), reason.ptr())); @@ -386,22 +387,26 @@ void RenX::Server::banPlayer(int id, const Jupiter::ReadableString &reason) { RenX::PlayerInfo *player = RenX::Server::getPlayer(id); if (player != nullptr) - RenX::Server::banPlayer(player, reason); + RenX::Server::banPlayer(player, banner, reason); } } -void RenX::Server::banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length) +void RenX::Server::banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, time_t length) { if (RenX::Server::localBan) - RenX::banDatabase->add(this, player, reason, length); + RenX::banDatabase->add(this, player, banner, reason, length); if (length == 0) { if (RenX::Server::rconBan) RenX::Server::sock.send(Jupiter::StringS::Format("ckickban pid%d %.*s\n", player->id, reason.size(), reason.ptr())); + else if (banner.isNotEmpty()) + RenX::Server::forceKickPlayer(player, Jupiter::StringS::Format("You are permanently banned from the server by %.*s for: %.*s", banner.size(), banner.ptr(), reason.size(), reason.ptr())); else RenX::Server::forceKickPlayer(player, Jupiter::StringS::Format("You are permanently banned from the server for: %.*s", reason.size(), reason.ptr())); } + else if (banner.isNotEmpty()) + RenX::Server::forceKickPlayer(player, Jupiter::StringS::Format("You are banned from the server by %.*s for the next %d days, %d:%d:%d for: %.*s", banner.size(), banner.ptr(), length / 86400, length % 3600, (length % 3600) / 60, length % 60, reason.size(), reason.ptr())); else RenX::Server::forceKickPlayer(player, Jupiter::StringS::Format("You are banned from the server for the next %d days, %d:%d:%d for: %.*s", length/86400, length%3600, (length%3600)/60, length%60, reason.size(), reason.ptr())); } @@ -988,7 +993,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) auto onChat = [this](RenX::PlayerInfo *player, const Jupiter::ReadableString &message) { const Jupiter::ReadableString &prefix = this->getCommandPrefix(); - if (message.find(prefix) == 0 && message.size() != prefix.size()) + if ((player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_BOT) == 0 && message.find(prefix) == 0 && message.size() != prefix.size()) { Jupiter::ReferenceString command; Jupiter::ReferenceString parameters; @@ -1028,34 +1033,152 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) isBot = false; id = idToken.asInt(10); }; - auto banCheck = [this](const RenX::PlayerInfo *player) + auto banCheck = [this](RenX::PlayerInfo *player) { const Jupiter::ArrayList &entries = RenX::banDatabase->getEntries(); RenX::BanDatabase::Entry *entry = nullptr; + uint32_t netmask; + + RenX::BanDatabase::Entry *last_to_expire[7]; + for (size_t index = 0; index != sizeof(last_to_expire); ++index) + last_to_expire[index] = nullptr; + + auto handle_type = [entry](RenX::BanDatabase::Entry *&last_to_expire) + { + if (last_to_expire == nullptr) + last_to_expire = entry; + else if (last_to_expire->length == 0) + { + // favor older bans if they're also permanent + if (entry->length == 0 && entry->timestamp < last_to_expire->timestamp) + last_to_expire = entry; + } + else if (entry->length == 0 || entry->timestamp + entry->length > last_to_expire->timestamp + last_to_expire->length) + last_to_expire = entry; + }; + for (size_t i = 0; i != entries.size(); i++) { entry = entries.get(i); - if (entry->active) + if (entry->is_active()) { if (entry->length != 0 && entry->timestamp + entry->length < time(0)) banDatabase->deactivate(i); - else if ((this->localSteamBan && entry->steamid != 0 && entry->steamid == player->steamid) - || (this->localIPBan && entry->ip != 0 && entry->ip == player->ip32) - || (this->localRDNSBan && entry->rdns.isNotEmpty() && entry->rdns.equals(player->rdns)) - || (this->localNameBan && entry->name.isNotEmpty() && entry->name.equalsi(player->name))) + else { - char timeStr[256]; - if (entry->length == 0) - { - strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(&(entry->timestamp))); - this->forceKickPlayer(player, Jupiter::StringS::Format("You are were permanently banned from the server on %s for: %.*s", timeStr, entry->reason.size(), entry->reason.ptr())); - } + if (entry->prefix_length >= 32) + netmask = 0xFFFFFFFF; else + netmask = Jupiter_prefix_length_to_netmask(entry->prefix_length); + + if ((this->localSteamBan && entry->steamid != 0 && entry->steamid == player->steamid) + || (this->localIPBan && entry->ip != 0 && (entry->ip & netmask) == (player->ip32 & netmask)) + || (this->localRDNSBan && entry->rdns.isNotEmpty() && entry->rdns.equals(player->rdns)) + || (this->localNameBan && entry->name.isNotEmpty() && entry->name.equalsi(player->name))) + { + player->ban_flags |= entry->flags; + if (entry->is_type_game()) + handle_type(last_to_expire[0]); + if (entry->is_type_chat()) + handle_type(last_to_expire[1]); + if (entry->is_type_bot()) + handle_type(last_to_expire[2]); + if (entry->is_type_vote()) + handle_type(last_to_expire[3]); + if (entry->is_type_mine()) + handle_type(last_to_expire[4]); + if (entry->is_type_ladder()) + handle_type(last_to_expire[5]); + if (entry->is_type_alert()) + handle_type(last_to_expire[6]); + } + } + } + } + + char timeStr[256]; + if (last_to_expire[0] != nullptr) // Game ban + { + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[0]->timestamp + last_to_expire[0]->length))); + if (last_to_expire[0]->length == 0) + this->forceKickPlayer(player, Jupiter::StringS::Format("You were permanently banned from the server on %s for: %.*s", timeStr, last_to_expire[0]->reason.size(), last_to_expire[0]->reason.ptr())); + else + this->forceKickPlayer(player, Jupiter::StringS::Format("You are banned from the server until %s for: %.*s", timeStr, last_to_expire[0]->reason.size(), last_to_expire[0]->reason.ptr())); + + player->ban_flags |= RenX::BanDatabase::Entry::FLAG_TYPE_BOT; // implies FLAG_TYPE_BOT + } + else + { + if (last_to_expire[1] != nullptr) // Chat ban + { + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[1]->timestamp + last_to_expire[1]->length))); + this->mute(player); + if (last_to_expire[1]->length == 0) + this->sendMessage(player, Jupiter::StringS::Format("You were permanently muted on this server on %s for: %.*s", timeStr, last_to_expire[1]->reason.size(), last_to_expire[1]->reason.ptr())); + else + this->sendMessage(player, Jupiter::StringS::Format("You are muted on this server until %s for: %.*s", timeStr, last_to_expire[1]->reason.size(), last_to_expire[1]->reason.ptr())); + + player->ban_flags |= RenX::BanDatabase::Entry::FLAG_TYPE_BOT; // implies FLAG_TYPE_BOT + } + else if (last_to_expire[2] != nullptr) // Bot ban + { + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[2]->timestamp + last_to_expire[2]->length))); + if (last_to_expire[2]->length == 0) + this->sendMessage(player, Jupiter::StringS::Format("You were permanently bot-muted on this server on %s for: %.*s", timeStr, last_to_expire[2]->reason.size(), last_to_expire[2]->reason.ptr())); + else + this->sendMessage(player, Jupiter::StringS::Format("You are bot-muted on this server until %s for: %.*s", timeStr, last_to_expire[2]->reason.size(), last_to_expire[2]->reason.ptr())); + } + if (last_to_expire[3] != nullptr) // Vote ban + { + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[3]->timestamp + last_to_expire[3]->length))); + if (last_to_expire[3]->length == 0) + this->sendMessage(player, Jupiter::StringS::Format("You were permanently vote-muted on this server on %s for: %.*s", timeStr, last_to_expire[3]->reason.size(), last_to_expire[3]->reason.ptr())); + else + this->sendMessage(player, Jupiter::StringS::Format("You are vote-muted on this server until %s for: %.*s", timeStr, last_to_expire[3]->reason.size(), last_to_expire[3]->reason.ptr())); + } + if (last_to_expire[4] != nullptr) // Mine ban + { + this->mineBan(player); + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[4]->timestamp + last_to_expire[4]->length))); + if (last_to_expire[4]->length == 0) + this->sendMessage(player, Jupiter::StringS::Format("You were permanently mine-banned on this server on %s for: %.*s", timeStr, last_to_expire[4]->reason.size(), last_to_expire[4]->reason.ptr())); + else + this->sendMessage(player, Jupiter::StringS::Format("You are mine-banned on this server until %s for: %.*s", timeStr, last_to_expire[4]->reason.size(), last_to_expire[4]->reason.ptr())); + } + if (last_to_expire[5] != nullptr) // Ladder ban + { + strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(last_to_expire[5]->timestamp + last_to_expire[5]->length))); + if (last_to_expire[5]->length == 0) + this->sendMessage(player, Jupiter::StringS::Format("You were permanently ladder-banned on this server on %s for: %.*s", timeStr, last_to_expire[5]->reason.size(), last_to_expire[5]->reason.ptr())); + else + this->sendMessage(player, Jupiter::StringS::Format("You are ladder-banned on this server until %s for: %.*s", timeStr, last_to_expire[5]->reason.size(), last_to_expire[5]->reason.ptr())); + } + if (last_to_expire[6] != nullptr) // Alert + { + unsigned int serverCount = serverManager->size(); + IRC_Bot *server; + Jupiter::IRC::Client::Channel *channel; + unsigned int channelCount; + Jupiter::String &fmtName = RenX::getFormattedPlayerName(player); + Jupiter::StringL msg = Jupiter::StringL::Format(IRCCOLOR "04[Alert] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR " is marked for monitoring by %.*s for: \"%.*s\". Please keep an eye on them in ", fmtName.size(), fmtName.ptr(), last_to_expire[6]->banner.size(), last_to_expire[6]->banner.ptr(), last_to_expire[6]->reason.size(), last_to_expire[6]->reason.ptr()); + Jupiter::StringS msg2 = Jupiter::StringS::Format(IRCCOLOR "04[Alert] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR " is marked for monitoring by %.*s for: \"%.*s\"." IRCCOLOR, fmtName.size(), fmtName.ptr(), last_to_expire[6]->banner.size(), last_to_expire[6]->banner.ptr(), last_to_expire[6]->reason.size(), last_to_expire[6]->reason.ptr()); + for (unsigned int a = 0; a < serverCount; a++) + { + server = serverManager->getServer(a); + channelCount = server->getChannelCount(); + for (unsigned int b = 0; b < channelCount; b++) { - strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof(entry->timestamp + entry->length))); - this->forceKickPlayer(player, Jupiter::StringS::Format("You are banned from the server until %s for: %.*s", timeStr, entry->reason.size(), entry->reason.ptr())); + channel = server->getChannel(b); + if (this->isAdminLogChanType(channel->getType())) + { + server->sendMessage(channel->getName(), msg2); + msg += channel->getName(); + for (unsigned int c = 0; c < channel->getUserCount(); c++) + if (channel->getUserPrefix(c) != 0 && channel->getUser(c)->getNickname().equals(server->getNickname()) == false) + server->sendMessage(channel->getUser(c)->getUser()->getNickname(), msg); + msg -= channel->getName().size(); + } } - return; } } } @@ -2329,6 +2452,10 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) playerToken = tokens.getToken(5); RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerToken); + + if ((player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_VOTE) != 0) + RenX::Server::sendData(Jupiter::StringS::Format("ccancelvote %.*s\n", teamToken.size(), teamToken.ptr())); + for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnVoteCall(this, team, voteType, player, parameters); onAction(); diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h index 8a842c7..f96ebb2 100644 --- a/RenX.Core/RenX_Server.h +++ b/RenX.Core/RenX_Server.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -339,7 +339,7 @@ namespace RenX * * @param id Player ID of the player to ban. */ - void banPlayer(int id, const Jupiter::ReadableString &reason); + void banPlayer(int id, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason); /** * @brief Bans a player from the server. @@ -347,7 +347,7 @@ namespace RenX * @param player Data of the player to ban. * @param length Duration of the ban (0 for permanent). */ - void banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length = 0); + void banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, time_t length = 0); /** * @brief Removes a player's data based on their ID number. diff --git a/RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp b/RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp index 372504a..293e389 100644 --- a/RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp +++ b/RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,6 +24,8 @@ #include "RenX_PlayerInfo.h" #include "RenX_Functions.h" +using namespace Jupiter::literals; + RenX_ExcessiveHeadshotsPlugin::RenX_ExcessiveHeadshotsPlugin() { RenX_ExcessiveHeadshotsPlugin::OnRehash(); @@ -31,18 +33,18 @@ RenX_ExcessiveHeadshotsPlugin::RenX_ExcessiveHeadshotsPlugin() int RenX_ExcessiveHeadshotsPlugin::OnRehash() { - RenX_ExcessiveHeadshotsPlugin::ratio = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), STRING_LITERAL_AS_REFERENCE("HeadshotKillRatio"), 0.5); - RenX_ExcessiveHeadshotsPlugin::minKills = Jupiter::IRC::Client::Config->getInt(RenX_ExcessiveHeadshotsPlugin::getName(), STRING_LITERAL_AS_REFERENCE("Kills"), 10); - RenX_ExcessiveHeadshotsPlugin::minKD = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), STRING_LITERAL_AS_REFERENCE("KillDeathRatio"), 5.0); - RenX_ExcessiveHeadshotsPlugin::minKPS = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), STRING_LITERAL_AS_REFERENCE("KillsPerSecond"), 0.5); - RenX_ExcessiveHeadshotsPlugin::minFlags = Jupiter::IRC::Client::Config->getInt(RenX_ExcessiveHeadshotsPlugin::getName(), STRING_LITERAL_AS_REFERENCE("Flags"), 4); + RenX_ExcessiveHeadshotsPlugin::ratio = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), "HeadshotKillRatio"_jrs, 0.5); + RenX_ExcessiveHeadshotsPlugin::minKills = Jupiter::IRC::Client::Config->getInt(RenX_ExcessiveHeadshotsPlugin::getName(), "Kills"_jrs, 10); + RenX_ExcessiveHeadshotsPlugin::minKD = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), "KillDeathRatio"_jrs, 5.0); + RenX_ExcessiveHeadshotsPlugin::minKPS = Jupiter::IRC::Client::Config->getDouble(RenX_ExcessiveHeadshotsPlugin::getName(), "KillsPerSecond"_jrs, 0.5); + RenX_ExcessiveHeadshotsPlugin::minFlags = Jupiter::IRC::Client::Config->getInt(RenX_ExcessiveHeadshotsPlugin::getName(), "Flags"_jrs, 4); return 0; } void RenX_ExcessiveHeadshotsPlugin::RenX_OnKill(RenX::Server *server, const RenX::PlayerInfo *player, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &damageType) { if (player->kills < 3) return; - if (damageType.equals("Rx_DmgType_Headshot")) + if (damageType.equals("Rx_DmgType_Headshot"_jrs)) { unsigned int flags = 0; std::chrono::milliseconds game_time = server->getGameTime(player); @@ -56,7 +58,7 @@ void RenX_ExcessiveHeadshotsPlugin::RenX_OnKill(RenX::Server *server, const RenX if (flags >= RenX_ExcessiveHeadshotsPlugin::minFlags) { - server->banPlayer(player, STRING_LITERAL_AS_REFERENCE("Aimbot detected")); + server->banPlayer(player, "Jupiter Bot"_jrs, "Aimbot detected"_jrs); server->sendPubChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u", player->name.size(), player->name.ptr(), player->kills, player->deaths, player->headshots); const Jupiter::ReadableString &steamid = server->formatSteamID(player); server->sendAdmChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u - IP: " IRCBOLD "%.*s" IRCBOLD " - Steam ID: " IRCBOLD "%.*s" IRCBOLD, player->name.size(), player->name.ptr(), player->kills, player->deaths, player->headshots, player->ip.size(), player->ip.ptr(), steamid.size(), steamid.ptr()); diff --git a/RenX.Ladder/RenX_Ladder.cpp b/RenX.Ladder/RenX_Ladder.cpp index 831366f..c13434c 100644 --- a/RenX.Ladder/RenX_Ladder.cpp +++ b/RenX.Ladder/RenX_Ladder.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Jessica James. + * Copyright (C) 2015-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,6 +21,7 @@ #include "RenX_Ladder.h" #include "RenX_Server.h" #include "RenX_PlayerInfo.h" +#include "RenX_BanDatabase.h" using namespace Jupiter::literals; @@ -49,7 +50,7 @@ void RenX_LadderPlugin::updateLadder(RenX::Server *server, const RenX::TeamType for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next) { player = node->data; - if (player->steamid != 0) + if (player->steamid != 0 && (player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_LADDER) == 0) { entry = RenX_LadderPlugin::database.getPlayerEntry(player->steamid); if (entry == nullptr) diff --git a/RenX.Logging/RenX_Logging.cpp b/RenX.Logging/RenX_Logging.cpp index 54435fe..93cd5be 100644 --- a/RenX.Logging/RenX_Logging.cpp +++ b/RenX.Logging/RenX_Logging.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -110,7 +110,7 @@ void RenX_LoggingPlugin::init() Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD " using Steam ID " IRCBOLD "%.*s" IRCBOLD ". Their hostname is: " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->steamTag.size(), RenX::tags->steamTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr())); RenX_LoggingPlugin::joinNoSteamAdminFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("JoinNoSteamAdminFormat"), - Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD ", but is not using Steam. Their hostname is: " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr())); + Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD ", but is " IRCBOLD "not" IRCBOLD " using Steam. Their hostname is: " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr())); RenX_LoggingPlugin::partFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("PartFormat"), Jupiter::StringS::Format(IRCCOLOR "12[Part] " IRCBOLD "%.*s" IRCBOLD " left the %.*s.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr())); diff --git a/RenX.Warn/RenX_Warn.cpp b/RenX.Warn/RenX_Warn.cpp index 093eb3e..c7f53ee 100644 --- a/RenX.Warn/RenX_Warn.cpp +++ b/RenX.Warn/RenX_Warn.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -77,7 +77,7 @@ void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.ptr(), warns)); break; default: - server->banPlayer(player, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), pluginInstance.warnAction); + server->banPlayer(player, STRING_LITERAL_AS_REFERENCE("Jupiter Bot/RenX.Warn"), Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), pluginInstance.warnAction); source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.ptr(), warns)); break; } @@ -187,7 +187,7 @@ void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co source->sendMessage(player, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns)); break; default: - source->banPlayer(target, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), pluginInstance.warnAction); + source->banPlayer(target, STRING_LITERAL_AS_REFERENCE("Jupiter Bot/RenX.Warn"), Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), pluginInstance.warnAction); source->sendMessage(player, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns)); break; }