2034 lines
54 KiB
C++
2034 lines
54 KiB
C++
/**
|
|
* SETCommand.cc
|
|
*
|
|
* 28/12/2000 - David Henriksen <david@itwebnet.dk>
|
|
* Initial Version.
|
|
* 01/01/2001 - Greg Sikorski <gte@atomicrevs.demon.co.uk>
|
|
* Modifications.
|
|
* 10/02/2001 - David Henriksen <david@itwebnet.dk>
|
|
* Minor bug fixes.
|
|
*
|
|
* 20/02/2001 - Gator Robert White <gator@cajun-gator.net>
|
|
* removed AlwaysOp
|
|
* Sets channel options on the specified channel.
|
|
* 2001-03-16 - Perry Lorier <isomer@coders.net>
|
|
* Added 'DESC' as an alias for 'DESCRIPTION'
|
|
* 2001-04-16 - Alex Badea <vampire@go.ro>
|
|
* Changed the implementation for SET LANG, everything is dynamic now.
|
|
* 2012-04-16 - Seven <gergo_f@yahoo.com>
|
|
* Reimplemented NOFORCE channel flag
|
|
* Other minor modifications
|
|
* 2012-09-08 - Seven <gergo_f@yahoo.com>
|
|
* Added channel NOVOICE flag
|
|
*
|
|
* Caveats: None.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
* USA.
|
|
*
|
|
* $Id: SETCommand.cc,v 1.64 2008/04/16 20:34:44 danielaustin Exp $
|
|
*/
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include "StringTokenizer.h"
|
|
#include "cservice.h"
|
|
#include "Network.h"
|
|
#include "levels.h"
|
|
#include "responses.h"
|
|
#include "cservice_config.h"
|
|
#include <stdio.h>
|
|
|
|
const char SETCommand_cc_rcsId[] = "$Id: SETCommand.cc,v 1.64 2008/04/16 20:34:44 danielaustin Exp $" ;
|
|
|
|
namespace gnuworld
|
|
{
|
|
using namespace level;
|
|
|
|
bool SETCommand::Exec( iClient* theClient, const string& Message )
|
|
{
|
|
bot->incStat("COMMANDS.SET");
|
|
|
|
StringTokenizer st( Message ) ;
|
|
|
|
if( st.size() < 3 )
|
|
{
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
|
|
/* Is the user authorised? */
|
|
|
|
sqlUser* theUser = bot->isAuthed(theClient, true);
|
|
if(!theUser)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* First, is this a #channel or user set?
|
|
*/
|
|
|
|
if( st[1][0] != '#' ) // Didn't find a hash?
|
|
{
|
|
// Look by user then.
|
|
string option = string_upper(st[1]);
|
|
string value = string_upper(st[2]);
|
|
if (option == "INVISIBLE")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
theUser->setFlag(sqlUser::F_INVIS);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invis_on,
|
|
string("Your INVISIBLE setting is now ON.")));
|
|
return true;
|
|
}
|
|
|
|
if (value == "OFF")
|
|
{
|
|
theUser->removeFlag(sqlUser::F_INVIS);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invis_off,
|
|
string("Your INVISIBLE setting is now OFF.")));
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
|
|
if (option == "NOADDUSER")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
theUser->setFlag(sqlUser::F_NOADDUSER);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::noadduser_on,
|
|
string("Your NOADDUSER setting is now ON.")));
|
|
return true;
|
|
}
|
|
|
|
if (value == "OFF")
|
|
{
|
|
theUser->removeFlag(sqlUser::F_NOADDUSER);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::noadduser_off,
|
|
string("Your NOADDUSER setting is now OFF.")));
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
|
|
#ifdef USE_NOTES
|
|
if (option == "NONOTES")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
theUser->setFlag(sqlUser::F_NONOTES);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"You are no longer able to receive notes from anyone.");
|
|
return true;
|
|
}
|
|
|
|
if (value == "OFF")
|
|
{
|
|
theUser->removeFlag(sqlUser::F_NONOTES);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"You are now able to receive notes.");
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
#endif
|
|
#ifdef USE_USERS_URL
|
|
if ((option == "URL") || (option == "DESC") || (option == "DESCRIPTION") || (option == "MOTTO"))
|
|
{
|
|
string url;
|
|
if (value == "OFF")
|
|
{
|
|
url = "";
|
|
bot->Notice(theClient, bot->getResponse(theUser, language::userurl_off,
|
|
string("Cleared your %s")).c_str(),string_upper(option).c_str());
|
|
}
|
|
else
|
|
{
|
|
url = st.assemble(2);
|
|
bot->Notice(theClient, bot->getResponse(theUser, language::userurl_on,
|
|
string("Set your %s to %s.")).c_str(),string_upper(option).c_str(),url.c_str());
|
|
}
|
|
theUser->setUrl(url);
|
|
theUser->commit(theClient);
|
|
return true;
|
|
}
|
|
#endif
|
|
#ifdef USING_NEFARIOUS
|
|
if (option == "AUTONICK")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
theUser->setFlag(sqlUser::F_AUTONICK);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"Your AUTONICK setting is now ON.");
|
|
return true;
|
|
}
|
|
if (value == "OFF")
|
|
{
|
|
theUser->removeFlag(sqlUser::F_AUTONICK);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"Your AUTONICK setting is now OFF.");
|
|
return true;
|
|
}
|
|
bot->Notice(theClient,"value of %s must be ON or OFF", option.c_str());
|
|
return true;
|
|
}
|
|
if ((option == "NICK") || (option == "NICKNAME"))
|
|
{
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
string theNick = st[2];
|
|
bool notMe = false;
|
|
if ((admLevel >= level::nickset) && (st.size() > 3))
|
|
{
|
|
sqlUser* tmpUser = bot->getUserRecord(st[2]);
|
|
if (!tmpUser)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::not_registered,
|
|
string("The user %s doesn't appear to be registered.")).c_str(),
|
|
st[2].c_str());
|
|
return true;
|
|
}
|
|
theUser = tmpUser;
|
|
theNick = st[3];
|
|
value = string_upper(st[3]);
|
|
notMe = true;
|
|
}
|
|
if (value == "OFF")
|
|
{
|
|
theUser->removeFlag(sqlUser::F_AUTONICK);
|
|
theUser->setNickName("");
|
|
theUser->commit(theClient);
|
|
if (notMe)
|
|
bot->Notice(theClient,"Successfully cleared %s's nickname.", theUser->getUserName().c_str());
|
|
else
|
|
bot->Notice(theClient,"You have cleared your nickname.");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (theNick.length() < 2)
|
|
{
|
|
bot->Notice(theClient,"Your nickname must be at least 2 characters long.");
|
|
return true;
|
|
}
|
|
if (theNick.length() > 32)
|
|
{
|
|
bot->Notice(theClient,"ERROR: Nickname too long.");
|
|
return true;
|
|
}
|
|
if (bot->NickIsRegisteredTo(theNick).empty())
|
|
{
|
|
if (theUser->getNickName().empty())
|
|
theUser->setFlag(sqlUser::F_AUTONICK);
|
|
theUser->setNickName(theNick);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"You have successfully registered nickname %s.",theNick.c_str());
|
|
}
|
|
else
|
|
bot->Notice(theClient,"Sorry, that nickname is already registered.");
|
|
return true;
|
|
}
|
|
bot->Notice(theClient,"value of %s must be ON or OFF", option.c_str());
|
|
return true;
|
|
}
|
|
#endif
|
|
if (option == "DISABLEAUTH")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
/* only admins can use this command */
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel > 0)
|
|
{
|
|
theUser->setFlag(sqlUser::F_NOADMIN);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"You have lost the force :(");
|
|
bot->logAdminMessage("%s (%s) set DISABLEAUTH on!",
|
|
theClient->getNickName().c_str(), theUser->getUserName().c_str());
|
|
} else {
|
|
/* not an admin, return unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (value == "OFF")
|
|
{
|
|
/* only allow removal if it is set! */
|
|
if (theUser->getFlag(sqlUser::F_NOADMIN))
|
|
{
|
|
theUser->removeFlag(sqlUser::F_NOADMIN);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,"Welcome back, brave Jedi.");
|
|
bot->logAdminMessage("%s (%s) set DISABLEAUTH off!",
|
|
theClient->getNickName().c_str(), theUser->getUserName().c_str());
|
|
} else {
|
|
/* not set? pretend it's an unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
if (option == "NOPURGE")
|
|
{
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (!admLevel)
|
|
{
|
|
/* not an admin, return unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
return true;
|
|
}
|
|
sqlUser* targetUser = theUser;
|
|
if ((value != "ON") && (value != "OFF"))
|
|
{
|
|
targetUser = bot->getUserRecord(st[2]);
|
|
if (!targetUser)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::not_registered,
|
|
string("The user %s doesn't appear to be registered.")).c_str(),
|
|
st[2].c_str());
|
|
return true;
|
|
}
|
|
if (st.size() < 4)
|
|
{
|
|
bot->Notice(theClient,"SYNTAX: SET NOPURGE user ON|OFF");
|
|
return false;
|
|
}
|
|
else
|
|
value = string_upper(st[3]);
|
|
}
|
|
if (value == "ON")
|
|
{
|
|
targetUser->setFlag(sqlUser::F_NOPURGE);
|
|
targetUser->commit(theClient);
|
|
bot->Notice(theClient,"NOPURGE setting for %s is now ON", targetUser->getUserName().c_str());
|
|
return true;
|
|
}
|
|
if (value == "OFF")
|
|
{
|
|
/* only allow removal if it is set! */
|
|
//if (targetUser->getFlag(sqlUser::F_NOPURGE))
|
|
//{
|
|
targetUser->removeFlag(sqlUser::F_NOPURGE);
|
|
targetUser->commit(theClient);
|
|
//}
|
|
bot->Notice(theClient,"NOPURGE setting for %s is now OFF", targetUser->getUserName().c_str());
|
|
return true;
|
|
}
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
|
|
#ifdef USE_SETMAXLOGINS
|
|
if (option == "MAXLOGINS")
|
|
{
|
|
unsigned int maxlogins = atoi(value.c_str());
|
|
if (maxlogins > 3 || maxlogins <= 0)
|
|
{
|
|
bot->Notice(theClient, "Max Logins cannot be greater than 3 or less than 1");
|
|
return false;
|
|
}
|
|
|
|
theUser->setMaxLogins(maxlogins);
|
|
theUser->commit(theClient);
|
|
|
|
bot->Notice(theClient, "Max Logins now set to %i", maxlogins);
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
if (option == "LANG")
|
|
{
|
|
cservice::languageTableType::iterator ptr = bot->languageTable.find(value);
|
|
if (ptr != bot->languageTable.end())
|
|
{
|
|
string lang = ptr->second.second;
|
|
theUser->setLanguageId(ptr->second.first);
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::lang_set_to,
|
|
string("Language is set to %s.")).c_str(), lang.c_str());
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
"ERROR: Invalid language selection.");
|
|
return true;
|
|
}
|
|
|
|
#ifdef TOTP_AUTH_ENABLED
|
|
if (option == "TOTP")
|
|
{
|
|
if (value == "ON")
|
|
{
|
|
if (theUser->getFlag(sqlUser::F_TOTP_ENABLED))
|
|
{
|
|
bot->Notice(theClient, "TOTP is already enabled for your account");
|
|
return true;
|
|
}
|
|
if (!theUser->generateTOTPKey())
|
|
{
|
|
bot->Notice(theClient, "Failed to enable TOTP authentication, please contact a CService representative.");
|
|
return false;
|
|
}
|
|
if (!theUser->commit(theClient))
|
|
{
|
|
bot->Notice(theClient, "Failed to enable TOTP authentication, please contact a CService representative.");
|
|
return false;
|
|
}
|
|
bot->Notice(theClient, "TOTP key set. Your base 32 encoded secret key is: %s", theUser->getTotpKey().c_str());
|
|
bot->Notice(theClient, "Your key in hex string: %s", theUser->getTotpHexKey().c_str());
|
|
bot->Notice(theClient, "For QR representation of your key, visit: https://cservice.undernet.org/genqr.php?code=%s&name=UnderNet", theUser->getTotpKey().c_str());
|
|
bot->Notice(theClient, "Please note, this key will never be presented to you again. NEVER GIVE YOUR KEY TO ANYONE!");
|
|
bot->Notice(theClient, "To confirm TOTP activation please configure your device with the above key and type /msg %s set TOTP confirm <token>", bot->getNickName().c_str());
|
|
return true;
|
|
}
|
|
else if (value == "CONFIRM")
|
|
{
|
|
if(theUser->getFlag(sqlUser::F_TOTP_ENABLED))
|
|
{
|
|
bot->Notice(theClient, "TOTP is already enabled for your account.");
|
|
return true;
|
|
}
|
|
if (st.size() == 3)
|
|
{
|
|
bot->Notice(theClient, "Usage: /msg %s set totp CONFIRM <token>", bot->getNickName().c_str());
|
|
return true;
|
|
}
|
|
if (theUser->getTotpKey() == "")
|
|
{
|
|
bot->Notice(theClient, "Before confirming TOTP it must be enabled using /msg %s set TOTP on", bot->getNickName().c_str());
|
|
return true;
|
|
}
|
|
OathResult::OATH_RESULT_TYPE response = theUser->validateTOTP(st[3].c_str());
|
|
if (response != OathResult::OK)
|
|
{
|
|
if (response == OathResult::ERROR)
|
|
{
|
|
bot->Notice(theClient, "TOTP key validation failed due to an error, please contact a CService representative.");
|
|
}
|
|
if (response == OathResult::INVALID_TOKEN)
|
|
{
|
|
bot->Notice(theClient, "TOTP validation failed, invalid key, please make sure your device is configured properly with the correct key.");
|
|
}
|
|
return false;
|
|
}
|
|
if (st.size() == 4)
|
|
{
|
|
bot->Notice(theClient, "WARNING: This will enable time-based OTP (one time passwords). Once enabled, in order to login you will require a device to generate the OTP token which has the stored secret key. If you are sure, type: /msg %s set totp CONFIRM <token> -force",bot->getNickName().c_str());
|
|
return true;
|
|
}
|
|
if (string_upper(st[4]) == "-FORCE")
|
|
{
|
|
theUser->setFlag(sqlUser::F_TOTP_ENABLED);
|
|
if (!theUser->commit(theClient))
|
|
{
|
|
bot->Notice(theClient, "Failed to enable TOTP authentication, please contact a CService representative.");
|
|
return true;
|
|
}
|
|
bot->Notice(theClient, "TOTP Authentication is ENABLED");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
bot->Notice(theClient, "Invalid option %s", st[4].c_str());
|
|
return true;
|
|
}
|
|
}
|
|
else if (value == "OFF")
|
|
{
|
|
if (!theUser->getFlag(sqlUser::F_TOTP_ENABLED))
|
|
{
|
|
bot->Notice(theClient, "TOTP is already disabled for your account.");
|
|
return true;
|
|
}
|
|
if (st.size() < 4)
|
|
{
|
|
bot->Notice(theClient, "Usage: /msg %s set totp OFF <token>", bot->getNickName().c_str());
|
|
return false;
|
|
}
|
|
OathResult::OATH_RESULT_TYPE response = theUser->validateTOTP(st[3].c_str());
|
|
if (response != OathResult::OK)
|
|
{
|
|
if (response == OathResult::ERROR)
|
|
{
|
|
bot->Notice(theClient, "TOTP key validation failed due to an error, please contact a CService representative.");
|
|
}
|
|
if (response == OathResult::INVALID_TOKEN)
|
|
{
|
|
bot->Notice(theClient, "TOTP validation failed. (Invalid Token)");
|
|
}
|
|
return false;
|
|
}
|
|
theUser->clearTotpKey();
|
|
theUser->clearTotpHexKey();
|
|
theUser->removeFlag(sqlUser::F_TOTP_ENABLED);
|
|
if (!theUser->commit(theClient))
|
|
{
|
|
bot->Notice(theClient, "Failed to disable TOTP authentication, please contact a CService representative.");
|
|
return false;
|
|
}
|
|
bot->Notice(theClient, "TOTP Authentication is DISABLED");
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
if (option == "POWER")
|
|
{
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (!admLevel)
|
|
{
|
|
/* not an admin, return unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
return true;
|
|
}
|
|
sqlUser* targetUser = theUser;
|
|
if ((value != "ON") && (value != "OFF"))
|
|
{
|
|
targetUser = bot->getUserRecord(st[2]);
|
|
if (!targetUser)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::not_registered,
|
|
string("The user %s doesn't appear to be registered.")).c_str(),
|
|
st[2].c_str());
|
|
return true;
|
|
}
|
|
if (st.size() < 4)
|
|
{
|
|
bot->Notice(theClient,"SYNTAX: SET POWER user ON|OFF");
|
|
return false;
|
|
}
|
|
else
|
|
value = string_upper(st[3]);
|
|
}
|
|
if (value == "ON")
|
|
{
|
|
/* only admins can use this command */
|
|
if (((admLevel > 0) && (theUser->getFlag(sqlUser::F_POWER))) || ((theUser->getID() == 1) && (targetUser == theUser)))
|
|
{
|
|
targetUser->setFlag(sqlUser::F_POWER);
|
|
targetUser->commit(theClient);
|
|
bot->Notice(theClient,"Set POWER to ON for user %s", targetUser->getUserName().c_str());
|
|
} else {
|
|
/* not an admin, return unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
}
|
|
return true;
|
|
}
|
|
if (value == "OFF")
|
|
{
|
|
/* only allow removal if it is set! */
|
|
if (((admLevel > 0) && (theUser->getFlag(sqlUser::F_POWER)))
|
|
&& (targetUser->getFlag(sqlUser::F_POWER)))
|
|
{
|
|
targetUser->removeFlag(sqlUser::F_POWER);
|
|
targetUser->commit(theClient);
|
|
bot->Notice(theClient,"Set POWER to OFF for user %s", targetUser->getUserName().c_str());
|
|
} else {
|
|
/* not set? pretend it's an unknown command */
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
}
|
|
return true;
|
|
}
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
#ifdef USING_NEFARIOUS
|
|
if ((option == "HOST") || (option == "HOSTNAME"))
|
|
{
|
|
if (value == "OFF")
|
|
{
|
|
//theClient->clearFakeHost();
|
|
theUser->setHostName(string());
|
|
theUser->commit(theClient);
|
|
bot->Notice(theClient, "Your host was successfully cleared. Please reconnect to apply your original host.");
|
|
}
|
|
else
|
|
{
|
|
if (st[2].size() > 128)
|
|
{
|
|
bot->Notice(theClient, "Hostname can be maximum 128 characters long.");
|
|
return true;
|
|
}
|
|
if ((st[2].size() < 3) || (!validHostName(st[2])))
|
|
{
|
|
bot->Notice(theClient, "Invalid hostname provided. A valid hostname has at least a 2 characters long domain, and contains at least one dot.");
|
|
return true;
|
|
}
|
|
if (string_lower(st[2]).find(string_lower(iClient::getHiddenHostSuffix())) != string::npos)
|
|
{
|
|
bot->Notice(theClient, "Using the hidden-host-suffix in your hostname is not allowed.");
|
|
return true;
|
|
}
|
|
#ifdef VALIDATE_SET_HOSTNAME
|
|
if (!checkAllValidChars(st[2]))
|
|
{
|
|
bot->Notice(theClient, "Your hostname must be made of letters (A-Z, a-z) and numbers (0-9).");
|
|
return true;
|
|
}
|
|
#endif
|
|
if (bot->HostIsReserved(st[2]))
|
|
{
|
|
#ifdef ADMINS_USE_RESTRICTED_SETHOSTS
|
|
bool isAdmin = bot->getAdminAccessLevel(theUser, false) > 0;
|
|
bool isCoder = bot->getCoderAccessLevel(theUser) > 0;
|
|
bool isOper = theClient->isOper();
|
|
if (!isAdmin && !isCoder && !isOper)
|
|
{
|
|
bot->Notice(theClient, "Setting a reserved or restricted hostname is not allowed.");
|
|
return true;
|
|
}
|
|
#else
|
|
bot->Notice(theClient, "Setting a reserved or restricted hostname is not allowed.");
|
|
return true;
|
|
#endif
|
|
}
|
|
string userWithHost = bot->HostIsRegisteredTo(st[2]);
|
|
if (!userWithHost.empty() && (userWithHost != theUser->getUserName()))
|
|
{
|
|
bot->Notice(theClient, "Sorry, that hostname is already used by someone else.");
|
|
return true;
|
|
}
|
|
theUser->setHostName(st[2]);
|
|
theUser->commit(theClient);
|
|
server->SendOutFakeHost(theClient, theUser->getHostName().c_str(), bot);
|
|
bot->Notice(theClient, "Your hostname is now set to %s", theUser->getHostName().c_str());
|
|
}
|
|
return true;
|
|
}
|
|
#endif
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::invalid_option,
|
|
string("Invalid option.")));
|
|
return true;
|
|
}
|
|
|
|
Channel* tmpChan = Network->findChannel(st[1]);
|
|
|
|
/* Is the channel registered? */
|
|
|
|
sqlChannel* theChan = bot->getChannelRecord(st[1]);
|
|
if(!theChan)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::chan_not_reg,
|
|
string("Sorry, %s isn't registered with me.")).c_str(),
|
|
st[1].c_str());
|
|
return false;
|
|
}
|
|
|
|
// Check level.
|
|
|
|
int level = bot->getEffectiveAccessLevel(theUser, theChan, false);
|
|
string option = string_upper(st[2]);
|
|
string value;
|
|
string reason;
|
|
|
|
if (st.size() < 4)
|
|
{
|
|
value = "";
|
|
}
|
|
else
|
|
{
|
|
value = string_upper(st[3]);
|
|
if (st.size() < 5)
|
|
reason = "";
|
|
else
|
|
reason = st.assemble(4);
|
|
}
|
|
|
|
/*
|
|
* Check the "Locked" status first, so admin's can bypas to turn it OFF :)
|
|
*/
|
|
|
|
if(option == "LOCKED")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::locked)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_LOCKED);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_LOCKED);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_LOCKED) ? "ON" : "OFF");
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Check if the channel is "Locked", if so, only allow admins to change settings.
|
|
*/
|
|
|
|
if(theChan->getFlag(sqlChannel::F_LOCKED))
|
|
{
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel < level::set::locked)
|
|
{
|
|
bot->Notice(theClient, "The channel settings for %s have been locked by a cservice"
|
|
" administrator and cannot be changed.", theChan->getName().c_str());
|
|
return(true);
|
|
}
|
|
}
|
|
|
|
if(option == "CAUTION")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if(admLevel < level::set::caution)
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::noreg)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_CAUTION);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_CAUTION);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_CAUTION) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "NOREG")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if(admLevel < level::set::noreg)
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::noreg)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_NOREG);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOREG);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOREG) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "SPECIAL")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::special)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_SPECIAL);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_SPECIAL);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_SPECIAL) ? "ON" : "OFF");
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
if(option == "NEVERREG")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::neverreg)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_NEVREG);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NEVREG);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NEVREG) ? "ON" : "OFF");
|
|
|
|
return true;
|
|
}
|
|
|
|
if(option == "NOPURGE")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::nopurge)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_NOPURGE);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOPURGE);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOPURGE) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "SUSPEND")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::suspend)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if (reason == "")
|
|
{
|
|
bot->Notice(theClient, "No reason given! You must specify a reason after ON/OFF");
|
|
return true;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_SUSPEND);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_SUSPEND);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
/* write a channel log entry */
|
|
string logmsg;
|
|
if (!theChan->getFlag(sqlChannel::F_SUSPEND))
|
|
logmsg += "un";
|
|
logmsg += "suspend reason: ";
|
|
logmsg += reason;
|
|
if (theChan->getFlag(sqlChannel::F_SUSPEND))
|
|
{
|
|
bot->writeChannelLog(theChan, theClient, sqlChannel::EV_SUSPEND, logmsg);
|
|
/* inform admin channel */
|
|
bot->logAdminMessage("%s (%s) has suspended %s",
|
|
theClient->getNickName().c_str(), theUser->getUserName().c_str(),
|
|
theChan->getName().c_str());
|
|
if (tmpChan) bot->deopAllOnChan(tmpChan); // Deop everyone. :)
|
|
} else {
|
|
bot->writeChannelLog(theChan, theClient, sqlChannel::EV_UNSUSPEND, logmsg);
|
|
/* inform admin channel */
|
|
bot->logAdminMessage("%s (%s) has unsuspended %s",
|
|
theClient->getNickName().c_str(), theUser->getUserName().c_str(),
|
|
theChan->getName().c_str());
|
|
}
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_SUSPEND) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "TEMPMAN")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::tempman)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_TEMP);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_TEMP);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_TEMP) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "VACATION")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::vacation)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_VACATION);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_VACATION);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_VACATION) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
/*
|
|
* Check the "NoForce" status first, so admin's can bypas to turn it OFF :)
|
|
*/
|
|
|
|
if(option == "NOFORCE")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::noforce)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_NOFORCE);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOFORCE);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOFORCE) ? "ON" : "OFF");
|
|
|
|
//TODO?
|
|
//bot->writeChannelLog(theChan, theClient, sqlChannel::EV_NOFORCE, "");
|
|
|
|
if (value == "ON") {
|
|
for(sqlChannel::forceMapType::const_iterator ptr = theChan->forceMap.begin();
|
|
ptr != theChan->forceMap.end(); ++ptr)
|
|
{
|
|
// Look up this username in the cache.
|
|
cservice::sqlUserHashType::iterator ptr2 = bot->sqlUserCache.find(ptr->second.second);
|
|
sqlUser* AdminUser = ptr2->second;
|
|
int ForceLevel = ptr->second.first;
|
|
|
|
//Now Remove force access who is not privileged :)
|
|
if (ForceLevel < level::immune::noforce)
|
|
{
|
|
bot->noticeAllAuthedClients(AdminUser,
|
|
bot->getResponse(AdminUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),"ON");
|
|
|
|
theChan->forceMap.erase(AdminUser->getID());
|
|
|
|
bot->noticeAllAuthedClients(AdminUser,
|
|
bot->getResponse(AdminUser,
|
|
language::rem_temp_access,
|
|
string("Removed your temporary access of %i from channel %s")).c_str(),
|
|
ForceLevel, theChan->getName().c_str());
|
|
}
|
|
} //for cycle
|
|
}//if (value == ON)
|
|
|
|
return true;
|
|
}
|
|
if(option == "MIA")
|
|
{
|
|
// Check for admin access
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if (admLevel == 0) {
|
|
// No need to tell users about admin commands.
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
if (admLevel < level::set::mia)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("Sorry, you have insufficient access to perform that command.")));
|
|
return false;
|
|
}
|
|
if(value == "ON") theChan->setFlag(sqlChannel::F_MIA);
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_MIA);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_MIA) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
|
|
if(option == "NOOP")
|
|
{
|
|
if(level < level::set::noop)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_NOOP);
|
|
if (tmpChan) bot->deopAllOnChan(tmpChan); // Deop everyone. :)
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOOP);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOOP) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "NOVOICE")
|
|
{
|
|
if(level < level::set::novoice)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_NOVOICE);
|
|
if (tmpChan) bot->deVoiceAllOnChan(tmpChan); // DeVoice everyone. :)
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOVOICE);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOVOICE) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "STRICTOP")
|
|
{
|
|
if(level < level::set::strictop)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_STRICTOP);
|
|
if (tmpChan) bot->deopAllUnAuthedOnChan(tmpChan);
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_STRICTOP);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_STRICTOP) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
#ifdef USE_NOTAKE
|
|
if(option == "NOTAKE")
|
|
{
|
|
if(level < level::set::notake)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_NOTAKE);
|
|
theChan->setNoTake(2); //default revenge is BAN
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_NOTAKE);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_NOTAKE) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
if(option == "TAKEREVENGE")
|
|
{
|
|
if(level < level::set::notake)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return false;
|
|
}
|
|
int setting;
|
|
if (value != "")
|
|
{
|
|
if (!IsNumeric(value))
|
|
{
|
|
if (value=="IGNORE")
|
|
setting = 1;
|
|
else if (value=="BAN")
|
|
setting = 2;
|
|
else if (value=="SUSPEND")
|
|
setting = 3;
|
|
else
|
|
setting = 4; /* dummy value to cause failure */
|
|
} else {
|
|
setting = atoi(value.c_str());
|
|
}
|
|
if ( (setting < 1) || (setting > 3))
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::userflags_syntax,
|
|
string("Invalid TAKEREVENGE setting. Correct values are IGNORE, BAN or SUSPEND.")));
|
|
return false;
|
|
}
|
|
theChan->setNoTake(setting);
|
|
theChan->commit();
|
|
} else {
|
|
setting = theChan->getNoTake();
|
|
}
|
|
/* set value to textual description */
|
|
switch (setting) {
|
|
default: break;
|
|
case 1: value = "IGNORE"; break;
|
|
case 2: value = "BAN"; break;
|
|
case 3: value = "SUSPEND"; break;
|
|
}
|
|
bot->Notice(theClient,"TAKEREVENGE for %s is %s",
|
|
theChan->getName().c_str(), value.c_str());
|
|
return true;
|
|
}
|
|
#endif
|
|
if(option == "AUTOTOPIC")
|
|
{
|
|
if(level < level::set::autotopic)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_AUTOTOPIC);
|
|
bot->doAutoTopic(theChan);
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_AUTOTOPIC);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_AUTOTOPIC) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "AUTOJOIN")
|
|
{
|
|
if(level < level::set::autojoin)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_AUTOJOIN);
|
|
theChan->setInChan(true);
|
|
bot->Join(theChan->getName(), "+R",
|
|
theChan->getChannelTS(), true);
|
|
bot->joinCount++;
|
|
/*if (tmpChan)
|
|
{
|
|
if(theChan->getFlag(sqlChannel::F_NOOP)) bot->deopAllOnChan(tmpChan);
|
|
if(theChan->getFlag(sqlChannel::F_STRICTOP)) bot->deopAllUnAuthedOnChan(tmpChan);
|
|
}*/
|
|
}
|
|
else if(value == "OFF")
|
|
{
|
|
theChan->removeFlag(sqlChannel::F_AUTOJOIN);
|
|
theChan->setInChan(false);
|
|
bot->joinCount--;
|
|
bot->Part(theChan->getName());
|
|
}
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_AUTOJOIN) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_AUTOJOIN) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "USERFLAGS")
|
|
{
|
|
if(level < level::set::userflag)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return false;
|
|
}
|
|
|
|
int setting;
|
|
if (value != "")
|
|
{
|
|
if (!IsNumeric(value))
|
|
{
|
|
if (value=="NONE")
|
|
setting = 0;
|
|
else if (value=="OP")
|
|
setting = 1;
|
|
else if (value=="HALFOP")
|
|
setting = 2;
|
|
else if (value=="VOICE")
|
|
setting = 3;
|
|
else
|
|
setting = 4; /* dummy value to cause failure */
|
|
} else {
|
|
setting = atoi(value.c_str());
|
|
}
|
|
if ( (setting < 0) || (setting > 3))
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::userflags_syntax,
|
|
string("Invalid USERFLAGS setting. Correct values are NONE, OP, HALFOP or VOICE.")));
|
|
return false;
|
|
}
|
|
|
|
theChan->setUserFlags(setting);
|
|
theChan->commit();
|
|
} else {
|
|
setting = theChan->getUserFlags();
|
|
}
|
|
/* set value to textual description */
|
|
switch (setting) {
|
|
default: break;
|
|
case 0: value = "NONE"; break;
|
|
case 1: value = "OP"; break;
|
|
case 2: value = "HALF"; break;
|
|
case 3: value = "VOICE"; break;
|
|
}
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::userflags_status,
|
|
string("USERFLAGS for %s is %s")).c_str(),
|
|
theChan->getName().c_str(), value.c_str());
|
|
return true;
|
|
}
|
|
|
|
if(option == "MASSDEOPPRO")
|
|
{
|
|
if(level < level::set::massdeoppro)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
// Temporary MASSDEOPPRO range! 0-7.. is this correct?
|
|
if(!IsNumeric(value))
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::massdeoppro_syntax,
|
|
string("value of MASSDEOPPRO has to be 0-7")));
|
|
return true;
|
|
}
|
|
int numValue = atoi(value.c_str());
|
|
if(numValue > 7 || numValue < 0)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::massdeoppro_syntax,
|
|
string("value of MASSDEOPPRO has to be 0-7")));
|
|
return true;
|
|
}
|
|
theChan->setMassDeopPro(numValue);
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::massdeoppro_status,
|
|
string("MASSDEOPPRO for %s is set to %d")).c_str(),
|
|
theChan->getName().c_str(), numValue);
|
|
return true;
|
|
}
|
|
|
|
if(option == "DESCRIPTION" || option == "DESC")
|
|
{
|
|
string desc = st.assemble(3);
|
|
if(level < level::set::desc)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(strlen(desc.c_str()) > 384)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::desc_max_len,
|
|
string("The DESCRIPTION can be a maximum of 384 chars!")));
|
|
return true;
|
|
}
|
|
theChan->setDescription(desc);
|
|
theChan->commit();
|
|
|
|
if(desc == "")
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::desc_cleared,
|
|
string("DESCRIPTION for %s is cleared.")).c_str(),
|
|
theChan->getName().c_str());
|
|
} else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::desc_status,
|
|
string("DESCRIPTION for %s is: %s")).c_str(),
|
|
theChan->getName().c_str(),
|
|
desc.c_str());
|
|
}
|
|
|
|
if (theChan->getFlag(sqlChannel::F_AUTOTOPIC))
|
|
{
|
|
bot->doAutoTopic(theChan);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if(option == "URL")
|
|
{
|
|
string url = st.assemble(3);
|
|
if(level < level::set::url)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(strlen(url.c_str()) > 128) // Gator - changed to 75
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::url_max_len,
|
|
string("The URL can be a maximum of 128 chars!")));
|
|
return true;
|
|
}
|
|
theChan->setURL(url);
|
|
theChan->commit();
|
|
|
|
if(url == "")
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::url_cleared,
|
|
string("URL for %s is cleared.")).c_str(),
|
|
theChan->getName().c_str());
|
|
} else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::url_status,
|
|
string("URL for %s is: %s")).c_str(),
|
|
theChan->getName().c_str(),
|
|
url.c_str());
|
|
}
|
|
|
|
if (theChan->getFlag(sqlChannel::F_AUTOTOPIC))
|
|
{
|
|
bot->doAutoTopic(theChan);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef USE_WELCOME
|
|
if(option == "WELCOME")
|
|
{
|
|
string welcome;
|
|
if (st.size() > 3)
|
|
welcome = st.assemble(3);
|
|
if (level < level::set::welcome)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if (strlen(welcome.c_str()) > 512)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::welcome_max_len,
|
|
string("The WELCOME can be a maximum of 512 chars!")));
|
|
return true;
|
|
}
|
|
|
|
if ((string_upper(welcome) == "OFF") || (welcome == ""))
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::welcome_cleared,
|
|
string("WELCOME for %s is cleared.")).c_str(),
|
|
theChan->getName().c_str());
|
|
theChan->setWelcome("");
|
|
theChan->commit();
|
|
}
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::welcome_status,
|
|
string("WELCOME for %s is: %s")).c_str(),
|
|
theChan->getName().c_str(),
|
|
welcome.c_str());
|
|
theChan->setWelcome(welcome);
|
|
theChan->commit();
|
|
}
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
if(option == "KEYWORDS")
|
|
{
|
|
/* Keywords are being processed as a long string. */
|
|
string keywords = st.assemble(3);
|
|
if(level < level::set::keywords)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(strlen(value.c_str()) > 80) // is 80 ok as an max keywords length?
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::keywords_max_len,
|
|
string("The string of keywords cannot exceed 80 chars!")));
|
|
return true;
|
|
}
|
|
theChan->setKeywords(keywords);
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::keywords_status,
|
|
string("KEYWORDS for %s are: %s")).c_str(),
|
|
theChan->getName().c_str(),
|
|
keywords.c_str());
|
|
return true;
|
|
}
|
|
|
|
if(option == "MODE")
|
|
{
|
|
if(level < level::set::mode)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if (!tmpChan)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::no_such_chan,
|
|
string("Can't locate channel %s on the network!")).c_str(),
|
|
st[1].c_str());
|
|
return false;
|
|
}
|
|
|
|
theChan->setChannelMode(tmpChan->getModeString());
|
|
theChan->commit();
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getChannelMode().c_str());
|
|
return true;
|
|
}
|
|
|
|
|
|
if(option == "COMMENT")
|
|
{
|
|
/* Check for admin access */
|
|
int admLevel = bot->getAdminAccessLevel(theUser);
|
|
if(admLevel < level::set::comment)
|
|
{
|
|
/* No need to tell users about admin commands. */
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
|
|
string comment = st.assemble(3);
|
|
|
|
if(comment.size() > 200)
|
|
{
|
|
bot->Notice(theClient, "The COMMENT can be a maximum of 200 chars!");
|
|
return true;
|
|
}
|
|
|
|
theChan->setComment(comment);
|
|
theChan->commit();
|
|
|
|
if(comment.empty())
|
|
{
|
|
bot->Notice(theClient, "COMMENT for %s is cleared.",
|
|
theChan->getName().c_str());
|
|
} else
|
|
{
|
|
bot->Notice(theClient, "COMMENT for %s is: %s",
|
|
theChan->getName().c_str(), comment.c_str());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
if(option == "FLOATLIM")
|
|
{
|
|
if(level < level::set::floatlim)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
if(value == "ON")
|
|
{
|
|
theChan->setFlag(sqlChannel::F_FLOATLIM);
|
|
}
|
|
else if(value == "OFF") theChan->removeFlag(sqlChannel::F_FLOATLIM);
|
|
else
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_syntax_on_off,
|
|
string("value of %s must be ON or OFF")).c_str(),
|
|
option.c_str());
|
|
return true;
|
|
}
|
|
theChan->commit();
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::set_cmd_status,
|
|
string("%s for %s is %s")).c_str(),
|
|
option.c_str(),
|
|
theChan->getName().c_str(),
|
|
theChan->getFlag(sqlChannel::F_FLOATLIM) ? "ON" : "OFF");
|
|
return true;
|
|
}
|
|
|
|
if(option == "FLOATMARGIN")
|
|
{
|
|
if(level < level::set::floatlim)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
|
|
unsigned int limit_offset = atoi(value.c_str());
|
|
|
|
if ((limit_offset <= 1) | (limit_offset > 20))
|
|
{
|
|
bot->Notice(theClient, "Invalid floating-limit Margin (2-20 Allowed).");
|
|
return true;
|
|
}
|
|
|
|
if (limit_offset <= theChan->getLimitGrace())
|
|
{
|
|
bot->Notice(theClient, "FLOATMARGIN cannot be less than or equal to FLOATGRACE.");
|
|
return true;
|
|
}
|
|
|
|
theChan->setLimitOffset(limit_offset);
|
|
theChan->commit();
|
|
|
|
bot->Notice(theClient, "Floating-limit Margin now set to %i", limit_offset);
|
|
return true;
|
|
}
|
|
|
|
if(option == "FLOATPERIOD")
|
|
{
|
|
if(level < level::set::floatlim)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
|
|
unsigned int limit_period = atoi(value.c_str());
|
|
|
|
if ((limit_period < 20) | (limit_period > 200))
|
|
{
|
|
bot->Notice(theClient, "Invalid floating-limit period (20-200 Allowed).");
|
|
return true;
|
|
}
|
|
|
|
theChan->setLimitPeriod(limit_period);
|
|
theChan->commit();
|
|
|
|
bot->Notice(theClient, "Floating-limit period now set to %i", limit_period);
|
|
return true;
|
|
}
|
|
|
|
if(option == "FLOATGRACE")
|
|
{
|
|
if(level < level::set::floatlim)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
|
|
unsigned int limit_grace = atoi(value.c_str());
|
|
|
|
if (limit_grace > 19)
|
|
{
|
|
bot->Notice(theClient, "Invalid floating-grace setting (0-19 Allowed).");
|
|
return true;
|
|
}
|
|
|
|
if (limit_grace > theChan->getLimitOffset())
|
|
{
|
|
bot->Notice(theClient, "FLOATGRACE cannot be greater than FLOATMARGIN.");
|
|
return true;
|
|
}
|
|
|
|
theChan->setLimitGrace(limit_grace);
|
|
theChan->commit();
|
|
|
|
bot->Notice(theClient, "Floating-limit grace now set to %i", limit_grace);
|
|
return true;
|
|
}
|
|
|
|
if(option == "FLOATMAX")
|
|
{
|
|
if(level < level::set::floatlim)
|
|
{
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::insuf_access,
|
|
string("You do not have enough access!")));
|
|
return true;
|
|
}
|
|
|
|
unsigned int limit_max = atoi(value.c_str());
|
|
|
|
if (limit_max > 65536)
|
|
{
|
|
bot->Notice(theClient, "Invalid floating-limit max (0-65536 Allowed).");
|
|
return true;
|
|
}
|
|
|
|
|
|
theChan->setLimitMax(limit_max);
|
|
theChan->commit();
|
|
|
|
if (!limit_max)
|
|
{
|
|
bot->Notice(theClient, "Floating-limit MAX setting has now been disabled.");
|
|
} else {
|
|
bot->Notice(theClient, "Floating-limit max now set to %i", limit_max);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bot->Notice(theClient,
|
|
bot->getResponse(theUser,
|
|
language::mode_invalid,
|
|
string("ERROR: Invalid channel setting.")));
|
|
return true ;
|
|
}
|
|
|
|
} // namespace gnuworld.
|