diff --git a/Jupiter b/Jupiter
index d8dd8de..a5f0625 160000
--- a/Jupiter
+++ b/Jupiter
@@ -1 +1 @@
-Subproject commit d8dd8dea5465e209083e423cbec8b7df1ad5cf59
+Subproject commit a5f06257535dcabecdc074af3f3591179e1bbfdc
diff --git a/Jupiter Bot.sln b/Jupiter Bot.sln
index 0eea142..bd777fa 100644
--- a/Jupiter Bot.sln
+++ b/Jupiter Bot.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bot", "Bot\Bot.vcxproj", "{C188871B-5F32-4946-B301-24CA2EBB275D}"
EndProject
@@ -151,6 +151,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.HybridUUID", "RenX.Hyb
{9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Listen", "RenX.Listen\RenX.Listen.vcxproj", "{DA05D8B5-5E24-410E-A201-CC5905E327D3}"
+ 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
@@ -261,6 +267,10 @@ Global
{FF61361F-CB09-4C72-80E2-9CA2DA63910E}.Debug|Win32.Build.0 = Debug|Win32
{FF61361F-CB09-4C72-80E2-9CA2DA63910E}.Release|Win32.ActiveCfg = Release|Win32
{FF61361F-CB09-4C72-80E2-9CA2DA63910E}.Release|Win32.Build.0 = Release|Win32
+ {DA05D8B5-5E24-410E-A201-CC5905E327D3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DA05D8B5-5E24-410E-A201-CC5905E327D3}.Debug|Win32.Build.0 = Debug|Win32
+ {DA05D8B5-5E24-410E-A201-CC5905E327D3}.Release|Win32.ActiveCfg = Release|Win32
+ {DA05D8B5-5E24-410E-A201-CC5905E327D3}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Release/Bot.lib b/Release/Bot.lib
index 5cf68bd..c955f56 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 427603b..1e31821 100644
Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ
diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp
index 55b3e50..37a577b 100644
--- a/RenX.Core/RenX_Server.cpp
+++ b/RenX.Core/RenX_Server.cpp
@@ -31,12 +31,17 @@ int RenX::Server::think()
{
if (RenX::Server::connected == false)
{
- if (time(0) >= RenX::Server::lastAttempt + RenX::Server::delay)
+ if (RenX::Server::maxAttempts < 0 || RenX::Server::attempts < RenX::Server::maxAttempts)
{
- if (RenX::Server::connect())
- RenX::Server::sendLogChan(IRCCOLOR "03[RenX]" IRCCOLOR " Socket successfully reconnected to Renegade-X server.");
- else RenX::Server::sendLogChan(IRCCOLOR "04[Error]" IRCCOLOR " Failed to reconnect to Renegade-X server.");
+ if (time(0) >= RenX::Server::lastAttempt + RenX::Server::delay)
+ {
+ if (RenX::Server::connect())
+ RenX::Server::sendLogChan(IRCCOLOR "03[RenX]" IRCCOLOR " Socket successfully reconnected to Renegade-X server.");
+ else RenX::Server::sendLogChan(IRCCOLOR "04[Error]" IRCCOLOR " Failed to reconnect to Renegade-X server.");
+ }
}
+ else
+ return 1;
}
else
{
@@ -61,11 +66,19 @@ int RenX::Server::think()
else if (Jupiter::Socket::getLastError() != 10035) // This is a serious error
{
RenX::Server::wipeData();
- RenX::Server::sendLogChan(IRCCOLOR "07[Warning]" IRCCOLOR " Connection to Renegade-X server lost. Reconnection attempt in progress.");
- if (RenX::Server::reconnect())
- RenX::Server::sendLogChan(IRCCOLOR "06[Progress]" IRCCOLOR " Connection to Renegade-X server reestablished. Initializing Renegade-X RCON protocol...");
+ if (RenX::Server::maxAttempts != 0)
+ {
+ RenX::Server::sendLogChan(IRCCOLOR "07[Warning]" IRCCOLOR " Connection to Renegade-X server lost. Reconnection attempt in progress.");
+ if (RenX::Server::reconnect())
+ RenX::Server::sendLogChan(IRCCOLOR "06[Progress]" IRCCOLOR " Connection to Renegade-X server reestablished. Initializing Renegade-X RCON protocol...");
+ else
+ RenX::Server::sendLogChan(IRCCOLOR "04[Error]" IRCCOLOR " Connection to Renegade-X server lost. Reconnection attempt failed.");
+ }
else
- RenX::Server::sendLogChan(IRCCOLOR "04[Error]" IRCCOLOR " Connection to Renegade-X server lost. Reconnection attempt failed.");
+ {
+ RenX::Server::sendLogChan(IRCCOLOR "04[Error]" IRCCOLOR " Connection to Renegade-X server lost. No attempt will be made to reconnect.");
+ return 1;
+ }
return 0;
}
if (RenX::Server::rconVersion >= 3 && std::chrono::steady_clock::now() > RenX::Server::lastClientListUpdate + RenX::Server::clientUpdateRate)
@@ -503,6 +516,16 @@ unsigned short RenX::Server::getPort() const
return RenX::Server::port;
}
+const Jupiter::ReadableString &RenX::Server::getSocketHostname() const
+{
+ return RenX::Server::sock.getHostname();
+}
+
+unsigned short RenX::Server::getSocketPort() const
+{
+ return RenX::Server::sock.getPort();
+}
+
time_t RenX::Server::getLastAttempt() const
{
return RenX::Server::lastAttempt;
@@ -2200,6 +2223,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
if (this->rconVersion >= 3)
{
+ RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("s\n"));
RenX::Server::send(STRING_LITERAL_AS_REFERENCE("map"));
RenX::Server::fetchClientList();
@@ -2250,16 +2274,17 @@ void RenX::Server::disconnect()
bool RenX::Server::connect()
{
RenX::Server::lastAttempt = time(0);
- if (RenX::Server::sock.connectToHost(RenX::Server::hostname.c_str(), RenX::Server::port, RenX::Server::clientHostname.isEmpty() ? nullptr : RenX::Server::clientHostname.c_str()))
+ if (RenX::Server::sock.connect(RenX::Server::hostname.c_str(), RenX::Server::port, RenX::Server::clientHostname.isEmpty() ? nullptr : RenX::Server::clientHostname.c_str()))
{
RenX::Server::sock.setBlocking(false);
RenX::Server::sock.send(Jupiter::StringS::Format("a%.*s\n", RenX::Server::pass.size(), RenX::Server::pass.ptr()));
- RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("s\n"));
RenX::Server::connected = true;
RenX::Server::silenceParts = false;
+ RenX::Server::attempts = 0;
return true;
}
RenX::Server::connected = false;
+ ++RenX::Server::attempts;
return false;
}
@@ -2292,6 +2317,14 @@ const Jupiter::ReadableString &RenX::Server::getRCONUsername() const
return RenX::Server::rconUser;
}
+RenX::Server::Server(Jupiter::Socket &&socket, const Jupiter::ReadableString &configurationSection) : Server(configurationSection)
+{
+ RenX::Server::sock = std::move(socket);
+ RenX::Server::sock.send(Jupiter::StringS::Format("a%.*s\n", RenX::Server::pass.size(), RenX::Server::pass.ptr()));
+ RenX::Server::connected = true;
+ RenX::Server::silenceParts = false;
+}
+
RenX::Server::Server(const Jupiter::ReadableString &configurationSection)
{
RenX::Server::configSection = configurationSection;
@@ -2317,6 +2350,7 @@ 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"), 10);
+ RenX::Server::maxAttempts = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("MaxReconnectAttempts"), -1);
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);
diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h
index 7e7e8ca..1635d11 100644
--- a/RenX.Core/RenX_Server.h
+++ b/RenX.Core/RenX_Server.h
@@ -519,6 +519,20 @@ namespace RenX
*/
unsigned short getPort() const;
+ /**
+ * @brief Fetches the hostname from the server socket.
+ *
+ * @return String containing the hostname of the server.
+ */
+ const Jupiter::ReadableString &getSocketHostname() const;
+
+ /**
+ * @brief Fetches the port from the server socket.
+ *
+ * @return Port of the server.
+ */
+ unsigned short getSocketPort() const;
+
/**
* @brief Fetches the time of the last connection attempt.
* Note: This includes both successful and failed connection attempts.
@@ -734,6 +748,14 @@ namespace RenX
*/
const Jupiter::ReadableString &getRCONUsername() const;
+ /**
+ * @brief Creates a server object using the provided socket, and loads settings from the specified configuration section.
+ *
+ * @param socket Initialized Socket to use for the connection
+ * @param configurationSection Configuration section to load from.
+ */
+ Server(Jupiter::Socket &&socket, const Jupiter::ReadableString &configurationSection);
+
/**
* @brief Creates the Server object, and loads settings from the specified configuration section.
*
@@ -762,6 +784,7 @@ namespace RenX
bool firstAction = false;
unsigned int rconVersion = 0;
time_t lastAttempt = 0;
+ int attempts = 0;
std::chrono::steady_clock::time_point lastClientListUpdate = std::chrono::steady_clock::now();
Jupiter::String lastLine;
Jupiter::StringS commandListFormat;
@@ -773,6 +796,7 @@ namespace RenX
int logChanType;
int adminLogChanType;
time_t delay;
+ int maxAttempts;
std::chrono::milliseconds clientUpdateRate;
int steamFormat; /** 16 = hex, 10 = base 10, 8 = octal, -2 = SteamID 2, -3 = SteamID 3 */
bool rconBan;
diff --git a/RenX.Listen/RenX.Listen.vcxproj b/RenX.Listen/RenX.Listen.vcxproj
new file mode 100644
index 0000000..348d222
--- /dev/null
+++ b/RenX.Listen/RenX.Listen.vcxproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {DA05D8B5-5E24-410E-A201-CC5905E327D3}
+ PluginExample
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v140
+ 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.Listen/RenX.Listen.vcxproj.filters b/RenX.Listen/RenX.Listen.vcxproj.filters
new file mode 100644
index 0000000..2c7667e
--- /dev/null
+++ b/RenX.Listen/RenX.Listen.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.Listen/RenX_Listen.cpp b/RenX.Listen/RenX_Listen.cpp
new file mode 100644
index 0000000..7568955
--- /dev/null
+++ b/RenX.Listen/RenX_Listen.cpp
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2015 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 "Jupiter/IRC_Client.h"
+#include "Jupiter/INIFile.h"
+#include "Jupiter/CString.h"
+#include "RenX_Listen.h"
+#include "RenX_Core.h"
+#include "RenX_Server.h"
+
+RenX_ListenPlugin::~RenX_ListenPlugin()
+{
+ RenX_ListenPlugin::socket.closeSocket();
+}
+
+bool RenX_ListenPlugin::init()
+{
+ uint16_t port = Jupiter::IRC::Client::Config->getInt(this->getName(), STRING_LITERAL_AS_REFERENCE("Port"), 13372);
+ const Jupiter::ReadableString &address = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("Address"), STRING_LITERAL_AS_REFERENCE("0.0.0.0"));
+ RenX_ListenPlugin::serverSection = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("ServerSection"), this->getName());
+ return RenX_ListenPlugin::socket.bind(Jupiter::CStringS(address).c_str(), port, true) && RenX_ListenPlugin::socket.setBlocking(false);
+}
+
+int RenX_ListenPlugin::think()
+{
+ Jupiter::Socket *sock = socket.accept();
+ if (sock != nullptr)
+ {
+ sock->setBlocking(false);
+ RenX::Server *server = new RenX::Server(std::move(*sock), RenX_ListenPlugin::serverSection);
+ printf("Incoming server connected from " IRCCOLOR "12%.*s:%u", server->getSocketHostname().size(), server->getSocketHostname().ptr(), server->getSocketPort());
+ server->sendLogChan("Incoming server connected from " IRCCOLOR "12%.*s:%u", server->getSocketHostname().size(), server->getSocketHostname().ptr(), server->getSocketPort());
+ RenX::getCore()->addServer(server);
+ delete sock;
+ }
+ return 0;
+}
+
+int RenX_ListenPlugin::OnRehash()
+{
+ uint16_t port = Jupiter::IRC::Client::Config->getInt(this->getName(), STRING_LITERAL_AS_REFERENCE("Port"), 13372);
+ const Jupiter::ReadableString &address = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("Address"), STRING_LITERAL_AS_REFERENCE("0.0.0.0"));
+ RenX_ListenPlugin::serverSection = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("ServerSection"), this->getName());
+ if (port != RenX_ListenPlugin::socket.getPort() || address.equals(RenX_ListenPlugin::socket.getHostname()) == false)
+ {
+ puts("Notice: The Renegade-X listening socket has been changed!");
+ RenX_ListenPlugin::socket.closeSocket();
+ return RenX_ListenPlugin::socket.bind(Jupiter::CStringS(address).c_str(), port, true) == false || RenX_ListenPlugin::socket.setBlocking(false) == false;
+ }
+ return 0;
+}
+
+// Plugin instantiation and entry point.
+RenX_ListenPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) bool load()
+{
+ return pluginInstance.init();
+}
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/RenX.Listen/RenX_Listen.h b/RenX.Listen/RenX_Listen.h
new file mode 100644
index 0000000..5cccae2
--- /dev/null
+++ b/RenX.Listen/RenX_Listen.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2015 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 _EXAMPLE_H_HEADER
+#define _EXAMPLE_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Reference_String.h"
+#include "Jupiter/TCPSocket.h"
+#include "RenX_Plugin.h"
+
+class RenX_ListenPlugin : public RenX::Plugin
+{
+public: // RenX::Plugin
+
+public: // Jupiter::Plugin
+ const Jupiter::ReadableString &getName() override { return name; }
+ int think() override;
+ int OnRehash();
+
+public: // RenX_ListenPlugin
+ bool init();
+ ~RenX_ListenPlugin();
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Listen");
+ Jupiter::TCPSocket socket;
+ Jupiter::StringS serverSection;
+};
+
+#endif // _EXAMPLE_H_HEADER
\ No newline at end of file