1
0
mirror of https://github.com/anope/anope.git synced 2026-06-27 19:26:41 +02:00
Files
anope/modules/commands/ns_ajoin.cpp
T
Robby- bf67b9ee5c Make column titles in listings translatable.
Make some more strings translatable, and remove some that don't need translation at all.

Make expirytimes and units translatable.

Make predefined messages in listings also translatable.

Make the remaining command descriptions translatable.

Make some ns/cs info strings equal to dedupe in translation file. Add missing no-autoop setting to cs info output. Make some strings translatable.
2013-09-27 19:11:02 -04:00

330 lines
8.2 KiB
C++

/* NickServ core functions
*
* (C) 2003-2013 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
#include "module.h"
struct AJoinEntry;
struct AJoinList : Serialize::Checker<std::vector<AJoinEntry *> >
{
AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
~AJoinList();
};
struct AJoinEntry : Serializable
{
Serialize::Reference<NickCore> owner;
Anope::string channel;
Anope::string key;
AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
~AJoinEntry()
{
AJoinList *channels = owner->GetExt<AJoinList>("ajoinlist");
if (channels)
{
std::vector<AJoinEntry *>::iterator it = std::find((*channels)->begin(), (*channels)->end(), this);
if (it != (*channels)->end())
(*channels)->erase(it);
}
}
void Serialize(Serialize::Data &sd) const anope_override
{
if (!this->owner)
return;
sd["owner"] << this->owner->display;
sd["channel"] << this->channel;
sd["key"] << this->key;
}
static Serializable* Unserialize(Serializable *obj, Serialize::Data &sd)
{
Anope::string sowner;
sd["owner"] >> sowner;
NickCore *nc = NickCore::Find(sowner);
if (nc == NULL)
return NULL;
AJoinEntry *aj;
if (obj)
aj = anope_dynamic_static_cast<AJoinEntry *>(obj);
else
{
aj = new AJoinEntry(nc);
aj->owner = nc;
}
sd["channel"] >> aj->channel;
sd["key"] >> aj->key;
if (!obj)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
(*channels)->push_back(aj);
}
return aj;
}
};
AJoinList::~AJoinList()
{
for (unsigned i = 0; i < (*this)->size(); ++i)
delete (*this)->at(i);
}
class CommandNSAJoin : public Command
{
void DoList(CommandSource &source, NickCore *nc)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
if ((*channels)->empty())
source.Reply(_("%s's auto join list is empty."), nc->display.c_str());
else
{
ListFormatter list(source.GetAccount());
list.AddColumn(_("Number")).AddColumn(_("Channel")).AddColumn(_("Key"));
for (unsigned i = 0; i < (*channels)->size(); ++i)
{
AJoinEntry *aj = (*channels)->at(i);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Channel"] = aj->channel;
entry["Key"] = aj->key;
list.AddEntry(entry);
}
source.Reply(_("%s's auto join list:"), nc->display.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
}
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chan, const Anope::string &key)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
unsigned i = 0;
for (; i < (*channels)->size(); ++i)
if ((*channels)->at(i)->channel.equals_ci(chan))
break;
if (*source.nc == nc && (*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"))
source.Reply(_("Your auto join list is full."));
else if (i != (*channels)->size())
source.Reply(_("%s is already on %s's auto join list."), chan.c_str(), nc->display.c_str());
else if (IRCD->IsChannelValid(chan) == false)
source.Reply(CHAN_X_INVALID, chan.c_str());
else
{
AJoinEntry *entry = new AJoinEntry(nc);
entry->owner = nc;
entry->channel = chan;
entry->key = key;
(*channels)->push_back(entry);
source.Reply(_("Added %s to %s's auto join list."), chan.c_str(), nc->display.c_str());
}
}
void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chan)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
unsigned i = 0;
for (; i < (*channels)->size(); ++i)
if ((*channels)->at(i)->channel.equals_ci(chan))
break;
if (i == (*channels)->size())
source.Reply(_("%s was not found on %s's auto join list."), chan.c_str(), nc->display.c_str());
else
{
delete (*channels)->at(i);
source.Reply(_("%s was removed from %s's auto join list."), chan.c_str(), nc->display.c_str());
}
if ((*channels)->empty())
nc->Shrink<AJoinList>("ajoinlist");
}
public:
CommandNSAJoin(Module *creator) : Command(creator, "nickserv/ajoin", 1, 3)
{
this->SetDesc(_("Manage your auto join list"));
this->SetSyntax(_("ADD [\037user\037] \037channel\037 [\037key\037]"));
this->SetSyntax(_("DEL [\037user\037] \037channel\037"));
this->SetSyntax(_("LIST [\037user\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
NickCore *nc = source.GetAccount();
Anope::string param, param2;
if (params.size() > 1 && source.IsServicesOper() && IRCD->IsNickValid(params[1]))
{
NickAlias *na = NickAlias::Find(params[1]);
if (!na)
{
source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str());
return;
}
nc = na->nc;
param = params.size() > 2 ? params[2] : "";
param2 = params.size() > 3 ? params[3] : "";
}
else
{
param = params.size() > 1 ? params[1] : "";
param2 = params.size() > 2 ? params[2] : "";
}
if (params[0].equals_ci("LIST"))
this->DoList(source, nc);
else if (param.empty())
this->OnSyntaxError(source, "");
else if (Anope::ReadOnly)
source.Reply(READ_ONLY_MODE);
else if (params[0].equals_ci("ADD"))
this->DoAdd(source, nc, param, param2);
else if (params[0].equals_ci("DEL"))
this->DoDel(source, nc, param);
else
this->OnSyntaxError(source, "");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("This command manages your auto join list. When you identify\n"
"you will automatically join the channels on your auto join list.\n"
"Services Operators may provide a nick to modify other users'\n"
"auto join lists."));
return true;
}
};
class NSAJoin : public Module
{
CommandNSAJoin commandnsajoin;
ExtensibleItem<AJoinList> ajoinlist;
Serialize::Type ajoinentry_type;
public:
NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsajoin(this), ajoinlist(this, "ajoinlist"),
ajoinentry_type("AJoinEntry", AJoinEntry::Unserialize)
{
if (!IRCD->CanSVSJoin)
throw ModuleException("Your IRCd does not support SVSJOIN");
}
void OnNickIdentify(User *u) anope_override
{
BotInfo *NickServ = Config->GetClient("NickServ");
if (!NickServ)
return;
AJoinList *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
if (channels == NULL)
channels = u->Account()->Extend<AJoinList>("ajoinlist");
for (unsigned i = 0; i < (*channels)->size(); ++i)
{
AJoinEntry *entry = (*channels)->at(i);
Channel *c = Channel::Find(entry->channel);
ChannelInfo *ci;
if (c)
ci = c->ci;
else
ci = ChannelInfo::Find(entry->channel);
bool need_invite = false;
Anope::string key = entry->key;
AccessGroup u_access;
if (ci != NULL)
{
if (ci->HasExt("CS_SUSPENDED"))
continue;
u_access = ci->AccessFor(u);
}
if (c != NULL)
{
if (c->FindUser(u) != NULL)
continue;
else if (c->HasMode("OPERONLY") && !u->HasMode("OPER"))
continue;
else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN"))
continue;
else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExt("ssl")))
continue;
else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false)
need_invite = true;
else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false)
need_invite = true;
if (c->HasMode("KEY"))
{
Anope::string k;
if (c->GetParam("KEY", k))
{
if (u_access.HasPriv("GETKEY"))
key = k;
else if (key != k)
need_invite = true;
}
}
if (c->HasMode("LIMIT"))
{
Anope::string l;
if (c->GetParam("LIMIT", l))
{
try
{
unsigned limit = convertTo<unsigned>(l);
if (c->users.size() >= limit)
need_invite = true;
}
catch (const ConvertException &) { }
}
}
}
if (need_invite && c != NULL)
{
if (!u_access.HasPriv("INVITE"))
continue;
IRCD->SendInvite(NickServ, c, u);
}
IRCD->SendSVSJoin(NickServ, u, entry->channel, key);
}
}
};
MODULE_INIT(NSAJoin)