diff --git a/cbp/ModIRC.cbp b/cbp/ModIRC.cbp
index dc466e07..9431fb36 100644
--- a/cbp/ModIRC.cbp
+++ b/cbp/ModIRC.cbp
@@ -16,6 +16,7 @@
+
@@ -37,6 +38,7 @@
+
@@ -59,6 +61,7 @@
+
@@ -81,6 +84,7 @@
+
@@ -183,6 +187,7 @@
+
@@ -208,6 +213,7 @@
+
@@ -234,6 +240,7 @@
+
@@ -260,6 +267,7 @@
+
@@ -370,7 +378,10 @@
+
+
+
diff --git a/modules/irc/Common.cpp b/modules/irc/Common.cpp
index 006fe12a..d024fb1f 100644
--- a/modules/irc/Common.cpp
+++ b/modules/irc/Common.cpp
@@ -2,15 +2,76 @@
#include "Common.hpp"
#include "Module.hpp"
+// ------------------------------------------------------------------------------------------------
+#include
+
+// ------------------------------------------------------------------------------------------------
+#include
+
// ------------------------------------------------------------------------------------------------
#include
#include
// ------------------------------------------------------------------------------------------------
-static SQChar g_Buffer[512];
+namespace SqMod {
// ------------------------------------------------------------------------------------------------
-namespace SqMod {
+static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
+
+// ------------------------------------------------------------------------------------------------
+SStr GetTempBuff()
+{
+ return g_Buffer;
+}
+
+// ------------------------------------------------------------------------------------------------
+Uint32 GetTempBuffSize()
+{
+ return sizeof(g_Buffer);
+}
+
+// ------------------------------------------------------------------------------------------------
+void SqThrowF(CSStr str, ...)
+{
+ // Initialize the argument list
+ va_list args;
+ va_start (args, str);
+ // Write the requested contents
+ if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
+ strcpy(g_Buffer, "Unknown error has occurred");
+ // Release the argument list
+ va_end(args);
+ // Throw the exception with the resulted message
+ throw Sqrat::Exception(g_Buffer);
+}
+
+// ------------------------------------------------------------------------------------------------
+CSStr FmtStr(CSStr str, ...)
+{
+ // Initialize the argument list
+ va_list args;
+ va_start (args, str);
+ // Write the requested contents
+ if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
+ g_Buffer[0] = 0; /* make sure the string is terminated */
+ // Release the argument list
+ va_end(args);
+ // Return the data from the buffer
+ return g_Buffer;
+}
+
+// ------------------------------------------------------------------------------------------------
+StackGuard::StackGuard(HSQUIRRELVM vm)
+ : m_Top(sq_gettop(vm)), m_VM(vm)
+{
+ /* ... */
+}
+
+// ------------------------------------------------------------------------------------------------
+StackGuard::~StackGuard()
+{
+ sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
+}
// ------------------------------------------------------------------------------------------------
CSStr GetNick(CSStr origin)
diff --git a/modules/irc/Common.hpp b/modules/irc/Common.hpp
index 07d06155..715257be 100644
--- a/modules/irc/Common.hpp
+++ b/modules/irc/Common.hpp
@@ -4,6 +4,12 @@
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
+// ------------------------------------------------------------------------------------------------
+extern "C" {
+ struct SQVM;
+ typedef struct SQVM* HSQUIRRELVM;
+} /*extern "C"*/
+
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -25,6 +31,70 @@ namespace SqMod {
*/
class Session;
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the temporary buffer.
+*/
+SStr GetTempBuff();
+
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the size of the temporary buffer.
+*/
+Uint32 GetTempBuffSize();
+
+/* ------------------------------------------------------------------------------------------------
+ * Throw a formatted exception.
+*/
+void SqThrowF(CSStr str, ...);
+
+/* ------------------------------------------------------------------------------------------------
+ * Generate a formatted string.
+*/
+CSStr FmtStr(CSStr str, ...);
+
+/* ------------------------------------------------------------------------------------------------
+ * Implements RAII to restore the VM stack to it's initial size on function exit.
+*/
+struct StackGuard
+{
+ /* --------------------------------------------------------------------------------------------
+ * Base constructor.
+ */
+ StackGuard(HSQUIRRELVM vm);
+
+ /* --------------------------------------------------------------------------------------------
+ * Destructor.
+ */
+ ~StackGuard();
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor.
+ */
+ StackGuard(const StackGuard &);
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor.
+ */
+ StackGuard(StackGuard &&);
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator.
+ */
+ StackGuard & operator = (const StackGuard &);
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator.
+ */
+ StackGuard & operator = (StackGuard &&);
+
+private:
+
+ // --------------------------------------------------------------------------------------------
+ Int32 m_Top; /* The top of the stack when this instance was created. */
+ HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
+};
+
/* ------------------------------------------------------------------------------------------------
* Extract the name from the specified origin.
*/
diff --git a/modules/irc/Module.cpp b/modules/irc/Module.cpp
index a177aec1..6eeb48b1 100644
--- a/modules/irc/Module.cpp
+++ b/modules/irc/Module.cpp
@@ -186,7 +186,7 @@ void RegisterAPI(HSQUIRRELVM vm)
.Ctor()
/* Core Metamethods */
.Func(_SC("_cmp"), &Session::Cmp)
- .Func(_SC("_typename"), &Session::Typename)
+ .SquirrelFunc(_SC("_typename"), &Session::Typename)
.Func(_SC("_tostring"), &Session::ToString)
/* Properties */
.Prop(_SC("Valid"), &Session::IsValid)
diff --git a/modules/irc/Session.cpp b/modules/irc/Session.cpp
index 8259a745..33186cd5 100644
--- a/modules/irc/Session.cpp
+++ b/modules/irc/Session.cpp
@@ -24,6 +24,14 @@ Session* Session::s_Session = NULL;
// ------------------------------------------------------------------------------------------------
Session::Sessions Session::s_Sessions;
+// ------------------------------------------------------------------------------------------------
+SQInteger Session::Typename(HSQUIRRELVM vm)
+{
+ static SQChar name[] = _SC("SqIrcSession");
+ sq_pushstring(vm, name, sizeof(name));
+ return 1;
+}
+
// ------------------------------------------------------------------------------------------------
void Session::Process()
{
@@ -199,43 +207,41 @@ void Session::Destroy()
}
// ------------------------------------------------------------------------------------------------
-bool Session::Validate() const
-{
- if (m_Session)
- return true;
- // Invalid session instance
- _SqMod->SqThrow("Invalid IRC session (%s)", m_Tag.c_str());
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Session::ConnectedThrow() const
+void Session::Validate() const
{
+ // Do we have a valid session handle?
if (!m_Session)
- _SqMod->SqThrow("Invalid IRC session (%s)", m_Tag.c_str());
- else if (!irc_is_connected(m_Session))
- _SqMod->SqThrow("Session is not connected (%s)", m_Tag.c_str());
- else
- return true;
- return false;
+ SqThrowF("Invalid IRC session");
}
// ------------------------------------------------------------------------------------------------
-bool Session::NotConnected() const
+void Session::ValidateConnection() const
{
- if (!m_Session || !irc_is_connected(m_Session) || !m_Reconnect)
- return true;
- _SqMod->SqThrow("Already connected or trying connect to IRC server (%s)", m_Tag.c_str());
- return !m_Session;
+ // Do we have a valid session handle?
+ if (!m_Session)
+ SqThrowF("Invalid IRC session");
+ // Is the session connected?
+ else if (!irc_is_connected(m_Session))
+ SqThrowF("Session is not connected");
+}
+
+// ------------------------------------------------------------------------------------------------
+void Session::IsNotConnected() const
+{
+ // Do we have a session that is not connected or trying to connect?
+ if (m_Session && (irc_is_connected(m_Session) || m_Reconnect))
+ SqThrowF("Already connected or trying connect to IRC server");
}
// ------------------------------------------------------------------------------------------------
bool Session::ValidateEventSession(Session * ptr)
{
+ // Is the session instance valid?
if (ptr)
return true;
- // Invalid session instance
+ // We can't throw an error here so we simply log it
_SqMod->LogErr("Cannot forward IRC event without a session container");
+ // Invalid session instance
return false;
}
@@ -260,9 +266,10 @@ Session::Session()
{
if (!m_Session)
{
- _SqMod->SqThrow("Unable to create an IRC session");
// Explicitly make sure no further calls can be made to this session
m_Session = NULL;
+ // Now it's safe to throw the error
+ SqThrowF("Unable to create an IRC session");
}
else
{
@@ -270,26 +277,18 @@ Session::Session()
irc_set_ctx(m_Session, this);
// Is this the only session instance?
if (!s_Session && s_Sessions.empty())
- {
s_Session = this;
- }
+ // Is this the second session instance?
else if (s_Sessions.empty())
{
s_Sessions.push_back(s_Session);
s_Session = NULL;
s_Sessions.push_back(this);
}
+ // This is part of multiple session instances
else
- {
s_Sessions.push_back(this);
- }
}
- // Because Sqrat is majorly stupid and clears the error message
- // then does an assert on debug builds thinking the type wasn't registered
- // or throws a generic "unknown error" message on release builds
- // we have to use this approach
- if (Sqrat::Error::Occurred(_SqVM))
- _SqMod->LogErr("%s", Sqrat::Error::Message(_SqVM).c_str());
}
// ------------------------------------------------------------------------------------------------
@@ -309,260 +308,233 @@ Session::~Session()
// ------------------------------------------------------------------------------------------------
void Session::SetNick(CSStr nick)
{
+ // Validate the handle
+ Validate();
+ // Validate the specified nick name
if (!nick || strlen(nick) <= 0)
- _SqMod->SqThrow("Invalid IRC nickname");
+ SqThrowF("Invalid IRC nickname");
+ // Do we have to issue a nickname command?
else if (Connected())
irc_cmd_nick(m_Session, nick);
- else if (Validate())
+ // Simply save the specified nickname
+ else
m_Nick.assign(nick);
}
// ------------------------------------------------------------------------------------------------
void Session::SetPort(Uint32 num)
{
+ // The port cannot be changed once connected!
+ IsNotConnected();
+ // Validate the specified port number
if (num > 0xFFFF)
- _SqMod->SqThrow("Port number is out of range: %u > %u", num, 0xFFFF);
- else if (Validate() && NotConnected())
- m_Port = num;
+ SqThrowF("Port number is out of range: %u > %u", num, 0xFFFF);
+ // Assign the specified port number
+ m_Port = num;
}
// ------------------------------------------------------------------------------------------------
Int32 Session::CmdNick(CSStr nick)
{
+ // Make sure the session is connected
+ ValidateConnection();
+ // Validate the specified nick name
if (!nick || strlen(nick) <= 0)
- _SqMod->SqThrow("Invalid IRC nickname");
- else if (ConnectedThrow())
- return irc_cmd_nick(m_Session, nick);
- return -1;
+ SqThrowF("Invalid IRC nickname");
+ // Issue the command and return the result
+ return irc_cmd_nick(m_Session, nick);
}
// ------------------------------------------------------------------------------------------------
Object Session::GetNextTry() const
{
// Obtain the initial stack size
- const Int32 top = sq_gettop(_SqVM);
+ const StackGuard sg(_SqVM);
// Attempt to push a time-stamp instance on the stack
_SqMod->PushTimestamp(_SqVM, m_NextTry);
- // Obtain the object from the stack
- Var< Object > inst(_SqVM, -1);
- // Remove an pushed values (if any) to restore the stack
- sq_pop(_SqVM, sq_gettop(_SqVM) - top);
- // Return the timestamp instance
- return inst.value;
+ // Obtain the object from the stack and return it
+ return Var< Object >(_SqVM, -1).value;
}
// ------------------------------------------------------------------------------------------------
void Session::SetNextTry(Object & tm)
{
// Obtain the initial stack size
- const Int32 top = sq_gettop(_SqVM);
+ const StackGuard sg(_SqVM);
// Push the specified object onto the stack
Var< Object >::push(_SqVM, tm);
// The resulted times-tamp value
Int64 microseconds = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetTimestamp(_SqVM, -1, µseconds)))
- _SqMod->SqThrow("Invalid time-stamp specified");
- else
- m_NextTry = microseconds;
- // Remove an pushed values (if any) to restore the stack
- sq_pop(_SqVM, sq_gettop(_SqVM) - top);
+ SqThrowF("Invalid time-stamp specified");
+ // Assign the specified timestamp value
+ m_NextTry = microseconds;
}
// ------------------------------------------------------------------------------------------------
Object Session::GetSessionTime() const
{
// Obtain the initial stack size
- const Int32 top = sq_gettop(_SqVM);
+ const StackGuard sg(_SqVM);
// Attempt to push a time-stamp instance on the stack
if (m_SessionTime)
_SqMod->PushTimestamp(_SqVM, _SqMod->GetEpochTimeMicro() - m_SessionTime);
+ // This session was not connected yet
else
_SqMod->PushTimestamp(_SqVM, 0);
- // Obtain the object from the stack
- Var< Object > inst(_SqVM, -1);
- // Remove an pushed values (if any) to restore the stack
- sq_pop(_SqVM, sq_gettop(_SqVM) - top);
- // Return the timestamp instance
- return inst.value;
+ // Obtain the object from the stack and return it
+ return Var< Object >(_SqVM, -1).value;
}
// ------------------------------------------------------------------------------------------------
Int32 Session::Connect()
{
- // Are we even allowed to try to connect?
- if (!Validate() || !NotConnected())
- return -1; /* No point in going forward */
- // Did we already try to connect?
- else if (m_Reconnect)
- _SqMod->SqThrow("Attempting to connect IRC while connection was already issued");
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to connect
+ IsNotConnected();
// Validate the specified server
- else if (!m_Server.empty())
- _SqMod->SqThrow("Attempting to connect IRC without specifying a server");
+ if (!m_Server.empty())
+ SqThrowF("Attempting to connect IRC without specifying a server");
// Validate the specified nickname
else if (!m_Nick.empty())
- _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname");
- else
- {
- // Enable the reconnection system
- m_Reconnect = true;
- // Reset the number of tries
- m_LeftTries = m_Tries;
- // Set the time-point for the next try
- m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
- // This is not an IPv6 connection
- m_IPv6 = false;
- // Attempt to connect the session and return the result
- return irc_connect(m_Session, m_Server.c_str(), m_Port,
- m_Passwd.empty() ? NULL : m_Passwd.c_str(),
- m_Nick.c_str(),
- m_User.empty() ? NULL : m_User.c_str(),
- m_Name.empty() ? NULL : m_Name.c_str()
- );
- }
- // Connection denied before even attempted
- return -1;
+ SqThrowF("Attempting to connect IRC without specifying a nickname");
+ // Enable the reconnection system
+ m_Reconnect = true;
+ // Reset the number of tries
+ m_LeftTries = m_Tries;
+ // Set the time-point for the next try
+ m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
+ // This is not an IPv6 connection
+ m_IPv6 = false;
+ // Attempt to connect the session and return the result
+ return irc_connect(m_Session, m_Server.c_str(), m_Port,
+ m_Passwd.empty() ? NULL : m_Passwd.c_str(),
+ m_Nick.c_str(),
+ m_User.empty() ? NULL : m_User.c_str(),
+ m_Name.empty() ? NULL : m_Name.c_str()
+ );
}
// ------------------------------------------------------------------------------------------------
Int32 Session::Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user, CSStr name)
{
- // Are we even allowed to try to connect?
- if (!Validate() || !NotConnected())
- return -1; /* No point in going forward */
- // Did we already try to connect?
- else if (m_Reconnect)
- _SqMod->SqThrow("Attempting to connect IRC while connection was already issued");
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to connect
+ IsNotConnected();
// Validate the specified port
- else if (port > 0xFFFF)
- _SqMod->SqThrow("Port number is out of range: %u > %u", port, 0xFFFF);
+ if (port > 0xFFFF)
+ SqThrowF("Port number is out of range: %u > %u", port, 0xFFFF);
// Validate the specified server
else if (!server || strlen(server) <= 0)
- _SqMod->SqThrow("Attempting to connect IRC without specifying a server");
+ SqThrowF("Attempting to connect IRC without specifying a server");
// Validate the specified nickname
else if (!nick || strlen(nick) <= 0)
- _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname");
- else
- {
- // Save the specified port
- m_Port = port;
- // Save the specified server
- m_Server.assign(server);
- // Save the specified nickname
- m_Nick.assign(nick);
- // Save the specified password
- m_Passwd.assign(!passwd ? _SC("") : passwd);
- // Save the specified user
- m_User.assign(!user ? _SC("") : user);
- // Save the specified name
- m_Name.assign(!name ? _SC("") : name);
- // Enable the reconnection system
- m_Reconnect = true;
- // Reset the number of tries
- m_LeftTries = m_Tries;
- // Set the time-point for the next connection try
- m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
- // This is not an IPv6 connection
- m_IPv6 = false;
- // Attempt to connect the session and return the result
- return irc_connect(m_Session, m_Server.c_str(), m_Port,
- m_Passwd.empty() ? NULL : m_Passwd.c_str(),
- m_Nick.c_str(),
- m_User.empty() ? NULL : m_User.c_str(),
- m_Name.empty() ? NULL : m_Name.c_str()
- );
- }
- // Connection denied before even attempted
- return -1;
+ SqThrowF("Attempting to connect IRC without specifying a nickname");
+ // Save the specified port
+ m_Port = port;
+ // Save the specified server
+ m_Server.assign(server);
+ // Save the specified nickname
+ m_Nick.assign(nick);
+ // Save the specified password
+ m_Passwd.assign(passwd ? passwd : _SC(""));
+ // Save the specified user
+ m_User.assign(user ? user : _SC(""));
+ // Save the specified name
+ m_Name.assign(name ? name : _SC(""));
+ // Enable the reconnection system
+ m_Reconnect = true;
+ // Reset the number of tries
+ m_LeftTries = m_Tries;
+ // Set the time-point for the next connection try
+ m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
+ // This is not an IPv6 connection
+ m_IPv6 = false;
+ // Attempt to connect the session and return the result
+ return irc_connect(m_Session, m_Server.c_str(), m_Port,
+ m_Passwd.empty() ? NULL : m_Passwd.c_str(),
+ m_Nick.c_str(),
+ m_User.empty() ? NULL : m_User.c_str(),
+ m_Name.empty() ? NULL : m_Name.c_str()
+ );
}
// ------------------------------------------------------------------------------------------------
Int32 Session::Connect6()
{
- // Are we even allowed to try to connect?
- if (!Validate() || !NotConnected())
- return -1; /* No point in going forward */
- // Did we already try to connect?
- else if (m_Reconnect)
- _SqMod->SqThrow("Attempting to connect IRC while connection was already issued");
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to connect
+ IsNotConnected();
// Validate the specified server
- else if (!m_Server.empty())
- _SqMod->SqThrow("Attempting to connect IRC without specifying a server");
+ if (!m_Server.empty())
+ SqThrowF("Attempting to connect IRC without specifying a server");
// Validate the specified nickname
else if (!m_Nick.empty())
- _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname");
- else
- {
- // Enable the reconnection system
- m_Reconnect = true;
- // Reset the number of tries
- m_LeftTries = m_Tries;
- // Set the time-point for the next try
- m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
- // This is an IPv6 connection
- m_IPv6 = true;
- // Attempt to connect the session and return the result
- return irc_connect6(m_Session, m_Server.c_str(), m_Port,
- m_Passwd.empty() ? NULL : m_Passwd.c_str(),
- m_Nick.c_str(),
- m_User.empty() ? NULL : m_User.c_str(),
- m_Name.empty() ? NULL : m_Name.c_str()
- );
- }
- // Connection denied before even attempted
- return -1;
+ SqThrowF("Attempting to connect IRC without specifying a nickname");
+ // Enable the reconnection system
+ m_Reconnect = true;
+ // Reset the number of tries
+ m_LeftTries = m_Tries;
+ // Set the time-point for the next try
+ m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
+ // This is an IPv6 connection
+ m_IPv6 = true;
+ // Attempt to connect the session and return the result
+ return irc_connect6(m_Session, m_Server.c_str(), m_Port,
+ m_Passwd.empty() ? NULL : m_Passwd.c_str(),
+ m_Nick.c_str(),
+ m_User.empty() ? NULL : m_User.c_str(),
+ m_Name.empty() ? NULL : m_Name.c_str()
+ );
}
// ------------------------------------------------------------------------------------------------
Int32 Session::Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user, CSStr name)
{
- // Are we even allowed to try to connect?
- if (!Validate() || !NotConnected())
- return -1; /* No point in going forward */
- // Did we already try to connect?
- else if (m_Reconnect)
- _SqMod->SqThrow("Attempting to connect IRC while connection was already issued");
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to connect
+ IsNotConnected();
// Validate the specified port
- else if (port > 0xFFFF)
- _SqMod->SqThrow("Port number is out of range: %u > %u", port, 0xFFFF);
+ if (port > 0xFFFF)
+ SqThrowF("Port number is out of range: %u > %u", port, 0xFFFF);
// Validate the specified server
else if (!server || strlen(server) <= 0)
- _SqMod->SqThrow("Attempting to connect IRC without specifying a server");
+ SqThrowF("Attempting to connect IRC without specifying a server");
// Validate the specified nickname
else if (!nick || strlen(nick) <= 0)
- _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname");
- else
- {
- // Save the specified port
- m_Port = port;
- // Save the specified server
- m_Server.assign(server);
- // Save the specified nickname
- m_Nick.assign(nick);
- // Save the specified password
- m_Passwd.assign(!passwd ? _SC("") : passwd);
- // Save the specified user
- m_User.assign(!user ? _SC("") : user);
- // Save the specified name
- m_Name.assign(!name ? _SC("") : name);
- // Enable the reconnection system
- m_Reconnect = true;
- // Reset the number of tries
- m_LeftTries = m_Tries;
- // Set the time-point for the next connection try
- m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
- // This is an IPv6 connection
- m_IPv6 = true;
- // Attempt to connect the session and return the result
- return irc_connect6(m_Session, m_Server.c_str(), m_Port,
- m_Passwd.empty() ? NULL : m_Passwd.c_str(),
- m_Nick.c_str(),
- m_User.empty() ? NULL : m_User.c_str(),
- m_Name.empty() ? NULL : m_Name.c_str()
- );
- }
- // Connection denied before even attempted
- return -1;
+ SqThrowF("Attempting to connect IRC without specifying a nickname");
+ // Save the specified port
+ m_Port = port;
+ // Save the specified server
+ m_Server.assign(server);
+ // Save the specified nickname
+ m_Nick.assign(nick);
+ // Save the specified password
+ m_Passwd.assign(passwd ? passwd : _SC(""));
+ // Save the specified user
+ m_User.assign(user ? user : _SC(""));
+ // Save the specified name
+ m_Name.assign(name ? name : _SC(""));
+ // Enable the reconnection system
+ m_Reconnect = true;
+ // Reset the number of tries
+ m_LeftTries = m_Tries;
+ // Set the time-point for the next connection try
+ m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL));
+ // This is an IPv6 connection
+ m_IPv6 = true;
+ // Attempt to connect the session and return the result
+ return irc_connect6(m_Session, m_Server.c_str(), m_Port,
+ m_Passwd.empty() ? NULL : m_Passwd.c_str(),
+ m_Nick.c_str(),
+ m_User.empty() ? NULL : m_User.c_str(),
+ m_Name.empty() ? NULL : m_Name.c_str()
+ );
}
// ------------------------------------------------------------------------------------------------
@@ -585,16 +557,12 @@ void Session::ForwardEvent(Session * session, Function & listener, CCStr event,
{
// Is there anyone even listening to this event?
if (listener.IsNull())
- {
return; /* No point in going forward */
- }
// Make sure that the origin can't be a null pointer
else if (!origin)
- {
origin = _SC("");
- }
// Each event must have an array of parameters (empty or not)
- Array parameters(DefaultVM::Get(), count);
+ Array parameters(_SqVM, count);
// Are the any parameters?
if (params && count > 0)
{
@@ -602,10 +570,12 @@ void Session::ForwardEvent(Session * session, Function & listener, CCStr event,
for (Uint32 i = 0; i < count; ++i)
parameters.SetValue(i, params[i]);
}
+ // Obtain the initial stack size
+ const StackGuard sg(_SqVM);
// Obtain an object to this session instance without creating a new reference counter!
- ClassType< Session >::PushInstance(DefaultVM::Get(), session);
+ ClassType< Session >::PushInstance(_SqVM, session);
// Obtain the pushed object from the stack
- Var< Object > var(DefaultVM::Get(), -1);
+ Var< Object > var(_SqVM, -1);
// Call the event with the obtained values
listener.Execute< Object &, CSStr, CSStr, Array & >(var.value, event, origin, parameters);
}
@@ -616,29 +586,25 @@ void Session::ForwardEvent(Session * session, Function & listener, Uint32 event,
{
// Is there anyone even listening to this event?
if (listener.IsNull())
- {
return; /* No point in going forward */
- }
// Make sure that the origin can't be a null pointer
else if (!origin)
- {
origin = _SC("");
- }
// Each event must have an array of parameters (empty or not)
- Array parameters(DefaultVM::Get(), count);
+ Array parameters(_SqVM, count);
// Are the any parameters?
if (params && count > 0)
{
// Transform the parameters into a squirrel array
for (unsigned int i = 0; i < count; ++i)
- {
parameters.SetValue(i, params[i]);
- }
}
+ // Obtain the initial stack size
+ const StackGuard sg(_SqVM);
// Obtain an object to this session instance without creating a new reference counter!
- ClassType< Session >::PushInstance(DefaultVM::Get(), session);
+ ClassType< Session >::PushInstance(_SqVM, session);
// Obtain the pushed object from the stack
- Var< Object > var(DefaultVM::Get(), -1);
+ Var< Object > var(_SqVM, -1);
// Call the event with the obtained values
listener.Execute< Object &, Uint32, CSStr, Array & >(var.value, event, origin, parameters);
}
@@ -840,7 +806,7 @@ void Session::OnDccSendReq(irc_session_t * session, CCStr nick, CCStr addr, CCSt
// ------------------------------------------------------------------------------------------------
SQInteger Session::CmdMsgF(HSQUIRRELVM vm)
{
- // Save the stack top
+ // Obtain the initial stack size
const Int32 top = sq_gettop(vm);
// Do we have a target?
if (top <= 1)
@@ -908,7 +874,7 @@ SQInteger Session::CmdMsgF(HSQUIRRELVM vm)
// ------------------------------------------------------------------------------------------------
SQInteger Session::CmdMeF(HSQUIRRELVM vm)
{
- // Save the stack top
+ // Obtain the initial stack size
const Int32 top = sq_gettop(vm);
// Do we have a target?
if (top <= 1)
@@ -976,7 +942,7 @@ SQInteger Session::CmdMeF(HSQUIRRELVM vm)
// ------------------------------------------------------------------------------------------------
SQInteger Session::CmdNoticeF(HSQUIRRELVM vm)
{
- // Save the stack top
+ // Obtain the initial stack size
const Int32 top = sq_gettop(vm);
// Do we have a target?
if (top <= 1)
diff --git a/modules/irc/Session.hpp b/modules/irc/Session.hpp
index ec821cdc..a0625811 100644
--- a/modules/irc/Session.hpp
+++ b/modules/irc/Session.hpp
@@ -84,7 +84,17 @@ protected:
/* --------------------------------------------------------------------------------------------
* Make sure a valid session exists and throw an error if it doesn't.
*/
- bool Validate() const;
+ void Validate() const;
+
+ /* --------------------------------------------------------------------------------------------
+ * See whether this session is connected to a server and throw an error if not.
+ */
+ void ValidateConnection() const;
+
+ /* --------------------------------------------------------------------------------------------
+ * See whether this session is NOT! connected to a server and throw an error if it is.
+ */
+ void IsNotConnected() const;
/* --------------------------------------------------------------------------------------------
* See whether this session is connected to a server or not.
@@ -94,16 +104,6 @@ protected:
return (m_Session && irc_is_connected(m_Session));
}
- /* --------------------------------------------------------------------------------------------
- * See whether this session is connected to a server and throw an error if not.
- */
- bool ConnectedThrow() const;
-
- /* --------------------------------------------------------------------------------------------
- * See whether this session is NOT! connected to a server and throw an error if it is.
- */
- bool NotConnected() const;
-
/* --------------------------------------------------------------------------------------------
* Validate a session instance used by an event and log an error if it's invalid.
*/
@@ -218,10 +218,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
- CSStr Typename() const
- {
- return _SC("SqIrcSession");
- }
+ static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this session is valid.
@@ -260,8 +257,10 @@ public:
*/
void SetData(Object & data)
{
- if (Validate())
- m_Data = data;
+ // Validate the handle
+ Validate();
+ // Perform the requested operation
+ m_Data = data;
}
/* --------------------------------------------------------------------------------------------
@@ -277,8 +276,12 @@ public:
*/
void SetServer(CSStr server)
{
- if (Validate() && NotConnected())
- m_Server.assign(server);
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to change the server
+ IsNotConnected();
+ // Perform the requested operation
+ m_Server.assign(server);
}
/* --------------------------------------------------------------------------------------------
@@ -293,9 +296,12 @@ public:
* Modify the account password.
*/
void SetPassword(CSStr passwd)
- {
- if (Validate() && NotConnected())
- m_Passwd.assign(passwd);
+ { // Validate the handle
+ Validate();
+ // Make sure we are allowed to change the server
+ IsNotConnected();
+ // Perform the requested operation
+ m_Passwd.assign(passwd);
}
/* --------------------------------------------------------------------------------------------
@@ -324,8 +330,12 @@ public:
*/
void SetUser(CSStr user)
{
- if (Validate() && NotConnected())
- m_User.assign(user);
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to change the server
+ IsNotConnected();
+ // Perform the requested operation
+ m_User.assign(user);
}
/* --------------------------------------------------------------------------------------------
@@ -341,8 +351,12 @@ public:
*/
void SetName(CSStr name)
{
- if (Validate() && NotConnected())
- m_Name.assign(name);
+ // Validate the handle
+ Validate();
+ // Make sure we are allowed to change the server
+ IsNotConnected();
+ // Perform the requested operation
+ m_Name.assign(name);
}
/* --------------------------------------------------------------------------------------------
@@ -547,9 +561,10 @@ public:
*/
Int32 CmdJoin(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_join(m_Session, channel, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_join(m_Session, channel, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -557,9 +572,10 @@ public:
*/
Int32 CmdJoin(CSStr channel, CSStr key)
{
- if (ConnectedThrow())
- return irc_cmd_join(m_Session, channel, key);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_join(m_Session, channel, key);
}
/* --------------------------------------------------------------------------------------------
@@ -567,9 +583,10 @@ public:
*/
Int32 CmdPart(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_part(m_Session, channel);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_part(m_Session, channel);
}
/* --------------------------------------------------------------------------------------------
@@ -577,9 +594,10 @@ public:
*/
Int32 CmdInvite(CSStr nick, CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_invite(m_Session, nick, channel);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_invite(m_Session, nick, channel);
}
/* --------------------------------------------------------------------------------------------
@@ -587,9 +605,10 @@ public:
*/
Int32 CmdNames(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_names(m_Session, channel);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_names(m_Session, channel);
}
/* --------------------------------------------------------------------------------------------
@@ -597,9 +616,10 @@ public:
*/
Int32 CmdList()
{
- if (ConnectedThrow())
- return irc_cmd_list(m_Session, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_list(m_Session, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -607,9 +627,10 @@ public:
*/
Int32 CmdList(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_list(m_Session, channel);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_list(m_Session, channel);
}
/* --------------------------------------------------------------------------------------------
@@ -617,9 +638,10 @@ public:
*/
Int32 CmdTopic(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_topic(m_Session, channel, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_topic(m_Session, channel, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -627,9 +649,10 @@ public:
*/
Int32 CmdTopic(CSStr channel, CSStr topic)
{
- if (ConnectedThrow())
- return irc_cmd_topic(m_Session, channel, topic);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_topic(m_Session, channel, topic);
}
/* --------------------------------------------------------------------------------------------
@@ -637,9 +660,10 @@ public:
*/
Int32 CmdChannelMode(CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_channel_mode(m_Session, channel, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_channel_mode(m_Session, channel, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -647,9 +671,10 @@ public:
*/
Int32 CmdChannelMode(CSStr channel, CSStr mode)
{
- if (ConnectedThrow())
- return irc_cmd_channel_mode(m_Session, channel, mode);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_channel_mode(m_Session, channel, mode);
}
/* --------------------------------------------------------------------------------------------
@@ -657,9 +682,10 @@ public:
*/
Int32 CmdUserMode()
{
- if (ConnectedThrow())
- return irc_cmd_user_mode(m_Session, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_user_mode(m_Session, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -667,9 +693,10 @@ public:
*/
Int32 CmdUserMode(CSStr mode)
{
- if (ConnectedThrow())
- return irc_cmd_user_mode(m_Session, mode);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_user_mode(m_Session, mode);
}
/* --------------------------------------------------------------------------------------------
@@ -677,9 +704,10 @@ public:
*/
Int32 CmdKick(CSStr nick, CSStr channel)
{
- if (ConnectedThrow())
- return irc_cmd_kick(m_Session, nick, channel, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_kick(m_Session, nick, channel, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -687,9 +715,10 @@ public:
*/
Int32 CmdKick(CSStr nick, CSStr channel, CSStr reason)
{
- if (ConnectedThrow())
- return irc_cmd_kick(m_Session, nick, channel, reason);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_kick(m_Session, nick, channel, reason);
}
/* --------------------------------------------------------------------------------------------
@@ -697,9 +726,10 @@ public:
*/
Int32 CmdMsg(CSStr nch, CSStr text)
{
- if (ConnectedThrow())
- return irc_cmd_msg(m_Session, nch, text);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_msg(m_Session, nch, text);
}
/* --------------------------------------------------------------------------------------------
@@ -707,9 +737,10 @@ public:
*/
Int32 CmdMe(CSStr nch, CSStr text)
{
- if (ConnectedThrow())
- return irc_cmd_me(m_Session, nch, text);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_me(m_Session, nch, text);
}
/* --------------------------------------------------------------------------------------------
@@ -717,9 +748,10 @@ public:
*/
Int32 CmdNotice(CSStr nch, CSStr text)
{
- if (ConnectedThrow())
- return irc_cmd_notice(m_Session, nch, text);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_notice(m_Session, nch, text);
}
/* --------------------------------------------------------------------------------------------
@@ -727,9 +759,10 @@ public:
*/
Int32 CmdCtcpRequest(CSStr nick, CSStr request)
{
- if (ConnectedThrow())
- return irc_cmd_ctcp_request(m_Session, nick, request);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_ctcp_request(m_Session, nick, request);
}
/* --------------------------------------------------------------------------------------------
@@ -737,9 +770,10 @@ public:
*/
Int32 CmdCtcpReply(CSStr nick, CSStr reply)
{
- if (ConnectedThrow())
- return irc_cmd_ctcp_reply(m_Session, nick, reply);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_ctcp_reply(m_Session, nick, reply);
}
/* --------------------------------------------------------------------------------------------
@@ -752,9 +786,10 @@ public:
*/
Int32 CmdWhois(CSStr nick)
{
- if (ConnectedThrow())
- return irc_cmd_whois(m_Session, nick);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_whois(m_Session, nick);
}
/* --------------------------------------------------------------------------------------------
@@ -762,9 +797,10 @@ public:
*/
Int32 CmdQuit()
{
- if (ConnectedThrow())
- return irc_cmd_quit(m_Session, NULL);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_quit(m_Session, NULL);
}
/* --------------------------------------------------------------------------------------------
@@ -772,9 +808,10 @@ public:
*/
Int32 CmdQuit(CSStr reason)
{
- if (ConnectedThrow())
- return irc_cmd_quit(m_Session, reason);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_cmd_quit(m_Session, reason);
}
/* --------------------------------------------------------------------------------------------
@@ -782,9 +819,10 @@ public:
*/
Int32 SendRaw(CSStr str)
{
- if (ConnectedThrow())
- return irc_send_raw(m_Session, str);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Send the specified command and return the result
+ return irc_send_raw(m_Session, str);
}
/* --------------------------------------------------------------------------------------------
@@ -793,9 +831,10 @@ public:
*/
Int32 DestroyDcc(Uint32 dccid)
{
- if (ConnectedThrow())
- return irc_dcc_destroy(m_Session, dccid);
- return -1;
+ // Validate the connection status
+ ValidateConnection();
+ // Perform the requested operation and return the result
+ return irc_dcc_destroy(m_Session, dccid);
}
/* --------------------------------------------------------------------------------------------
@@ -803,8 +842,10 @@ public:
*/
void SetCtcpVersion(CSStr version)
{
- if (ConnectedThrow())
- irc_set_ctcp_version(m_Session, version);
+ // Validate the connection status
+ ValidateConnection();
+ // Perform the requested operation
+ irc_set_ctcp_version(m_Session, version);
}
/* --------------------------------------------------------------------------------------------
@@ -812,9 +853,10 @@ public:
*/
Int32 GetErrNo()
{
- if (Validate())
- return irc_errno(m_Session);
- return -1;
+ // Validate the handle
+ Validate();
+ // Return the requested information
+ return irc_errno(m_Session);
}
/* --------------------------------------------------------------------------------------------
@@ -822,9 +864,10 @@ public:
*/
CSStr GetErrStr()
{
- if (Validate())
- return irc_strerror(irc_errno(m_Session));
- return _SC("");
+ // Validate the handle
+ Validate();
+ // Return the requested information
+ return irc_strerror(irc_errno(m_Session));
}
/* --------------------------------------------------------------------------------------------
@@ -832,8 +875,10 @@ public:
*/
void SetOption(Uint32 option)
{
- if (Validate())
- return irc_option_set(m_Session, option);
+ // Validate the handle
+ Validate();
+ // Perform the requested operation and return the result
+ return irc_option_set(m_Session, option);
}
/* --------------------------------------------------------------------------------------------
@@ -841,8 +886,10 @@ public:
*/
void ResetOption(Uint32 option)
{
- if (Validate())
- return irc_option_set(m_Session, option);
+ // Validate the handle
+ Validate();
+ // Perform the requested operation and return the result
+ return irc_option_set(m_Session, option);
}
/* --------------------------------------------------------------------------------------------