summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/nickserv.example.conf2
-rw-r--r--docs/XMLRPC/XMLRPC2
-rw-r--r--include/xline.h2
-rw-r--r--modules/commands/cs_access.cpp4
-rw-r--r--modules/commands/cs_akick.cpp6
-rw-r--r--modules/commands/hs_off.cpp3
-rw-r--r--modules/commands/hs_on.cpp2
-rw-r--r--modules/commands/ns_getemail.cpp11
-rw-r--r--modules/commands/os_news.cpp16
-rw-r--r--modules/m_xmlrpc_main.cpp17
-rw-r--r--modules/protocol/inspircd12.cpp3
-rw-r--r--modules/pseudoclients/nickserv.cpp2
-rw-r--r--src/tools/anoperc.in2
-rw-r--r--src/xline.cpp36
14 files changed, 85 insertions, 23 deletions
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf
index e12d5ec2b..4b383f80e 100644
--- a/data/nickserv.example.conf
+++ b/data/nickserv.example.conf
@@ -79,7 +79,7 @@ module
confirmemailchanges = no
/*
- * A message sent to users on connect if they use an unregistered nick.
+ * A message sent to users on connect if they use an unregistered nick. %n will be replaced with the user's nickname.
*
* This directive is optional.
*/
diff --git a/docs/XMLRPC/XMLRPC b/docs/XMLRPC/XMLRPC
index 95a18abc4..ee655cb19 100644
--- a/docs/XMLRPC/XMLRPC
+++ b/docs/XMLRPC/XMLRPC
@@ -17,6 +17,8 @@ channel - Takes one parameter, a channel name, and returns real time information
user - Takes one parameter, a user name, and returns real time information regarding that user.
+notice - Takes three parameters, source user, target user, and message. Sends a message to the user.
+
XMLRPC was designed to be used with db_sql, and will not return any information that can be pulled from the SQL
database, such as accounts and registered channel information. It is instead used for pulling realtime data such
as users and channels currently online. For examples on how to use these calls in PHP, see xmlrpc.php in docs/XMLRPC.
diff --git a/include/xline.h b/include/xline.h
index 2eae08dc8..50d17464f 100644
--- a/include/xline.h
+++ b/include/xline.h
@@ -113,6 +113,8 @@ class CoreExport XLineManager : public Service
*/
void AddXLine(XLine *x);
+ void RemoveXLine(XLine *);
+
/** Delete an entry from this XLineManager
* @param x The entry
* @return true if the entry was found and deleted, else false
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 2fba96a9a..2e8212383 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -891,9 +891,9 @@ class CSAccess : public Module
{
if (group->ci == NULL)
return EVENT_CONTINUE;
- /* Special case. Allows a level of < 0 to match anyone, and a level of 0 to match anyone identified. */
+ /* Special case. Allows a level of -1 to match anyone, and a level of 0 to match anyone identified. */
int16_t level = group->ci->GetLevel(priv);
- if (level < 0)
+ if (level == -1)
return EVENT_ALLOW;
else if (level == 0 && group->nc)
return EVENT_ALLOW;
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
index 03db4c623..327b98b09 100644
--- a/modules/commands/cs_akick.cpp
+++ b/modules/commands/cs_akick.cpp
@@ -554,7 +554,11 @@ class CSAKick : public Module
mask = autokick->mask;
reason = autokick->reason;
if (reason.empty())
- reason = Language::Translate(u, Config->GetModule(this)->Get<const Anope::string>("autokickreason").c_str());
+ {
+ reason = Language::Translate(u, Config->GetModule(this)->Get<const Anope::string>("autokickreason").c_str())
+ .replace_all_cs("%n", u->nick)
+ .replace_all_cs("%c", c->name);
+ }
if (reason.empty())
reason = Language::Translate(u, _("User has been banned from the channel"));
return EVENT_STOP;
diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp
index 603b863c1..d0a64fb5b 100644
--- a/modules/commands/hs_off.cpp
+++ b/modules/commands/hs_off.cpp
@@ -23,7 +23,10 @@ class CommandHSOff : public Command
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
User *u = source.GetUser();
+
const NickAlias *na = NickAlias::Find(u->nick);
+ if (!na || na->nc != u->Account() || !na->HasVhost())
+ na = NickAlias::Find(u->Account()->display);
if (!na || !na->HasVhost())
source.Reply(HOST_NOT_ASSIGNED);
diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp
index d59206e27..26fa6266f 100644
--- a/modules/commands/hs_on.cpp
+++ b/modules/commands/hs_on.cpp
@@ -27,6 +27,8 @@ class CommandHSOn : public Command
User *u = source.GetUser();
const NickAlias *na = NickAlias::Find(u->nick);
+ if (!na || na->nc != u->Account() || !na->HasVhost())
+ na = NickAlias::Find(u->Account()->display);
if (na && u->Account() == na->nc && na->HasVhost())
{
if (!na->GetVhostIdent().empty())
diff --git a/modules/commands/ns_getemail.cpp b/modules/commands/ns_getemail.cpp
index 8d7976bb0..39239e86f 100644
--- a/modules/commands/ns_getemail.cpp
+++ b/modules/commands/ns_getemail.cpp
@@ -35,16 +35,16 @@ class CommandNSGetEMail : public Command
{
const NickCore *nc = it->second;
- if (!nc->email.empty() && nc->email.equals_ci(email))
+ if (!nc->email.empty() && Anope::Match(nc->email, email))
{
++j;
- source.Reply(_("Email matched: \002%s\002 to \002%s\002."), nc->display.c_str(), email.c_str());
+ source.Reply(_("Email matched: \002%s\002 (\002%s\002) to \002%s\002."), nc->display.c_str(), nc->email.c_str(), email.c_str());
}
}
if (j <= 0)
{
- source.Reply(_("No nick registrations matching \002%s\002 found."), email.c_str());
+ source.Reply(_("No registrations matching \002%s\002 were found."), email.c_str());
return;
}
@@ -55,10 +55,7 @@ class CommandNSGetEMail : public Command
{
this->SendSyntax(source);
source.Reply(" ");
- source.Reply(_("Returns the matching nicks that used given email. \002Note\002 that\n"
- "you can not use wildcards. Whenever this command is used, a message\n"
- "including the person who issued the command and the email it was used\n"
- "on will be logged."));
+ source.Reply(_("Returns the matching accounts that used given email."));
return true;
}
};
diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp
index b74ca3b57..a0dc13407 100644
--- a/modules/commands/os_news.cpp
+++ b/modules/commands/os_news.cpp
@@ -403,23 +403,27 @@ class OSNews : public Module
else if (Type == NEWS_RANDOM)
msg = _("[\002Random News\002 - %s] %s");
- unsigned displayed = 0;
- for (unsigned i = 0, end = newsList.size(); i < end; ++i)
+ int start = 0;
+
+ if (type != NEWS_RANDOM)
+ {
+ start = newsList.size() - news_count;
+ if (start < 0)
+ start = 0;
+ }
+
+ for (unsigned i = start, end = newsList.size(); i < end; ++i)
{
if (Type == NEWS_RANDOM && i != cur_rand_news)
continue;
u->SendMessage(bi, msg.c_str(), Anope::strftime(newsList[i]->time, u->Account(), true).c_str(), newsList[i]->text.c_str());
- ++displayed;
-
if (Type == NEWS_RANDOM)
{
++cur_rand_news;
break;
}
- else if (displayed >= news_count)
- break;
}
/* Reset to head of list to get first random news value */
diff --git a/modules/m_xmlrpc_main.cpp b/modules/m_xmlrpc_main.cpp
index 13645bc98..38cb4a8d7 100644
--- a/modules/m_xmlrpc_main.cpp
+++ b/modules/m_xmlrpc_main.cpp
@@ -59,6 +59,8 @@ class MyXMLRPCEvent : public XMLRPCEvent
this->DoUser(iface, client, request);
else if (request.name == "opers")
this->DoOperType(iface, client, request);
+ else if (request.name == "notice")
+ this->DoNotice(iface, client, request);
return true;
}
@@ -249,6 +251,21 @@ class MyXMLRPCEvent : public XMLRPCEvent
request.reply(ot->GetName(), perms);
}
}
+
+ void DoNotice(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
+ {
+ Anope::string from = request.data.size() > 0 ? request.data[0] : "";
+ Anope::string to = request.data.size() > 1 ? request.data[1] : "";
+ Anope::string message = request.data.size() > 2 ? request.data[2] : "";
+
+ BotInfo *bi = BotInfo::Find(from, true);
+ User *u = User::Find(to, true);
+
+ if (!bi || !u || message.empty())
+ return;
+
+ u->SendMessage(bi, message);
+ }
};
class ModuleXMLRPCMain : public Module
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index e3c61a442..c5c3a40e4 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -216,7 +216,8 @@ class InspIRCd12Proto : public IRCDProto
void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf) anope_override
{
- UplinkSocket::Message() << "PUSH " << dest << " ::" << Me->GetName() << " " << numeric << " " << dest << " " << buf;
+ User *u = User::Find(dest);
+ UplinkSocket::Message() << "PUSH " << dest << " ::" << Me->GetName() << " " << numeric << " " << (u ? u->nick : dest) << " " << buf;
}
void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override
diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp
index ee1049195..5d3579ced 100644
--- a/modules/pseudoclients/nickserv.cpp
+++ b/modules/pseudoclients/nickserv.cpp
@@ -400,7 +400,7 @@ class NickServCore : public Module, public NickServService
const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string>("unregistered_notice");
if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na && !u->Account())
- u->SendMessage(NickServ, unregistered_notice);
+ u->SendMessage(NickServ, unregistered_notice.replace_all_cs("%n", u->nick));
else if (na && !u->IsIdentified(true))
this->Validate(u);
}
diff --git a/src/tools/anoperc.in b/src/tools/anoperc.in
index 5f4e6c5eb..6fef1a125 100644
--- a/src/tools/anoperc.in
+++ b/src/tools/anoperc.in
@@ -16,7 +16,7 @@
ANOPEPID="@INSTDIR@/data/services.pid"
ANOPROG="@INSTDIR@/bin/services"
-LOG="@INSTDIR@/data/logs/"
+LOG="@INSTDIR@/logs/"
ARCVERSION="2"
isAnopeRunning () {
diff --git a/src/xline.cpp b/src/xline.cpp
index 8f02b930e..49341072f 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -107,6 +107,9 @@ XLine::XLine(const Anope::string &ma, const Anope::string &b, const time_t ex, c
XLine::~XLine()
{
+ if (manager)
+ manager->RemoveXLine(this);
+
delete regex;
delete c;
}
@@ -291,6 +294,30 @@ void XLineManager::AddXLine(XLine *x)
x->manager = this;
}
+void XLineManager::RemoveXLine(XLine *x)
+{
+ /* called from the destructor */
+
+ std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x);
+
+ if (!x->id.empty())
+ {
+ std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->id), it3 = XLinesByUID->upper_bound(x->id);
+ for (; it2 != XLinesByUID->end() && it2 != it3; ++it2)
+ if (it2->second == x)
+ {
+ XLinesByUID->erase(it2);
+ break;
+ }
+ }
+
+ if (it != this->xlines->end())
+ {
+ this->SendDel(x);
+ this->xlines->erase(it);
+ }
+}
+
bool XLineManager::DelXLine(XLine *x)
{
std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x);
@@ -310,6 +337,7 @@ bool XLineManager::DelXLine(XLine *x)
{
this->SendDel(x);
+ x->manager = NULL; // Don't call remove
delete x;
this->xlines->erase(it);
@@ -331,14 +359,16 @@ XLine* XLineManager::GetEntry(unsigned index)
void XLineManager::Clear()
{
- for (unsigned i = 0; i < this->xlines->size(); ++i)
+ std::vector<XLine *> xl;
+ this->xlines->swap(xl);
+
+ for (unsigned i = 0; i < xl.size(); ++i)
{
- XLine *x = this->xlines->at(i);
+ XLine *x = xl[i];
if (!x->id.empty())
XLinesByUID->erase(x->id);
delete x;
}
- this->xlines->clear();
}
bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason)