diff --git a/Jupiter Bot.sln b/Jupiter Bot.sln
index df7ca2c..40d22a9 100644
--- a/Jupiter Bot.sln
+++ b/Jupiter Bot.sln
@@ -127,6 +127,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.ModSystem", "RenX.ModS
{9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Warn", "RenX.Warn\RenX.Warn.vcxproj", "{41C67B8B-D84D-42C2-B174-200B2ACB19C0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -221,6 +227,10 @@ Global
{160CD71B-1E13-4816-9977-8BBD73871F31}.Debug|Win32.Build.0 = Debug|Win32
{160CD71B-1E13-4816-9977-8BBD73871F31}.Release|Win32.ActiveCfg = Release|Win32
{160CD71B-1E13-4816-9977-8BBD73871F31}.Release|Win32.Build.0 = Release|Win32
+ {41C67B8B-D84D-42C2-B174-200B2ACB19C0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {41C67B8B-D84D-42C2-B174-200B2ACB19C0}.Debug|Win32.Build.0 = Debug|Win32
+ {41C67B8B-D84D-42C2-B174-200B2ACB19C0}.Release|Win32.ActiveCfg = Release|Win32
+ {41C67B8B-D84D-42C2-B174-200B2ACB19C0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RenX.Warn/RenX.Warn.vcxproj b/RenX.Warn/RenX.Warn.vcxproj
new file mode 100644
index 0000000..5676bc8
--- /dev/null
+++ b/RenX.Warn/RenX.Warn.vcxproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {41C67B8B-D84D-42C2-B174-200B2ACB19C0}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter;../RenX.Core
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RenX.Warn/RenX.Warn.vcxproj.filters b/RenX.Warn/RenX.Warn.vcxproj.filters
new file mode 100644
index 0000000..56f02df
--- /dev/null
+++ b/RenX.Warn/RenX.Warn.vcxproj.filters
@@ -0,0 +1,38 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/RenX.Warn/RenX_Warn.cpp b/RenX.Warn/RenX_Warn.cpp
new file mode 100644
index 0000000..3c96713
--- /dev/null
+++ b/RenX.Warn/RenX_Warn.cpp
@@ -0,0 +1,251 @@
+/**
+ * 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 "IRC_Bot.h"
+#include "RenX_Server.h"
+#include "RenX_PlayerInfo.h"
+#include "RenX_Warn.h"
+
+int RenX_WarnPlugin::OnRehash()
+{
+ RenX_WarnPlugin::maxWarns = Jupiter::IRC::Client::Config->getInt(RenX_WarnPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MaxWarns"), 3);
+ RenX_WarnPlugin::warnAction = Jupiter::IRC::Client::Config->getInt(RenX_WarnPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MaxAction"), -1);
+ return 0;
+}
+
+RenX_WarnPlugin::RenX_WarnPlugin()
+{
+ this->OnRehash();
+}
+
+// Plugin instantiation and entry point.
+RenX_WarnPlugin pluginInstance;
+
+STRING_LITERAL_AS_NAMED_REFERENCE(WARNS_KEY, "w");
+
+// Warn IRC Command
+
+void WarnIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("warn"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("w"));
+ this->setAccessLevel(2);
+}
+
+void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ Jupiter::ArrayList servers = RenX::getCore()->getServers(chan->getType());
+ if (servers.size() != 0)
+ {
+ RenX::PlayerInfo *player;
+ RenX::Server *server;
+ for (size_t i = 0; i != servers.size(); i++)
+ {
+ server = servers.get(i);
+ if (server != nullptr)
+ {
+ player = server->getPlayerByPartName(parameters);
+ if (player != nullptr)
+ {
+ int warns = player->varData.getInt(pluginInstance.getName(), WARNS_KEY) + 1;
+ if (warns > pluginInstance.maxWarns)
+ {
+ switch (pluginInstance.warnAction)
+ {
+ case -1:
+ server->kickPlayer(player);
+ 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, 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;
+ }
+ }
+ else
+ {
+ player->varData.set(pluginInstance.getName(), WARNS_KEY, Jupiter::StringS::Format("%d", warns));
+ server->sendMessage(player, Jupiter::StringS::Format("You have been warned by %.*s@IRC; improve your behavior, or you will be disciplined. You have %d warnings.", nick.size(), nick.ptr(), warns));
+ source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", player->name.size(), player->name.ptr(), warns));
+ }
+ }
+ }
+ }
+ }
+ 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: Warn "));
+}
+
+const Jupiter::ReadableString &WarnIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(WarnIRCCommand)
+
+// Pardon IRC Command
+
+void PardonIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pardon"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("forgive"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("unwarn"));
+ this->setAccessLevel(2);
+}
+
+void PardonIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ Jupiter::ArrayList servers = RenX::getCore()->getServers(chan->getType());
+ if (servers.size() != 0)
+ {
+ RenX::PlayerInfo *player;
+ RenX::Server *server;
+ for (size_t i = 0; i != servers.size(); i++)
+ {
+ server = servers.get(i);
+ if (server != nullptr)
+ {
+ player = server->getPlayerByPartName(parameters);
+ if (player != nullptr)
+ {
+ player->varData.remove(pluginInstance.getName(), WARNS_KEY);
+ server->sendMessage(player, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", nick.size(), nick.ptr()));
+ source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", player->name.size(), player->name.ptr()));
+ }
+ }
+ }
+ }
+ else
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ }
+ else
+ this->trigger(source, channel, nick, nick);
+}
+
+const Jupiter::ReadableString &PardonIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(PardonIRCCommand)
+
+// Warn Game Command
+
+void WarnGameCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("warn"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("w"));
+ this->setAccessLevel(1);
+}
+
+void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
+ if (target != nullptr)
+ {
+ int warns = target->varData.getInt(pluginInstance.getName(), WARNS_KEY) + 1;
+ if (warns > pluginInstance.maxWarns)
+ {
+ switch (pluginInstance.warnAction)
+ {
+ case -1:
+ source->kickPlayer(target);
+ 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, 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;
+ }
+ }
+ else
+ {
+ target->varData.set(pluginInstance.getName(), WARNS_KEY, Jupiter::StringS::Format("%d", warns));
+ source->sendMessage(target, Jupiter::StringS::Format("You have been warned by %.*s; improve your behavior, or you will be disciplined. You have %d warnings.", player->name.size(), player->name.ptr(), warns));
+ source->sendMessage(player, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", target->name.size(), target->name.ptr(), warns));
+ }
+ }
+ }
+ else
+ source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: Warn "));
+}
+
+const Jupiter::ReadableString &WarnGameCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(WarnGameCommand)
+
+// Pardon Game Command
+
+void PardonGameCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pardon"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("forgive"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("unwarn"));
+ this->setAccessLevel(1);
+}
+
+void PardonGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
+ if (target != nullptr)
+ {
+ target->varData.remove(pluginInstance.getName(), WARNS_KEY);
+ source->sendMessage(target, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", player->name.size(), player->name.ptr()));
+ source->sendMessage(player, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", target->name.size(), target->name.ptr()));
+ }
+ }
+ else
+ this->trigger(source, player, player->name);
+}
+
+const Jupiter::ReadableString &PardonGameCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(PardonGameCommand)
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/RenX.Warn/RenX_Warn.h b/RenX.Warn/RenX_Warn.h
new file mode 100644
index 0000000..8582607
--- /dev/null
+++ b/RenX.Warn/RenX_Warn.h
@@ -0,0 +1,45 @@
+/**
+ * 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_WARN_H_HEADER
+#define _RENX_WARN_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Reference_String.h"
+#include "IRC_Command.h"
+#include "RenX_Plugin.h"
+#include "RenX_GameCommand.h"
+
+class RenX_WarnPlugin : public RenX::Plugin
+{
+public: // Jupiter::Plugin
+ const Jupiter::ReadableString &getName() override { return name; }
+ int OnRehash() override;
+ RenX_WarnPlugin();
+
+ int maxWarns;
+ int warnAction; /** -1 = kick; 0 = perm ban; other = temp ban */
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX_TemplatePlugin");
+};
+
+GENERIC_IRC_COMMAND(WarnIRCCommand)
+GENERIC_IRC_COMMAND(PardonIRCCommand)
+GENERIC_GAME_COMMAND(WarnGameCommand)
+GENERIC_GAME_COMMAND(PardonGameCommand)
+
+#endif // _RENX_WARN_H_HEADER
\ No newline at end of file