diff --git a/modules/irc/Common.cpp b/modules/irc/Common.cpp index d024fb1f..4b7540e8 100644 --- a/modules/irc/Common.cpp +++ b/modules/irc/Common.cpp @@ -3,7 +3,8 @@ #include "Module.hpp" // ------------------------------------------------------------------------------------------------ -#include +#include +#include // ------------------------------------------------------------------------------------------------ #include @@ -37,8 +38,10 @@ void SqThrowF(CSStr str, ...) 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"); + if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) + { + std::strcpy(g_Buffer, "Unknown error has occurred"); + } // Release the argument list va_end(args); // Throw the exception with the resulted message @@ -52,17 +55,26 @@ CSStr FmtStr(CSStr str, ...) 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 */ + if (std::vsnprintf(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() + : m_VM(_SqVM), m_Top(sq_gettop(m_VM)) +{ + /* ... */ +} + // ------------------------------------------------------------------------------------------------ StackGuard::StackGuard(HSQUIRRELVM vm) - : m_Top(sq_gettop(vm)), m_VM(vm) + : m_VM(vm), m_Top(sq_gettop(vm)) { /* ... */ } @@ -73,6 +85,96 @@ StackGuard::~StackGuard() sq_pop(m_VM, sq_gettop(m_VM) - m_Top); } +// -------------------------------------------------------------------------------------------- +StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt) + : mPtr(nullptr) + , mLen(-1) + , mRes(SQ_OK) + , mObj() + , mVM(vm) +{ + const Int32 top = sq_gettop(vm); + // Reset the converted value object + sq_resetobject(&mObj); + // Was the string or value specified? + if (top <= (idx - 1)) + { + mRes = sq_throwerror(vm, "Missing string or value"); + } + // Do we have enough values to call the format function and are we allowed to? + else if (top > idx && fmt) + { + // Pointer to the generated string + SStr str = nullptr; + // Attempt to generate the specified string format + mRes = sqstd_format(vm, idx, &mLen, &str); + // Did the format succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !str) + { + mRes = sq_throwerror(vm, "Unable to generate the string"); + } + else + { + mPtr = const_cast< CSStr >(str); + } + } + // Is the value on the stack an actual string? + else if (sq_gettype(vm, idx) == OT_STRING) + { + // Obtain a reference to the string object + mRes = sq_getstackobj(vm, idx, &mObj); + // Could we retrieve the object from the stack? + if (SQ_SUCCEEDED(mRes)) + { + // Keep a strong reference to the object + sq_addref(vm, &mObj); + // Attempt to retrieve the string value from the stack + mRes = sq_getstring(vm, idx, &mPtr); + } + // Did the retrieval succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !mPtr) + { + mRes = sq_throwerror(vm, "Unable to retrieve the string"); + } + } + // We have to try and convert it to string + else + { + // Attempt to convert the value from the stack to a string + mRes = sq_tostring(vm, idx); + // Could we convert the specified value to string? + if (SQ_SUCCEEDED(mRes)) + { + // Obtain a reference to the resulted object + mRes = sq_getstackobj(vm, -1, &mObj); + // Could we retrieve the object from the stack? + if (SQ_SUCCEEDED(mRes)) + { + // Keep a strong reference to the object + sq_addref(vm, &mObj); + // Attempt to obtain the string pointer + mRes = sq_getstring(vm, -1, &mPtr); + } + } + // Pop a value from the stack regardless of the result + sq_pop(vm, 1); + // Did the retrieval succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !mPtr) + { + mRes = sq_throwerror(vm, "Unable to retrieve the value"); + } + } +} + +// ------------------------------------------------------------------------------------------------ +StackStrF::~StackStrF() +{ + if (mVM && !sq_isnull(mObj)) + { + sq_release(mVM, &mObj); + } +} + // ------------------------------------------------------------------------------------------------ CSStr GetNick(CSStr origin) { diff --git a/modules/irc/Common.hpp b/modules/irc/Common.hpp index c0a3c554..1614cb0e 100644 --- a/modules/irc/Common.hpp +++ b/modules/irc/Common.hpp @@ -4,6 +4,9 @@ // ------------------------------------------------------------------------------------------------ #include "ModBase.hpp" +// ------------------------------------------------------------------------------------------------ +#include + // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -50,6 +53,11 @@ CSStr FmtStr(CSStr str, ...); */ struct StackGuard { + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + StackGuard(); + /* -------------------------------------------------------------------------------------------- * Base constructor. */ @@ -85,8 +93,51 @@ private: 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. */ + HSQUIRRELVM m_VM; // The VM where the stack should be restored. + Int32 m_Top; // The top of the stack when this instance was created. +}; + +/* ------------------------------------------------------------------------------------------------ + * Helper structure for retrieving a value from the stack as a string or a formatted string. +*/ +struct StackStrF +{ + // -------------------------------------------------------------------------------------------- + CSStr mPtr; // Pointer to the C string that was retrieved. + SQInteger mLen; // The string length if it could be retrieved. + SQRESULT mRes; // The result of the retrieval attempts. + HSQOBJECT mObj; // Strong reference to the string object. + HSQUIRRELVM mVM; // The associated virtual machine. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF(const StackStrF & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF(StackStrF && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~StackStrF(); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF & operator = (const StackStrF & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF & operator = (StackStrF && o) = delete; }; /* ------------------------------------------------------------------------------------------------ diff --git a/modules/irc/Module.cpp b/modules/irc/Module.cpp index 0d53f31e..7433fdad 100644 --- a/modules/irc/Module.cpp +++ b/modules/irc/Module.cpp @@ -4,12 +4,12 @@ #include "Session.hpp" // -------------------------------------------------------------------------------------------- -#include +#include +#include +#include // -------------------------------------------------------------------------------------------- -#include -#include -#include +#include // -------------------------------------------------------------------------------------------- #if defined(WIN32) || defined(_WIN32) @@ -20,14 +20,14 @@ namespace SqMod { // -------------------------------------------------------------------------------------------- -PluginFuncs* _Func = NULL; -PluginCallbacks* _Clbk = NULL; -PluginInfo* _Info = NULL; +PluginFuncs* _Func = nullptr; +PluginCallbacks* _Clbk = nullptr; +PluginInfo* _Info = nullptr; // -------------------------------------------------------------------------------------------- -HSQAPI _SqAPI = NULL; -HSQEXPORTS _SqMod = NULL; -HSQUIRRELVM _SqVM = NULL; +HSQAPI _SqAPI = nullptr; +HSQEXPORTS _SqMod = nullptr; +HSQUIRRELVM _SqVM = nullptr; /* ------------------------------------------------------------------------------------------------ * Bind speciffic functions to certain server events. @@ -53,7 +53,9 @@ void OnSquirrelInitialize() _SqMod = sq_api_import(_Func); // Did we failed to obtain the plugin exports? if(!_SqMod) + { OutputError("Failed to attach [%s] on host plugin.", SQIRC_NAME); + } else { // Obtain the Squirrel API @@ -70,12 +72,16 @@ void OnSquirrelLoad() { // Make sure that we have a valid plugin API if (!_SqMod) - return; /* Unable to proceed. */ + { + return; // Unable to proceed! + } // Obtain the Squirrel API and VM _SqVM = _SqMod->GetSquirrelVM(); // Make sure that a valid virtual machine exists if (!_SqVM) - return; /* Unable to proceed. */ + { + return; // Unable to proceed! + } // Set this as the default database DefaultVM::Set(_SqVM); // Register the module API @@ -93,7 +99,7 @@ void OnSquirrelTerminate() // Terminate all session and release script resources Session::Terminate(); // Release the current database (if any) - DefaultVM::Set(NULL); + DefaultVM::Set(nullptr); } /* -------------------------------------------------------------------------------------------- @@ -111,10 +117,12 @@ static void OnFrame(float /*delta*/) bool CheckAPIVer(CCStr ver) { // Obtain the numeric representation of the API version - long vernum = strtol(ver, NULL, 10); + long vernum = std::strtol(ver, nullptr, 10); // Check against version mismatch if (vernum == SQMOD_API_VER) + { return true; + } // Log the incident OutputError("API version mismatch on %s", SQIRC_NAME); OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER); @@ -131,7 +139,9 @@ static int OnInternalCommand(unsigned int type, const char * text) { case SQMOD_INITIALIZE_CMD: if (CheckAPIVer(text)) + { OnSquirrelInitialize(); + } break; case SQMOD_LOAD_CMD: OnSquirrelLoad(); @@ -170,10 +180,10 @@ void BindCallbacks() // ------------------------------------------------------------------------------------------------ void UnbindCallbacks() { - _Clbk->OnInitServer = NULL; - _Clbk->OnFrame = NULL; - _Clbk->OnInternalCommand = NULL; - _Clbk->OnShutdownServer = NULL; + _Clbk->OnInitServer = nullptr; + _Clbk->OnFrame = nullptr; + _Clbk->OnInternalCommand = nullptr; + _Clbk->OnShutdownServer = nullptr; } // -------------------------------------------------------------------------------------------- @@ -182,13 +192,13 @@ void RegisterAPI(HSQUIRRELVM vm) Table ircns(vm); ircns.Bind(_SC("Session"), Class< Session, NoCopy< Session > >(vm, _SC("SqIrcSession")) - /* Constructors */ + // Constructors .Ctor() - /* Core Metamethods */ + // Core Metamethods .Func(_SC("_cmp"), &Session::Cmp) .SquirrelFunc(_SC("_typename"), &Session::Typename) .Func(_SC("_tostring"), &Session::ToString) - /* Properties */ + // Properties .Prop(_SC("Valid"), &Session::IsValid) .Prop(_SC("Connected"), &Session::IsConnected) .Prop(_SC("Tag"), &Session::GetTag, &Session::SetTag) @@ -209,7 +219,7 @@ void RegisterAPI(HSQUIRRELVM vm) .Prop(_SC("Reconnecting"), &Session::GetReconnect) .Prop(_SC("IPv6"), &Session::GetIPv6) .Prop(_SC("Server"), &Session::GetServer, &Session::SetServer) - .Prop(_SC("CtcpVersion"), (void (Session::*)(void))(NULL), &Session::SetCtcpVersion) + .Prop(_SC("CtcpVersion"), (void (Session::*)(void))(nullptr), &Session::SetCtcpVersion) .Prop(_SC("ErrNo"), &Session::GetErrNo) .Prop(_SC("ErrStr"), &Session::GetErrStr) .Prop(_SC("OnConnect"), &Session::GetOnConnect) @@ -233,7 +243,7 @@ void RegisterAPI(HSQUIRRELVM vm) .Prop(_SC("OnNumeric"), &Session::GetOnNumeric) .Prop(_SC("OnDccChatReq"), &Session::GetOnDccChatReq) .Prop(_SC("OnDccSendReq"), &Session::GetOnDccSendReq) - /* Functions */ + // Member Methods .Overload< Int32 (Session::*)(void) >(_SC("Connect"), &Session::Connect) .Overload< Int32 (Session::*)(CSStr, Uint32, CSStr) >(_SC("Connect"), &Session::Connect) .Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr) >(_SC("Connect"), &Session::Connect) @@ -295,6 +305,7 @@ void RegisterAPI(HSQUIRRELVM vm) .Func(_SC("BindNumeric"), &Session::BindOnNumeric) .Func(_SC("BindDccChatReq"), &Session::BindOnDccChatReq) .Func(_SC("BindDccSendReq"), &Session::BindOnDccSendReq) + // Squirrel Methods .SquirrelFunc(_SC("CmdMsgF"), &Session::CmdMsgF) .SquirrelFunc(_SC("CmdMeF"), &Session::CmdMeF) .SquirrelFunc(_SC("CmdNoticeF"), &Session::CmdNoticeF) diff --git a/modules/irc/Session.cpp b/modules/irc/Session.cpp index 8db3927c..3eaf8488 100644 --- a/modules/irc/Session.cpp +++ b/modules/irc/Session.cpp @@ -3,8 +3,7 @@ #include "Module.hpp" // ------------------------------------------------------------------------------------------------ -#include -#include +#include // ------------------------------------------------------------------------------------------------ #include @@ -19,7 +18,7 @@ irc_callbacks_t Session::s_Callbacks; bool Session::s_Initialized = false; // ------------------------------------------------------------------------------------------------ -Session* Session::s_Session = NULL; +Session* Session::s_Session = nullptr; // ------------------------------------------------------------------------------------------------ Session::Sessions Session::s_Sessions; @@ -37,12 +36,16 @@ void Session::Process() { // Do we only have one IRC session? if (s_Session) + { s_Session->Update(); + } // Do we have multiple sessions? else if (!s_Sessions.empty()) { for (Sessions::iterator itr = s_Sessions.begin(); itr != s_Sessions.end(); ++itr) + { (*itr)->Update(); + } } } @@ -51,12 +54,16 @@ void Session::Terminate() { // Do we only have one IRC session? if (s_Session) + { s_Session->Destroy(); /* This should do the job. */ + } // Do we have multiple sessions? else if (!s_Sessions.empty()) { for (Sessions::iterator itr = s_Sessions.begin(); itr != s_Sessions.end(); ++itr) + { (*itr)->Destroy(); + } } } @@ -100,7 +107,9 @@ void Session::Update() { // Make sure we even have a session if (!m_Session) + { return; + } // Make sure that the IRC session is connected else if (!irc_is_connected(m_Session)) { @@ -115,19 +124,19 @@ void Session::Update() if (m_IPv6) { m_LastCode = irc_connect6(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } else { m_LastCode = irc_connect(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } } @@ -142,8 +151,8 @@ void Session::Update() tv.tv_usec = (m_PoolTime * 1000L); tv.tv_sec = 0; // Initialize the sets - memset(&in_set, 0, sizeof(fd_set)); - memset(&out_set, 0, sizeof(fd_set)); + std::memset(&in_set, 0, sizeof(fd_set)); + std::memset(&out_set, 0, sizeof(fd_set)); // Add the IRC session descriptors irc_add_select_descriptors(m_Session, &in_set, &out_set, &maxfd); // Call select() @@ -197,11 +206,11 @@ void Session::Destroy() // Disconnect the session Disconnect(); // Break the association with this instance (paranoia) - irc_set_ctx(m_Session, NULL); + irc_set_ctx(m_Session, nullptr); // Destroy the IRC session structure irc_destroy_session(m_Session); // Explicitly make sure no further calls can be made to this session (again... paranoia) - m_Session = NULL; + m_Session = nullptr; // Release resources Release(); } @@ -211,7 +220,9 @@ void Session::Validate() const { // Do we have a valid session handle? if (!m_Session) + { STHROWF("Invalid IRC session"); + } } // ------------------------------------------------------------------------------------------------ @@ -219,10 +230,14 @@ void Session::ValidateConnection() const { // Do we have a valid session handle? if (!m_Session) + { STHROWF("Invalid IRC session"); + } // Is the session connected? else if (!irc_is_connected(m_Session)) + { STHROWF("Session is not connected"); + } } // ------------------------------------------------------------------------------------------------ @@ -230,7 +245,9 @@ 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)) + { STHROWF("Already connected or trying connect to IRC server"); + } } // ------------------------------------------------------------------------------------------------ @@ -238,7 +255,9 @@ bool Session::ValidateEventSession(Session * ptr) { // Is the session instance valid? if (ptr) + { return true; + } // 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 @@ -267,7 +286,7 @@ Session::Session() if (!m_Session) { // Explicitly make sure no further calls can be made to this session - m_Session = NULL; + m_Session = nullptr; // Now it's safe to throw the error STHROWF("Unable to create an IRC session"); } @@ -277,17 +296,21 @@ 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_Session = nullptr; s_Sessions.push_back(this); } // This is part of multiple session instances else + { s_Sessions.push_back(this); + } } } @@ -299,10 +322,14 @@ Session::~Session() Sessions::iterator itr = std::find(s_Sessions.begin(), s_Sessions.end(), this); // Are we in the pool? if (itr != s_Sessions.end()) + { s_Sessions.erase(itr); /* Remove our self from the pool. */ + } // Is there a single session and that's us? if (s_Session == this) - s_Session = NULL; + { + s_Session = nullptr; + } } // ------------------------------------------------------------------------------------------------ @@ -312,13 +339,19 @@ void Session::SetNick(CSStr nick) Validate(); // Validate the specified nick name if (!nick || strlen(nick) <= 0) + { STHROWF("Invalid IRC nickname"); + } // Do we have to issue a nickname command? else if (Connected()) + { irc_cmd_nick(m_Session, nick); + } // Simply save the specified nickname else + { m_Nick.assign(nick); + } } // ------------------------------------------------------------------------------------------------ @@ -328,7 +361,9 @@ void Session::SetPort(Uint32 num) IsNotConnected(); // Validate the specified port number if (num > 0xFFFF) + { STHROWF("Port number is out of range: %u > %u", num, 0xFFFF); + } // Assign the specified port number m_Port = num; } @@ -340,7 +375,9 @@ Int32 Session::CmdNick(CSStr nick) ValidateConnection(); // Validate the specified nick name if (!nick || strlen(nick) <= 0) + { STHROWF("Invalid IRC nickname"); + } // Issue the command and return the result return irc_cmd_nick(m_Session, nick); } @@ -367,7 +404,9 @@ void Session::SetNextTry(Object & tm) Int64 microseconds = 0; // Attempt to get the numeric value inside the specified object if (SQ_FAILED(_SqMod->GetTimestamp(_SqVM, -1, µseconds))) + { STHROWF("Invalid time-stamp specified"); + } // Assign the specified timestamp value m_NextTry = microseconds; } @@ -379,10 +418,14 @@ Object Session::GetSessionTime() const 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 and return it return Var< Object >(_SqVM, -1).value; } @@ -396,10 +439,14 @@ Int32 Session::Connect() IsNotConnected(); // Validate the specified server if (!m_Server.empty()) + { STHROWF("Attempting to connect IRC without specifying a server"); + } // Validate the specified nickname else if (!m_Nick.empty()) + { STHROWF("Attempting to connect IRC without specifying a nickname"); + } // Enable the reconnection system m_Reconnect = true; // Reset the number of tries @@ -410,10 +457,10 @@ Int32 Session::Connect() 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_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } @@ -426,13 +473,19 @@ Int32 Session::Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSSt IsNotConnected(); // Validate the specified port if (port > 0xFFFF) + { STHROWF("Port number is out of range: %u > %u", port, 0xFFFF); + } // Validate the specified server else if (!server || strlen(server) <= 0) + { STHROWF("Attempting to connect IRC without specifying a server"); + } // Validate the specified nickname else if (!nick || strlen(nick) <= 0) + { STHROWF("Attempting to connect IRC without specifying a nickname"); + } // Save the specified port m_Port = port; // Save the specified server @@ -455,10 +508,10 @@ Int32 Session::Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSSt 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_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } @@ -471,10 +524,14 @@ Int32 Session::Connect6() IsNotConnected(); // Validate the specified server if (!m_Server.empty()) + { STHROWF("Attempting to connect IRC without specifying a server"); + } // Validate the specified nickname else if (!m_Nick.empty()) + { STHROWF("Attempting to connect IRC without specifying a nickname"); + } // Enable the reconnection system m_Reconnect = true; // Reset the number of tries @@ -485,10 +542,10 @@ Int32 Session::Connect6() 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_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } @@ -501,13 +558,19 @@ Int32 Session::Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSS IsNotConnected(); // Validate the specified port if (port > 0xFFFF) + { STHROWF("Port number is out of range: %u > %u", port, 0xFFFF); + } // Validate the specified server else if (!server || strlen(server) <= 0) + { STHROWF("Attempting to connect IRC without specifying a server"); + } // Validate the specified nickname else if (!nick || strlen(nick) <= 0) + { STHROWF("Attempting to connect IRC without specifying a nickname"); + } // Save the specified port m_Port = port; // Save the specified server @@ -530,10 +593,10 @@ Int32 Session::Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSS 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_Passwd.empty() ? nullptr : m_Passwd.c_str(), m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() + m_User.empty() ? nullptr : m_User.c_str(), + m_Name.empty() ? nullptr : m_Name.c_str() ); } @@ -557,10 +620,14 @@ 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 */ + { + 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(_SqVM, count); // Are the any parameters? @@ -568,7 +635,9 @@ void Session::ForwardEvent(Session * session, Function & listener, CCStr event, { // Transform the parameters into a squirrel array for (Uint32 i = 0; i < count; ++i) + { parameters.SetValue(i, params[i]); + } } // Obtain the initial stack size const StackGuard sg(_SqVM); @@ -586,10 +655,14 @@ 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 */ + { + 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(_SqVM, count); // Are the any parameters? @@ -597,7 +670,9 @@ void Session::ForwardEvent(Session * session, Function & listener, Uint32 event, { // 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); @@ -626,7 +701,7 @@ void Session::ForwardEvent(Session * /*session*/, Function & /*listener*/, CCStr // ------------------------------------------------------------------------------------------------ void Session::OnConnect(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) { // Prevent any attempts to reconnect now @@ -641,11 +716,13 @@ void Session::OnConnect(irc_session_t * session, CCStr event, CCStr origin, CCSt // ------------------------------------------------------------------------------------------------ void Session::OnNick(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) { if (params && params[0]) + { inst->m_Nick.assign(params[0]); + } ForwardEvent(inst, inst->m_OnNick, event, origin, params, count); } } @@ -653,154 +730,192 @@ void Session::OnNick(irc_session_t * session, CCStr event, CCStr origin, CCStr * // ------------------------------------------------------------------------------------------------ void Session::OnQuit(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnQuit, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnJoin(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnJoin, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnPart(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnPart, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnMode(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnMode, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnUmode(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnUmode, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnTopic(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnTopic, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnKick(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnKick, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnChannel(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnChannel, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnPrivMsg(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnPrivMsg, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnNotice(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnNotice, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnChannelNotice(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnChannelNotice, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnInvite(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnInvite, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnCtcpReq(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnCtcpReq, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnCtcpRep(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnCtcpRep, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnCtcpAction(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnCtcpAction, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnUnknown(irc_session_t * session, CCStr event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnUnknown, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnNumeric(irc_session_t * session, Uint32 event, CCStr origin, CCStr * params, Uint32 count) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnNumeric, event, origin, params, count); + } } // ------------------------------------------------------------------------------------------------ void Session::OnDccChatReq(irc_session_t * session, CCStr nick, CCStr addr, irc_dcc_t dccid) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnDccChatReq, nick, addr, dccid); + } } // ------------------------------------------------------------------------------------------------ void Session::OnDccSendReq(irc_session_t * session, CCStr nick, CCStr addr, CCStr filename, Ulong size, irc_dcc_t dccid) { - Session * inst = (Session *)irc_get_ctx(session); + Session * inst = reinterpret_cast< Session * >(irc_get_ctx(session)); if (ValidateEventSession(inst)) + { ForwardEvent(inst, inst->m_OnDccSendReq, nick, addr, filename, size, dccid); + } } // ------------------------------------------------------------------------------------------------ @@ -808,63 +923,59 @@ SQInteger Session::CmdMsgF(HSQUIRRELVM vm) { // Obtain the initial stack size const Int32 top = sq_gettop(vm); - // Do we have a target? + // Do we have a target value? if (top <= 1) + { return sq_throwerror(vm, "Missing the message target"); - // Do we have a valid target? - else if (sq_gettype(vm, 2) != OT_STRING) - return sq_throwerror(vm, "Invalid target specified"); + } // Do we have a message value? else if (top <= 2) + { return sq_throwerror(vm, "Missing the message value"); - // Obtain the instance and target - Var< Session * > inst(vm, 1); - Var< String > target(vm, 2); - // The value returned by the command - Int32 code = -1; + } + // The session instance + Session * session = nullptr; + // Attempt to extract the argument values + try + { + session = Var< Session * >(vm, 1).value; + } + catch (const Sqrat::Exception & e) + { + // Propagate the error + return sq_throwerror(vm, e.Message().c_str()); + } // Do we have a valid session instance? - if (!inst.value) + if (!session) + { return sq_throwerror(vm, "Invalid session instance"); + } // Do we have a valid session? - else if (!inst.value->m_Session) + else if (!session->m_Session) + { return sq_throwerror(vm, "Invalid IRC session"); + } // Is the session connected? - else if (!inst.value->Connected()) + else if (!session->Connected()) + { return sq_throwerror(vm, "Session is not connected"); - // Is the specified message value a string or something convertible to string? - else if (top == 3 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1)))) - { - CSStr msg = NULL; - // Attempt to retrieve the string from the stack - if (SQ_FAILED(sq_getstring(vm, -1, &msg))) - { - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); - // Now we can throw the error message - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Forward the resulted string value - code = irc_cmd_msg(inst.value->m_Session, target.value.c_str(), msg); - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to retrieve the target from the stack as a string + StackStrF target(vm, 2, false); + // Have we failed to retrieve the string? + if (SQ_FAILED(target.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - return ret; - // Forward the resulted string value - else if (msg) - code = irc_cmd_msg(inst.value->m_Session, target.value.c_str(), msg); + return target.mRes; // Propagate the error! } - // All methods of retrieving the message value failed - else - return sq_throwerror(vm, "Unable to extract the player message"); + // Attempt to retrieve the value from the stack as a string + StackStrF message(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(message.mRes)) + { + return message.mRes; // Propagate the error! + } + // Forward the resulted string value and save the returned result code + const Int32 code = irc_cmd_msg(session->m_Session, target.mPtr, message.mPtr); // Push the obtained code onto the stack sq_pushinteger(vm, code); // We have a value on the stack @@ -876,63 +987,59 @@ SQInteger Session::CmdMeF(HSQUIRRELVM vm) { // Obtain the initial stack size const Int32 top = sq_gettop(vm); - // Do we have a target? + // Do we have a target value? if (top <= 1) + { return sq_throwerror(vm, "Missing the message target"); - // Do we have a valid target? - else if (sq_gettype(vm, 2) != OT_STRING) - return sq_throwerror(vm, "Invalid target specified"); + } // Do we have a message value? else if (top <= 2) + { return sq_throwerror(vm, "Missing the message value"); - // Obtain the instance and target - Var< Session * > inst(vm, 1); - Var< String > target(vm, 2); - // The value returned by the command - Int32 code = -1; + } + // The session instance + Session * session = nullptr; + // Attempt to extract the argument values + try + { + session = Var< Session * >(vm, 1).value; + } + catch (const Sqrat::Exception & e) + { + // Propagate the error + return sq_throwerror(vm, e.Message().c_str()); + } // Do we have a valid session instance? - if (!inst.value) + if (!session) + { return sq_throwerror(vm, "Invalid session instance"); + } // Do we have a valid session? - else if (!inst.value->m_Session) + else if (!session->m_Session) + { return sq_throwerror(vm, "Invalid IRC session"); + } // Is the session connected? - else if (!inst.value->Connected()) + else if (!session->Connected()) + { return sq_throwerror(vm, "Session is not connected"); - // Is the specified message value a string or something convertible to string? - else if (top == 3 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1)))) - { - CSStr msg = NULL; - // Attempt to retrieve the string from the stack - if (SQ_FAILED(sq_getstring(vm, -1, &msg))) - { - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); - // Now we can throw the error message - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Forward the resulted string value - code = irc_cmd_me(inst.value->m_Session, target.value.c_str(), msg); - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to retrieve the target from the stack as a string + StackStrF target(vm, 2, false); + // Have we failed to retrieve the string? + if (SQ_FAILED(target.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - return ret; - // Forward the resulted string value - else if (msg) - code = irc_cmd_me(inst.value->m_Session, target.value.c_str(), msg); + return target.mRes; // Propagate the error! } - // All methods of retrieving the message value failed - else - return sq_throwerror(vm, "Unable to extract the player message"); + // Attempt to retrieve the value from the stack as a string + StackStrF message(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(message.mRes)) + { + return message.mRes; // Propagate the error! + } + // Forward the resulted string value and save the returned result code + const Int32 code = irc_cmd_me(session->m_Session, target.mPtr, message.mPtr); // Push the obtained code onto the stack sq_pushinteger(vm, code); // We have a value on the stack @@ -944,63 +1051,59 @@ SQInteger Session::CmdNoticeF(HSQUIRRELVM vm) { // Obtain the initial stack size const Int32 top = sq_gettop(vm); - // Do we have a target? + // Do we have a target value? if (top <= 1) + { return sq_throwerror(vm, "Missing the message target"); - // Do we have a valid target? - else if (sq_gettype(vm, 2) != OT_STRING) - return sq_throwerror(vm, "Invalid target specified"); + } // Do we have a message value? else if (top <= 2) + { return sq_throwerror(vm, "Missing the message value"); - // Obtain the instance and target - Var< Session * > inst(vm, 1); - Var< String > target(vm, 2); - // The value returned by the command - Int32 code = -1; + } + // The session instance + Session * session = nullptr; + // Attempt to extract the argument values + try + { + session = Var< Session * >(vm, 1).value; + } + catch (const Sqrat::Exception & e) + { + // Propagate the error + return sq_throwerror(vm, e.Message().c_str()); + } // Do we have a valid session instance? - if (!inst.value) + if (!session) + { return sq_throwerror(vm, "Invalid session instance"); + } // Do we have a valid session? - else if (!inst.value->m_Session) + else if (!session->m_Session) + { return sq_throwerror(vm, "Invalid IRC session"); + } // Is the session connected? - else if (!inst.value->Connected()) + else if (!session->Connected()) + { return sq_throwerror(vm, "Session is not connected"); - // Is the specified message value a string or something convertible to string? - else if (top == 3 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1)))) - { - CSStr msg = NULL; - // Attempt to retrieve the string from the stack - if (SQ_FAILED(sq_getstring(vm, -1, &msg))) - { - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); - // Now we can throw the error message - return sq_throwerror(vm, "Unable to retrieve the message"); - } - // Forward the resulted string value - code = irc_cmd_notice(inst.value->m_Session, target.value.c_str(), msg); - // If the value was converted to a string then pop the string - sq_pop(vm, sq_gettop(vm) - top); } - // Do we have enough values to call the format function? - else if (top > 3) + // Attempt to retrieve the target from the stack as a string + StackStrF target(vm, 2, false); + // Have we failed to retrieve the string? + if (SQ_FAILED(target.mRes)) { - SStr msg = NULL; - SQInteger len = 0; - // Attempt to generate the specified string format - SQRESULT ret = sqstd_format(vm, 3, &len, &msg); - // Did the format failed? - if (SQ_FAILED(ret)) - return ret; - // Forward the resulted string value - else if (msg) - code = irc_cmd_notice(inst.value->m_Session, target.value.c_str(), msg); + return target.mRes; // Propagate the error! } - // All methods of retrieving the message value failed - else - return sq_throwerror(vm, "Unable to extract the player message"); + // Attempt to retrieve the value from the stack as a string + StackStrF message(vm, 3); + // Have we failed to retrieve the string? + if (SQ_FAILED(message.mRes)) + { + return message.mRes; // Propagate the error! + } + // Forward the resulted string value and save the returned result code + const Int32 code = irc_cmd_notice(session->m_Session, target.mPtr, message.mPtr); // Push the obtained code onto the stack sq_pushinteger(vm, code); // We have a value on the stack diff --git a/modules/irc/Session.hpp b/modules/irc/Session.hpp index a0625811..8a8ba882 100644 --- a/modules/irc/Session.hpp +++ b/modules/irc/Session.hpp @@ -200,11 +200,17 @@ public: Int32 Cmp(const Session & o) const { if (m_Session == o.m_Session) + { return 0; + } else if (m_Session > o.m_Session) + { return 1; + } else + { return -1; + } } /* -------------------------------------------------------------------------------------------- @@ -485,7 +491,7 @@ public: */ Int32 Connect(CSStr server, Uint32 port, CSStr nick) { - return Connect(server, port, nick, NULL, NULL, NULL); + return Connect(server, port, nick, nullptr, nullptr, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -493,7 +499,7 @@ public: */ Int32 Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd) { - return Connect(server, port, nick, passwd, NULL, NULL); + return Connect(server, port, nick, passwd, nullptr, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -501,7 +507,7 @@ public: */ Int32 Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user) { - return Connect(server, port, nick, passwd, user, NULL); + return Connect(server, port, nick, passwd, user, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -519,7 +525,7 @@ public: */ Int32 Connect6(CSStr server, Uint32 port, CSStr nick) { - return Connect(server, port, nick, NULL, NULL, NULL); + return Connect(server, port, nick, nullptr, nullptr, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -527,7 +533,7 @@ public: */ Int32 Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd) { - return Connect(server, port, nick, passwd, NULL, NULL); + return Connect(server, port, nick, passwd, nullptr, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -535,7 +541,7 @@ public: */ Int32 Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user) { - return Connect(server, port, nick, passwd, user, NULL); + return Connect(server, port, nick, passwd, user, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -564,7 +570,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_join(m_Session, channel, NULL); + return irc_cmd_join(m_Session, channel, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -619,7 +625,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_list(m_Session, NULL); + return irc_cmd_list(m_Session, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -641,7 +647,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_topic(m_Session, channel, NULL); + return irc_cmd_topic(m_Session, channel, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -663,7 +669,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_channel_mode(m_Session, channel, NULL); + return irc_cmd_channel_mode(m_Session, channel, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -685,7 +691,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_user_mode(m_Session, NULL); + return irc_cmd_user_mode(m_Session, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -707,7 +713,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_kick(m_Session, nick, channel, NULL); + return irc_cmd_kick(m_Session, nick, channel, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -800,7 +806,7 @@ public: // Validate the connection status ValidateConnection(); // Send the specified command and return the result - return irc_cmd_quit(m_Session, NULL); + return irc_cmd_quit(m_Session, nullptr); } /* -------------------------------------------------------------------------------------------- @@ -1054,9 +1060,13 @@ public: void BindOnConnect(Object & env, Function & func) { if (func.IsNull()) + { m_OnConnect.ReleaseGently(); + } else + { m_OnConnect = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1073,9 +1083,13 @@ public: void BindOnNick(Object & env, Function & func) { if (func.IsNull()) + { m_OnNick.ReleaseGently(); + } else + { m_OnNick = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1092,9 +1106,13 @@ public: void BindOnQuit(Object & env, Function & func) { if (func.IsNull()) + { m_OnQuit.ReleaseGently(); + } else + { m_OnQuit = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1111,9 +1129,13 @@ public: void BindOnJoin(Object & env, Function & func) { if (func.IsNull()) + { m_OnJoin.ReleaseGently(); + } else + { m_OnJoin = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1130,9 +1152,13 @@ public: void BindOnPart(Object & env, Function & func) { if (func.IsNull()) + { m_OnPart.ReleaseGently(); + } else + { m_OnPart = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1149,9 +1175,13 @@ public: void BindOnMode(Object & env, Function & func) { if (func.IsNull()) + { m_OnMode.ReleaseGently(); + } else + { m_OnMode = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1168,9 +1198,13 @@ public: void BindOnUmode(Object & env, Function & func) { if (func.IsNull()) + { m_OnUmode.ReleaseGently(); + } else + { m_OnUmode = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1187,9 +1221,13 @@ public: void BindOnTopic(Object & env, Function & func) { if (func.IsNull()) + { m_OnTopic.ReleaseGently(); + } else + { m_OnTopic = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1206,9 +1244,13 @@ public: void BindOnKick(Object & env, Function & func) { if (func.IsNull()) + { m_OnKick.ReleaseGently(); + } else + { m_OnKick = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1225,9 +1267,13 @@ public: void BindOnChannel(Object & env, Function & func) { if (func.IsNull()) + { m_OnChannel.ReleaseGently(); + } else + { m_OnChannel = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1244,9 +1290,13 @@ public: void BindOnPrivMsg(Object & env, Function & func) { if (func.IsNull()) + { m_OnPrivMsg.ReleaseGently(); + } else + { m_OnPrivMsg = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1263,9 +1313,13 @@ public: void BindOnNotice(Object & env, Function & func) { if (func.IsNull()) + { m_OnNotice.ReleaseGently(); + } else + { m_OnNotice = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1282,9 +1336,13 @@ public: void BindOnChannelNotice(Object & env, Function & func) { if (func.IsNull()) + { m_OnChannelNotice.ReleaseGently(); + } else + { m_OnChannelNotice = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1301,9 +1359,13 @@ public: void BindOnInvite(Object & env, Function & func) { if (func.IsNull()) + { m_OnInvite.ReleaseGently(); + } else + { m_OnInvite = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1320,9 +1382,13 @@ public: void BindOnCtcpReq(Object & env, Function & func) { if (func.IsNull()) + { m_OnCtcpReq.ReleaseGently(); + } else + { m_OnCtcpReq = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1339,9 +1405,13 @@ public: void BindOnCtcpRep(Object & env, Function & func) { if (func.IsNull()) + { m_OnCtcpRep.ReleaseGently(); + } else + { m_OnCtcpRep = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1358,9 +1428,13 @@ public: void BindOnCtcpAction(Object & env, Function & func) { if (func.IsNull()) + { m_OnCtcpAction.ReleaseGently(); + } else + { m_OnCtcpAction = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1377,9 +1451,13 @@ public: void BindOnUnknown(Object & env, Function & func) { if (func.IsNull()) + { m_OnUnknown.ReleaseGently(); + } else + { m_OnUnknown = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1396,9 +1474,13 @@ public: void BindOnNumeric(Object & env, Function & func) { if (func.IsNull()) + { m_OnNumeric.ReleaseGently(); + } else + { m_OnNumeric = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1415,9 +1497,13 @@ public: void BindOnDccChatReq(Object & env, Function & func) { if (func.IsNull()) + { m_OnDccChatReq.ReleaseGently(); + } else + { m_OnDccChatReq = Function(env.GetVM(), env, func.GetFunc()); + } } /* -------------------------------------------------------------------------------------------- @@ -1434,9 +1520,13 @@ public: void BindOnDccSendReq(Object & env, Function & func) { if (func.IsNull()) + { m_OnDccSendReq.ReleaseGently(); + } else + { m_OnDccSendReq = Function(env.GetVM(), env, func.GetFunc()); + } } };