Browse Source

Added reasons to kicks and bans.

RenX::BanDataBase:
* Added "reason" parameter to add()
* Added reason to Entry
* Added write() functions
* Version number incremented
RenX::Server:
* Added "reason" parameter to kickPlayer() and banPlayer() functions.
* Added forceKickPlayer() function
Adjusted plugins to above changes.
pull/3/head
JustinAJ 9 years ago
parent
commit
50e96e6ebe
  1. BIN
      Release/Plugins/RenX.Core.lib
  2. 61
      RenX.Commands/RenX_Commands.cpp
  3. 108
      RenX.Core/RenX_BanDatabase.cpp
  4. 18
      RenX.Core/RenX_BanDatabase.h
  5. 81
      RenX.Core/RenX_Server.cpp
  6. 22
      RenX.Core/RenX_Server.h
  7. 2
      RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp
  8. 2
      RenX.ModSystem/RenX_ModSystem.cpp
  9. 8
      RenX.Warn/RenX_Warn.cpp

BIN
Release/Plugins/RenX.Core.lib

Binary file not shown.

61
RenX.Commands/RenX_Commands.cpp

@ -39,7 +39,8 @@ inline bool togglePhasing(RenX::Server *server)
inline void onDie(RenX::Server *server, const RenX::PlayerInfo *player) inline void onDie(RenX::Server *server, const RenX::PlayerInfo *player)
{ {
if (player->isBot && server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false)) server->kickPlayer(player); if (player->isBot && server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false))
server->kickPlayer(player, Jupiter::StringS::empty);
} }
bool RenX_CommandsPlugin::RenX_OnBan(RenX::Server *server, const RenX::PlayerInfo *player, Jupiter::StringType &data) bool RenX_CommandsPlugin::RenX_OnBan(RenX::Server *server, const RenX::PlayerInfo *player, Jupiter::StringType &data)
@ -1517,16 +1518,18 @@ void KickIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
RenX::Server *server; RenX::Server *server;
unsigned int kicks = 0; unsigned int kicks = 0;
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
for (size_t i = 0; i != servers.size(); i++) for (size_t i = 0; i != servers.size(); i++)
{ {
server = servers.get(i); server = servers.get(i);
if (server != nullptr) if (server != nullptr)
{ {
player = server->getPlayerByPartName(parameters); player = server->getPlayerByPartName(name);
if (player != nullptr) if (player != nullptr)
{ {
server->kickPlayer(player); server->kickPlayer(player, reason);
kicks++; ++kicks;
} }
} }
} }
@ -1535,12 +1538,12 @@ void KickIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
} }
} }
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Kick <Player>")); else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Kick <Player> [Reason]"));
} }
const Jupiter::ReadableString &KickIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &KickIRCCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: Kick <Player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: Kick <Player> [Reason]");
return defaultHelp; return defaultHelp;
} }
@ -1569,6 +1572,8 @@ void TempBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
RenX::Server *server; RenX::Server *server;
unsigned int kicks = 0; unsigned int kicks = 0;
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
Jupiter::String banner(nick.size() + 4); Jupiter::String banner(nick.size() + 4);
banner += nick; banner += nick;
banner += "@IRC"; banner += "@IRC";
@ -1577,11 +1582,11 @@ void TempBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
server = servers.get(i); server = servers.get(i);
if (server != nullptr) if (server != nullptr)
{ {
player = server->getPlayerByPartName(parameters); player = server->getPlayerByPartName(name);
if (player != nullptr) if (player != nullptr)
{ {
player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick); player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick);
server->banPlayer(player, pluginInstance.getTBanTime()); server->banPlayer(player, reason, pluginInstance.getTBanTime());
kicks++; kicks++;
} }
} }
@ -1591,12 +1596,12 @@ void TempBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
} }
} }
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: TempBan <Player>")); else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: TempBan <Player> [Reason]"));
} }
const Jupiter::ReadableString &TempBanIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &TempBanIRCCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: TempBan <Player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: TempBan <Player> [Reason]");
return defaultHelp; return defaultHelp;
} }
@ -1625,6 +1630,8 @@ void KickBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
RenX::Server *server; RenX::Server *server;
unsigned int kicks = 0; unsigned int kicks = 0;
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
Jupiter::String banner(nick.size() + 4); Jupiter::String banner(nick.size() + 4);
banner += nick; banner += nick;
banner += "@IRC"; banner += "@IRC";
@ -1637,7 +1644,7 @@ void KickBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
if (player != nullptr) if (player != nullptr)
{ {
player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick); player->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), nick);
server->banPlayer(player); server->banPlayer(player, reason);
kicks++; kicks++;
} }
} }
@ -1647,12 +1654,12 @@ void KickBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
} }
} }
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: KickBan <Player>")); else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: KickBan <Player> [Reason]"));
} }
const Jupiter::ReadableString &KickBanIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &KickBanIRCCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: KickBan <Player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: KickBan <Player> [Reason]");
return defaultHelp; return defaultHelp;
} }
@ -2412,7 +2419,9 @@ void KickGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
{ {
if (parameters.isEmpty() == false) if (parameters.isEmpty() == false)
{ {
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
RenX::PlayerInfo *target = source->getPlayerByPartName(name);
if (target == nullptr) if (target == nullptr)
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
else if (player == target) else if (player == target)
@ -2421,17 +2430,17 @@ void KickGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not kick higher level moderators.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not kick higher level moderators."));
else else
{ {
source->kickPlayer(target); source->kickPlayer(target, reason);
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been kicked from the game.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been kicked from the game."));
} }
} }
else else
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: kick <player>")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: kick <player> [Reason]"));
} }
const Jupiter::ReadableString &KickGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &KickGameCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: kick <player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: kick <player> [Reason]");
return defaultHelp; return defaultHelp;
} }
@ -2451,7 +2460,9 @@ void TempBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
{ {
if (parameters.isEmpty() == false) if (parameters.isEmpty() == false)
{ {
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
RenX::PlayerInfo *target = source->getPlayerByPartName(name);
if (target == nullptr) if (target == nullptr)
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
else if (player == target) else if (player == target)
@ -2461,17 +2472,17 @@ void TempBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
else else
{ {
target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name); target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name);
source->banPlayer(target, pluginInstance.getTBanTime()); source->banPlayer(target, reason, pluginInstance.getTBanTime());
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been temporarily banned and kicked from the game.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been temporarily banned and kicked from the game."));
} }
} }
else else
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: tban <player>")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: tban <player> [Reason]"));
} }
const Jupiter::ReadableString &TempBanGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &TempBanGameCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: tban <player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: tban <player> [Reason]");
return defaultHelp; return defaultHelp;
} }
@ -2492,6 +2503,8 @@ void KickBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
{ {
if (parameters.isEmpty() == false) if (parameters.isEmpty() == false)
{ {
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
if (target == nullptr) if (target == nullptr)
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
@ -2502,17 +2515,17 @@ void KickBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
else else
{ {
target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name); target->varData.set(pluginInstance.getName(), STRING_LITERAL_AS_REFERENCE("banner"), player->name);
source->banPlayer(target); source->banPlayer(target, reason);
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been banned and kicked from the game.")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been banned and kicked from the game."));
} }
} }
else else
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: ban <player>")); source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: ban <player> [reason]"));
} }
const Jupiter::ReadableString &KickBanGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &KickBanGameCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: ban <player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: ban <player> [reason]");
return defaultHelp; return defaultHelp;
} }

