diff --git a/Jupiter b/Jupiter
index 94bda33..2132691 160000
--- a/Jupiter
+++ b/Jupiter
@@ -1 +1 @@
-Subproject commit 94bda33c248ef6fd9c0e09ecda6b27184865df6c
+Subproject commit 21326918e9caf39c37d487183801715724908f85
diff --git a/Release/Bot.lib b/Release/Bot.lib
index 0c94a68..c40ec42 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 41da5c7..9a3bc6f 100644
Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ
diff --git a/RenX.Core/RenX.Core.vcxproj b/RenX.Core/RenX.Core.vcxproj
index 87d9cf7..21d663f 100644
--- a/RenX.Core/RenX.Core.vcxproj
+++ b/RenX.Core/RenX.Core.vcxproj
@@ -70,6 +70,7 @@
+
@@ -80,6 +81,7 @@
+
diff --git a/RenX.Core/RenX.Core.vcxproj.filters b/RenX.Core/RenX.Core.vcxproj.filters
index e375b38..24b4e41 100644
--- a/RenX.Core/RenX.Core.vcxproj.filters
+++ b/RenX.Core/RenX.Core.vcxproj.filters
@@ -47,6 +47,9 @@
Header Files
+
+ Header Files
+
@@ -67,5 +70,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/RenX.Core/RenX_BanDatabase.cpp b/RenX.Core/RenX_BanDatabase.cpp
new file mode 100644
index 0000000..8f372cb
--- /dev/null
+++ b/RenX.Core/RenX_BanDatabase.cpp
@@ -0,0 +1,147 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include "Jupiter/IRC_Client.h"
+#include "Jupiter/INIFile.h"
+#include "RenX_PlayerInfo.h"
+#include "RenX_BanDatabase.h"
+#include "RenX_Core.h"
+#include "RenX_Plugin.h"
+
+RenX::BanDatabase _banDatabase;
+RenX::BanDatabase *RenX::banDatabase = &_banDatabase;
+RenX::BanDatabase &RenX::defaultBanDatabase = _banDatabase;
+
+bool RenX::BanDatabase::load(const Jupiter::ReadableString &fname)
+{
+ 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;
+ Entry *entry;
+ char c;
+ while (!feof(file))
+ {
+ entry = new Entry();
+ 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;
+ }
+ c = fgetc(file);
+ while (c != '\n' && c != EOF)
+ {
+ if (c == '\0')
+ {
+ // add plugin data.
+ break;
+ }
+ entry->name += c;
+ c = fgetc(file);
+ }
+ entries.add(entry);
+ }
+ fclose(file);
+ return true;
+ }
+ else
+ {
+ RenX::BanDatabase::version = 0;
+ 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;
+ }
+}
+
+void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player, time_t length)
+{
+ Entry *entry = new Entry();
+ entry->active = 1;
+ entry->timestamp = time(0);
+ entry->length = length;
+ entry->steamid = player->steamid;
+ entry->ip = player->ip32;
+ entry->name = player->name;
+ entries.add(entry);
+
+ FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "ab");
+ if (file != nullptr)
+ {
+ 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);
+ // add plugin data
+ Jupiter::String pluginData;
+ Jupiter::ArrayList &xPlugins = *RenX::getCore()->getPlugins();
+ for (size_t i = 0; i < xPlugins.size(); i++)
+ if (xPlugins.get(i)->RenX_OnBan(server, player, pluginData))
+ {
+ fputc('\0', file);
+ fwrite(xPlugins.get(i)->getName().ptr(), sizeof(char), xPlugins.get(i)->getName().size(), file);
+ fputc('\0', file);
+ fwrite(pluginData.ptr(), sizeof(char), pluginData.size(), file);
+ }
+
+
+ fputc('\n', file);
+ fclose(file);
+ }
+}
+
+uint8_t RenX::BanDatabase::getVersion() const
+{
+ return RenX::BanDatabase::version;
+}
+
+const Jupiter::ReadableString &RenX::BanDatabase::getFileName() const
+{
+ return RenX::BanDatabase::filename;
+}
+
+const Jupiter::ArrayList &RenX::BanDatabase::getEntries() const
+{
+ return RenX::BanDatabase::entries;
+}
+
+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::~BanDatabase()
+{
+ RenX::BanDatabase::entries.emptyAndDelete();
+}
\ No newline at end of file
diff --git a/RenX.Core/RenX_BanDatabase.h b/RenX.Core/RenX_BanDatabase.h
new file mode 100644
index 0000000..491c6eb
--- /dev/null
+++ b/RenX.Core/RenX_BanDatabase.h
@@ -0,0 +1,114 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _RENX_BANDATABASE_H_HEADER
+#define _RENX_BANDATABASE_H_HEADER
+
+#include
+#include
+#include "Jupiter/String.h"
+#include "Jupiter/CString.h"
+#include "Jupiter/ArrayList.h"
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+namespace RenX
+{
+ struct PlayerInfo;
+ class Server;
+
+ /**
+ * @brief Represents the local ban database.
+ */
+ class RENX_API BanDatabase
+ {
+ public:
+ /**
+ * @brief Represents a Ban entry in the database.
+ */
+ struct RENX_API Entry
+ {
+ unsigned char active; /** 1 if the ban is active, 0 otherwise */
+ 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 */;
+ Jupiter::StringS name /** Name of the banned player */;
+ };
+
+ /**
+ * @brief Loads a file into the ban system.
+ * Note: This will generate a database file if none is found.
+ *
+ * @param fname String containing the name of the file to load
+ * @return True on success, false otherwise.
+ */
+ bool load(const Jupiter::ReadableString &fname);
+
+ /**
+ * @param Adds a ban entry for a player 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 length Duration of the ban
+ */
+ void add(RenX::Server *server, const RenX::PlayerInfo *player, time_t length);
+
+ /**
+ * @brief Fetches the version of the database file.
+ *
+ * @return Database version
+ */
+ uint8_t getVersion() const;
+
+ /**
+ * @brief Fetches the name of the database file.
+ *
+ * @return Database file name
+ */
+ const Jupiter::ReadableString &getFileName() const;
+
+ /**
+ * @brief Fetches the list of ban entries.
+ *
+ * @return List of entries
+ */
+ const Jupiter::ArrayList &getEntries() const;
+
+ BanDatabase();
+ ~BanDatabase();
+
+ private:
+ uint8_t version;
+ Jupiter::CStringS filename;
+ Jupiter::ArrayList entries;
+ };
+
+ RENX_API extern RenX::BanDatabase *banDatabase;
+ RENX_API extern RenX::BanDatabase &defaultBanDatabase;
+}
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _RENX_BANDATABASE_H_HEADER
\ No newline at end of file
diff --git a/RenX.Core/RenX_Core.cpp b/RenX.Core/RenX_Core.cpp
index 76be9f7..c1508b7 100644
--- a/RenX.Core/RenX_Core.cpp
+++ b/RenX.Core/RenX_Core.cpp
@@ -40,7 +40,7 @@ RenX::Core::Core()
RenX::Core::translationsFile.readFile(Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("RenX"), STRING_LITERAL_AS_REFERENCE("TranslationsFile"), STRING_LITERAL_AS_REFERENCE("Translations.ini")));
RenX::initTranslations(RenX::Core::translationsFile);
RenX::Core::commandsFile.readFile(Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("RenX"), STRING_LITERAL_AS_REFERENCE("CommandsFile"), STRING_LITERAL_AS_REFERENCE("RenXGameCommands.ini")));
-
+
unsigned int wc = serverList.wordCount(WHITESPACE);
RenX::Server *server;
diff --git a/RenX.Core/RenX_PlayerInfo.h b/RenX.Core/RenX_PlayerInfo.h
index cf4fc75..49423be 100644
--- a/RenX.Core/RenX_PlayerInfo.h
+++ b/RenX.Core/RenX_PlayerInfo.h
@@ -46,6 +46,7 @@ namespace RenX
Jupiter::StringS adminType;
Jupiter::StringS uuid;
uint64_t steamid = 0;
+ uint32_t ip32 = 0;
TeamType team = Other;
int id = 0;
bool isBot = false;
diff --git a/RenX.Core/RenX_Plugin.cpp b/RenX.Core/RenX_Plugin.cpp
index 9d3ec14..797a89e 100644
--- a/RenX.Core/RenX_Plugin.cpp
+++ b/RenX.Core/RenX_Plugin.cpp
@@ -45,6 +45,11 @@ void RenX::Plugin::RenX_OnPlayerDelete(Server *, const RenX::PlayerInfo *)
return;
}
+bool RenX::Plugin::RenX_OnBan(Server *, const RenX::PlayerInfo *, Jupiter::StringType &)
+{
+ return false;
+}
+
void RenX::Plugin::RenX_OnJoin(Server *, const RenX::PlayerInfo *)
{
return;
diff --git a/RenX.Core/RenX_Plugin.h b/RenX.Core/RenX_Plugin.h
index cdae664..ded8d74 100644
--- a/RenX.Core/RenX_Plugin.h
+++ b/RenX.Core/RenX_Plugin.h
@@ -24,6 +24,7 @@
*/
#include "Jupiter/Plugin.h"
+#include "Jupiter/String_Type.h"
#include "RenX.h"
namespace RenX
@@ -40,6 +41,7 @@ namespace RenX
/** Non-RCON RenX logs */
virtual void RenX_OnPlayerCreate(Server *server, const PlayerInfo *player);
virtual void RenX_OnPlayerDelete(Server *server, const PlayerInfo *player);
+ virtual bool RenX_OnBan(Server *server, const PlayerInfo *player, Jupiter::StringType &data);
/** Player type logs */
virtual void RenX_OnJoin(Server *server, const PlayerInfo *player);
diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp
index 11a2990..f2ed0b6 100644
--- a/RenX.Core/RenX_Server.cpp
+++ b/RenX.Core/RenX_Server.cpp
@@ -25,6 +25,7 @@
#include "RenX_GameCommand.h"
#include "RenX_Functions.h"
#include "RenX_Plugin.h"
+#include "RenX_BanDatabase.h"
int RenX::Server::think()
{
@@ -300,24 +301,38 @@ void RenX::Server::kickPlayer(const RenX::PlayerInfo *player)
void RenX::Server::banPlayer(int id)
{
- RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", id));
+ if (RenX::Server::rconBan)
+ RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", id));
+ else
+ {
+ RenX::PlayerInfo *player = RenX::Server::getPlayer(id);
+ if (player != nullptr)
+ RenX::Server::banPlayer(player);
+ }
}
-void RenX::Server::banPlayer(const RenX::PlayerInfo *player)
+void RenX::Server::banPlayer(const RenX::PlayerInfo *player, time_t length)
{
- if (this->profile->pidbug)
+ if (RenX::Server::rconBan && length == 0)
{
- if (player->isBot)
- RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
- else if (player->id < 1000)
- RenX::Server::banPlayer(player->id);
- else if (player->name.contains('|') == false)
- RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
+ if (this->profile->pidbug)
+ {
+ if (player->isBot)
+ RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
+ else if (player->id < 1000)
+ RenX::Server::banPlayer(player->id);
+ else if (player->name.contains('|') == false)
+ RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
+ else
+ RenX::Server::banPlayer(player->id);
+ }
else
- RenX::Server::banPlayer(player->id);
+ RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", player->id));
}
else
- RenX::Server::banPlayer(player->id);
+ RenX::Server::kickPlayer(player);
+ if (RenX::Server::localBan)
+ RenX::banDatabase->add(this, player, length);
}
bool RenX::Server::removePlayer(int id)
@@ -665,6 +680,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
r->joinTime = time(nullptr);
r->steamid = steamid;
r->ip = ip;
+ r->ip32 = Jupiter::Socket::pton4(Jupiter::CStringS(r->ip).c_str());
if (id != 0)
server->players.add(r);
switch (this->uuidMode)
@@ -680,6 +696,24 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
}
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnPlayerCreate(server, r);
+
+ const Jupiter::ArrayList &entries = RenX::banDatabase->getEntries();
+ RenX::BanDatabase::Entry *entry;
+ for (size_t i = 0; i != entries.size(); i++)
+ {
+ entry = entries.get(i);
+ if (entry->active)
+ {
+ if (entry->timestamp + entry->length > time(0))
+ entry->active = false;
+ else if (server->localSteamBan && entry->steamid == r->steamid)
+ server->kickPlayer(r);
+ else if (server->localIPBan && entry->ip == r->ip32)
+ server->kickPlayer(r);
+ else if (server->localNameBan && entry->name.equalsi(r->name))
+ server->kickPlayer(r);
+ }
+ }
}
else if (r->name.size() == 0) r->name = name;
r->team = team;
@@ -990,7 +1024,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
name = playerData.gotoToken(4, CListDelim);
}
- printf("Name: %.*s - ID: %d - isBot: %u - steamid: %llu - ip: %.*s" ENDL, name.size(), name.ptr(), id, isBot, steamid.asUnsignedLongLong(), ip.size(), ip.ptr());
RenX::PlayerInfo *player = getPlayerOrAdd(this, name, id, team, isBot, steamid.asUnsignedLongLong(), ip);
}
else
@@ -1134,6 +1167,11 @@ void RenX::Server::init()
RenX::Server::rules = Jupiter::IRC::Client::Config->get(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("Rules"), STRING_LITERAL_AS_REFERENCE("Anarchy!"));
RenX::Server::delay = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("ReconnectDelay"), 60);
RenX::Server::uuidMode = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("UUIDMode"), 0);
+ RenX::Server::rconBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("RCONBan"), false);
+ RenX::Server::localSteamBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("LocalSteamBan"), true);
+ RenX::Server::localIPBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("LocalIPBan"), true);
+ RenX::Server::localNameBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("LocalNameBan"), false);
+ RenX::Server::localBan = RenX::Server::localIPBan || RenX::Server::localSteamBan || RenX::Server::localNameBan;
RenX::Server::steamFormat = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("SteamFormat"), 16);
RenX::Server::neverSay = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("NeverSay"), false);
diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h
index 9705adb..9d76fcb 100644
--- a/RenX.Core/RenX_Server.h
+++ b/RenX.Core/RenX_Server.h
@@ -23,6 +23,7 @@
* @brief Defines the Server class.
*/
+#include
#include "Jupiter/TCPSocket.h"
#include "Jupiter/DLList.h"
#include "Jupiter/ArrayList.h"
@@ -257,8 +258,9 @@ namespace RenX
* @brief Bans a player from the server.
*
* @param player Data of the player to ban.
+ * @param length Duration of the ban (0 for permanent).
*/
- void banPlayer(const RenX::PlayerInfo *player);
+ void banPlayer(const RenX::PlayerInfo *player, time_t length = 0);
/**
* @brief Removes a player's data based on their ID number.
@@ -523,6 +525,11 @@ namespace RenX
time_t delay;
int steamFormat; /** 16 = hex, 10 = base 10, 8 = octal, -2 = SteamID 2, -3 = SteamID 3 */
unsigned int uuidMode; /** 0 = steam, 1 = nickname */
+ bool rconBan;
+ bool localBan;
+ bool localSteamBan;
+ bool localIPBan;
+ bool localNameBan;
bool neverSay;
Jupiter::TCPSocket sock;
Jupiter::CStringS clientHostname;