108
RenX.Core/RenX_BanDatabase.cpp

@ -27,6 +27,9 @@ RenX::BanDatabase _banDatabase;
RenX::BanDatabase *RenX::banDatabase = &_banDatabase; RenX::BanDatabase *RenX::banDatabase = &_banDatabase;
RenX::BanDatabase &RenX::defaultBanDatabase = _banDatabase; RenX::BanDatabase &RenX::defaultBanDatabase = _banDatabase;
const Jupiter::ReferenceString DEFAULT_REASON = "(No reason information provided)";
const uint8_t write_version = 1;
bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname) bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
{ {
RenX::BanDatabase::filename = fname; RenX::BanDatabase::filename = fname;
@ -40,6 +43,9 @@ bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
Jupiter::String playerName(16); Jupiter::String playerName(16);
Jupiter::String key(32); Jupiter::String key(32);
Jupiter::String value(32); Jupiter::String value(32);
Jupiter::String reason(128);
if (RenX::BanDatabase::version < 1)
reason = DEFAULT_REASON;
Entry *entry; Entry *entry;
int c; int c;
while (!feof(file)) while (!feof(file))
@ -72,6 +78,24 @@ bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
} }
entry->name = playerName; 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 // load variable data
while (c == '\0') while (c == '\0')
{ {
@ -109,11 +133,23 @@ bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
entries.add(entry); entries.add(entry);
} }
fclose(file); fclose(file);
if (RenX::BanDatabase::version != write_version)
{
file = fopen(RenX::BanDatabase::filename.c_str(), "wb");
if (file != nullptr)
{
size_t index = 0;
while (index != RenX::BanDatabase::entries.size())
RenX::BanDatabase::write(RenX::BanDatabase::entries.get(++index), file);
}
fprintf(stdout, "Updated BanDatabase file \"%s\" from version %d to %d.", RenX::BanDatabase::filename.c_str(), RenX::BanDatabase::version, write_version);
RenX::BanDatabase::version = write_version;
}
return true; return true;
} }
else else
{ {
RenX::BanDatabase::version = 0; RenX::BanDatabase::version = write_version;
file = fopen(RenX::BanDatabase::filename.c_str(), "ab"); file = fopen(RenX::BanDatabase::filename.c_str(), "ab");
if (file != nullptr) if (file != nullptr)
{ {
@ -126,7 +162,39 @@ bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
} }
} }
void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player, time_t length) void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry)
{
FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "ab");
if (file != nullptr)
{
RenX::BanDatabase::write(entry, file);
fclose(file);
}
}
void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry, FILE *file)
{
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->name.ptr(), sizeof(char), entry->name.size(), file);
for (size_t index = 0; index != entry->varData.size(); ++index)
{
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);
}
fputc('\n', file);
}
void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length)
{ {
Entry *entry = new Entry(); Entry *entry = new Entry();
entry->active = 1; entry->active = 1;
@ -135,36 +203,16 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player
entry->steamid = player->steamid; entry->steamid = player->steamid;
entry->ip = player->ip32; entry->ip = player->ip32;
entry->name = player->name; entry->name = player->name;
entries.add(entry);
FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "ab"); // add plugin data
if (file != nullptr) Jupiter::String pluginData;
{ Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins();
fgetpos(file, &entry->pos); for (size_t i = 0; i < xPlugins.size(); i++)
fwrite(&entry->active, 1, 1, file); if (xPlugins.get(i)->RenX_OnBan(server, player, pluginData))
fwrite(&entry->timestamp, sizeof(time_t), 1, file); entry->varData.set(xPlugins.get(i)->getName(), pluginData);
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->name.ptr(), sizeof(char), entry->name.size(), file);
// add plugin data
Jupiter::String pluginData;
Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins();
for (size_t i = 0; i < xPlugins.size(); i++)
if (xPlugins.get(i)->RenX_OnBan(server, player, pluginData))
{
const Jupiter::ReadableString &pluginName = xPlugins.get(i)->getName();
fputc('\0', file);
fwrite(pluginName.ptr(), sizeof(char), pluginName.size(), file);
fputc('\0', file);
fwrite(pluginData.ptr(), sizeof(char), pluginData.size(), file);
entry->varData.set(pluginName, pluginData);
}
entries.add(entry);
fputc('\n', file); RenX::BanDatabase::write(entry);
fclose(file);
}
} }
bool RenX::BanDatabase::deactivate(size_t index) bool RenX::BanDatabase::deactivate(size_t index)

18
RenX.Core/RenX_BanDatabase.h

@ -53,6 +53,7 @@ namespace RenX
uint64_t steamid /** SteamID of the banned player */; uint64_t steamid /** SteamID of the banned player */;
uint32_t ip /** IPv4 address of the banned player */; uint32_t ip /** IPv4 address of the banned player */;
Jupiter::StringS name /** Name of the banned player */; Jupiter::StringS name /** Name of the banned player */;
Jupiter::StringS reason /** Reason the player was banned */;
Jupiter::INIFile::Section varData; /** Variable entry data */ Jupiter::INIFile::Section varData; /** Variable entry data */
}; };
@ -72,7 +73,22 @@ namespace RenX
* @param player Data of the player to be banned * @param player Data of the player to be banned
* @param length Duration of the ban * @param length Duration of the ban
*/ */
void add(RenX::Server *server, const RenX::PlayerInfo *player, time_t length); void add(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length);
/**
* @brief Writes a ban file to the database.
*
* @param entry Entry to write to the database.
*/
void write(Entry *entry);
/**
* @brief Writes a ban file to the database.
*
* @param entry Entry to write to the database.
* @param file FILE stream to write to.
*/
static void write(Entry *entry, FILE *file);
/** /**
* @brief Deactivates a ban entry. * @brief Deactivates a ban entry.

81
RenX.Core/RenX_Server.cpp

@ -278,37 +278,58 @@ Jupiter::StringS RenX::Server::formatSteamID(uint64_t id) const
} }
} }
void RenX::Server::kickPlayer(int id) void RenX::Server::kickPlayer(int id, const Jupiter::ReadableString &reason)
{ {
RenX::Server::sock.send(Jupiter::StringS::Format("ckick pid%d\n", id)); if (reason.isEmpty())
RenX::Server::sock.send(Jupiter::StringS::Format("ckick pid%d\n", id));
else
RenX::Server::sock.send(Jupiter::StringS::Format("ckick pid%d %.*s\n", id, reason.size(), reason.ptr()));
}
void RenX::Server::kickPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason)
{
RenX::Server::kickPlayer(player->id, reason);
}
void RenX::Server::forceKickPlayer(int id, const Jupiter::ReadableString &reason)
{
if (reason.isEmpty())
RenX::Server::sock.send(Jupiter::StringS::Format("cfkick pid%d You were kicked from the server.\n", id));
else
RenX::Server::sock.send(Jupiter::StringS::Format("cfkick pid%d %.*s\n", id, reason.size(), reason.ptr()));
} }
void RenX::Server::kickPlayer(const RenX::PlayerInfo *player) void RenX::Server::forceKickPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason)
{ {
RenX::Server::kickPlayer(player->id); RenX::Server::forceKickPlayer(player->id, reason);
} }
void RenX::Server::banPlayer(int id) void RenX::Server::banPlayer(int id, const Jupiter::ReadableString &reason)
{ {
if (RenX::Server::rconBan) if (RenX::Server::rconBan)
RenX::Server::sock.send(Jupiter::StringS::Format("ckickban pid%d\n", id)); RenX::Server::sock.send(Jupiter::StringS::Format("ckickban pid%d %.*s\n", id, reason.size(), reason.ptr()));
else else
{ {
RenX::PlayerInfo *player = RenX::Server::getPlayer(id); RenX::PlayerInfo *player = RenX::Server::getPlayer(id);
if (player != nullptr) if (player != nullptr)
RenX::Server::banPlayer(player); RenX::Server::banPlayer(player, reason);
} }
} }
void RenX::Server::banPlayer(const RenX::PlayerInfo *player, time_t length) void RenX::Server::banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length)
{ {
if (RenX::Server::rconBan && length == 0)
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", player->id));
else
RenX::Server::kickPlayer(player);
if (RenX::Server::localBan) if (RenX::Server::localBan)
RenX::banDatabase->add(this, player, length); RenX::banDatabase->add(this, player, 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
RenX::Server::forceKickPlayer(player, Jupiter::StringS::Format("You are permanently banned from the server for: %.*s", 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/3600, length%3600, length/60, length%60, reason.size(), reason.ptr()));
} }
bool RenX::Server::removePlayer(int id) bool RenX::Server::removePlayer(int id)
@ -906,7 +927,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
auto banCheck = [this](const RenX::PlayerInfo *player) auto banCheck = [this](const RenX::PlayerInfo *player)
{ {
const Jupiter::ArrayList<RenX::BanDatabase::Entry> &entries = RenX::banDatabase->getEntries(); const Jupiter::ArrayList<RenX::BanDatabase::Entry> &entries = RenX::banDatabase->getEntries();
RenX::BanDatabase::Entry *entry; RenX::BanDatabase::Entry *entry = nullptr;
for (size_t i = 0; i != entries.size(); i++) for (size_t i = 0; i != entries.size(); i++)
{ {
entry = entries.get(i); entry = entries.get(i);
@ -914,15 +935,25 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
{ {
if (entry->length != 0 && entry->timestamp + entry->length < time(0)) if (entry->length != 0 && entry->timestamp + entry->length < time(0))
banDatabase->deactivate(i); banDatabase->deactivate(i);
else if (this->localSteamBan && entry->steamid != 0 && entry->steamid == player->steamid) else if ((this->localSteamBan && entry->steamid != 0 && entry->steamid == player->steamid)
return true; || (this->localIPBan && entry->ip != 0 && entry->ip == player->ip32)
else if (this->localIPBan && entry->ip != 0 && entry->ip == player->ip32) || (this->localNameBan && entry->name.isEmpty() == false && entry->name.equalsi(player->name)))
return true; {
else if (this->localNameBan && entry->name.isEmpty() == false && entry->name.equalsi(player->name)) char timeStr[256];
return true; 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()));
}
else
{
strftime(timeStr, sizeof(timeStr), "%b %d %Y at %H:%M:%S", localtime(std::addressof<const time_t>(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()));
}
return;
}
} }
} }
return false;
}; };
auto getPlayerOrAdd = [&](const Jupiter::ReadableString &name, int id, RenX::TeamType team, bool isBot, uint64_t steamid, const Jupiter::ReadableString &ip) auto getPlayerOrAdd = [&](const Jupiter::ReadableString &name, int id, RenX::TeamType team, bool isBot, uint64_t steamid, const Jupiter::ReadableString &ip)
{ {
@ -971,8 +1002,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
if (recalcUUID) if (recalcUUID)
{ {
this->setUUIDIfDifferent(r, calc_uuid(r)); this->setUUIDIfDifferent(r, calc_uuid(r));
if (banCheck(r)) banCheck(r);
this->kickPlayer(r);
} }
} }
return r; return r;
@ -1868,8 +1898,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
if (player != nullptr) if (player != nullptr)
{ {
player->id = buff.getToken(3, RenX::DelimC).asInt(); player->id = buff.getToken(3, RenX::DelimC).asInt();
if (banCheck(player)) banCheck(player);
this->kickPlayer(player);
for (size_t i = 0; i < xPlugins.size(); i++) for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnIDChange(this, player, oldID); xPlugins.get(i)->RenX_OnIDChange(this, player, oldID);
} }

22
RenX.Core/RenX_Server.h

@ -244,21 +244,35 @@ namespace RenX
* *
* @param id Player ID of the player to kick. * @param id Player ID of the player to kick.
*/ */
void kickPlayer(int id); void kickPlayer(int id, const Jupiter::ReadableString &reason);
/** /**
* @brief Kicks a player from the server. * @brief Kicks a player from the server.
* *
* @param player Data of the player to kick. * @param player Data of the player to kick.
*/ */
void kickPlayer(const RenX::PlayerInfo *player); void kickPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason);
/**
* @brief Kicks a player from the server.
*
* @param id Player ID of the player to kick.
*/
void forceKickPlayer(int id, const Jupiter::ReadableString &reason);
/**
* @brief Kicks a player from the server.
*
* @param player Data of the player to kick.
*/
void forceKickPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason);
/** /**
* @brief Bans a player from the server. * @brief Bans a player from the server.
* *
* @param id Player ID of the player to ban. * @param id Player ID of the player to ban.
*/ */
void banPlayer(int id); void banPlayer(int id, const Jupiter::ReadableString &reason);
/** /**
* @brief Bans a player from the server. * @brief Bans a player from the server.
@ -266,7 +280,7 @@ namespace RenX
* @param player Data of the player to ban. * @param player Data of the player to ban.
* @param length Duration of the ban (0 for permanent). * @param length Duration of the ban (0 for permanent).
*/ */
void banPlayer(const RenX::PlayerInfo *player, time_t length = 0); void banPlayer(const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason, time_t length = 0);
/** /**
* @brief Removes a player's data based on their ID number. * @brief Removes a player's data based on their ID number.

2
RenX.ExcessiveHeadshots/ExcessiveHeadshots.cpp

@ -53,7 +53,7 @@ void RenX_ExcessiveHeadshotsPlugin::RenX_OnKill(RenX::Server *server, const RenX
if (flags >= RenX_ExcessiveHeadshotsPlugin::minFlags) if (flags >= RenX_ExcessiveHeadshotsPlugin::minFlags)
{ {
server->kickPlayer(player); server->banPlayer(player, STRING_LITERAL_AS_REFERENCE("Aimbot detected"));
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); 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); 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()); 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());

2
RenX.ModSystem/RenX_ModSystem.cpp

@ -197,7 +197,7 @@ int RenX_ModSystemPlugin::auth(RenX::Server *server, const RenX::PlayerInfo *pla
} }
else if (kickLockMismatch_l) else if (kickLockMismatch_l)
{ {
server->kickPlayer(player); server->kickPlayer(player, STRING_LITERAL_AS_REFERENCE("Moderator entry lock mismatch"));
return -1; return -1;
} }
} }

8
RenX.Warn/RenX_Warn.cpp

@ -72,11 +72,11 @@ void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha
switch (pluginInstance.warnAction) switch (pluginInstance.warnAction)
{ {
case -1: case -1:
server->kickPlayer(player); server->kickPlayer(player, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns));
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)); 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; break;
default: default:
server->banPlayer(player, pluginInstance.warnAction); server->banPlayer(player, 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)); 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; break;
} }
@ -182,11 +182,11 @@ void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
switch (pluginInstance.warnAction) switch (pluginInstance.warnAction)
{ {
case -1: case -1:
source->kickPlayer(target); source->kickPlayer(target, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns));
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)); 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; break;
default: default:
source->banPlayer(target, pluginInstance.warnAction); source->banPlayer(target, 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)); 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; break;
} }

Loading…
Cancel
Save