mirror of
https://github.com/anope/anope.git
synced 2026-06-12 17:04:47 +02:00
178 lines
4.2 KiB
C++
178 lines
4.2 KiB
C++
// Anope IRC Services <https://www.anope.org/>
|
|
//
|
|
// Copyright (C) 2003-2026 Anope Contributors
|
|
//
|
|
// Anope is free software. You can use, modify, and/or distribute it under the
|
|
// terms of version 2 of the GNU General Public License. See docs/LICENSE.txt
|
|
// for the complete terms of this license and docs/AUTHORS.txt for a list of
|
|
// contributors.
|
|
//
|
|
// Based on the original code of Epona by Lara
|
|
// Based on the original code of Services by Andy Church
|
|
//
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
#include "module.h"
|
|
#include "modules/global/service.h"
|
|
|
|
class GlobalCore final
|
|
: public Module
|
|
, public Global::Service
|
|
{
|
|
private:
|
|
Reference<BotInfo> global;
|
|
PrimitiveExtensibleItem<std::vector<Anope::string>> queue;
|
|
|
|
void ServerGlobal(BotInfo *sender, Server *server, bool children, const Anope::string &message)
|
|
{
|
|
if (server != Me && !server->IsJuped())
|
|
server->Notice(sender, message);
|
|
|
|
if (children)
|
|
{
|
|
for (auto *link : server->GetLinks())
|
|
this->ServerGlobal(sender, link, true, message);
|
|
}
|
|
}
|
|
|
|
public:
|
|
GlobalCore(const Anope::string &modname, const Anope::string &creator)
|
|
: Module(modname, creator, PSEUDOCLIENT | VENDOR)
|
|
, Global::Service(this)
|
|
, queue(this, "global-queue")
|
|
{
|
|
}
|
|
|
|
void ClearQueue(NickCore *nc) override
|
|
{
|
|
queue.Unset(nc);
|
|
}
|
|
|
|
Reference<BotInfo> GetDefaultSender() const override
|
|
{
|
|
return global;
|
|
}
|
|
|
|
const std::vector<Anope::string> *GetQueue(NickCore* nc) const override
|
|
{
|
|
return queue.Get(nc);
|
|
}
|
|
|
|
size_t Queue(NickCore *nc, const Anope::string &message) override
|
|
{
|
|
auto *q = queue.Require(nc);
|
|
q->push_back(message);
|
|
return q->size();
|
|
}
|
|
|
|
void OnReload(Configuration::Conf &conf) override
|
|
{
|
|
const auto glnick = conf.GetModule(this).Get<const Anope::string>("client");
|
|
if (glnick.empty())
|
|
throw ConfigException(Module::name + ": <client> must be defined");
|
|
|
|
auto *bi = BotInfo::Find(glnick, true);
|
|
if (!bi)
|
|
throw ConfigException(Module::name + ": no bot named " + glnick);
|
|
|
|
global = bi;
|
|
}
|
|
|
|
void OnRestart() override
|
|
{
|
|
const auto msg = Config->GetModule(this).Get<const Anope::string>("globaloncycledown");
|
|
if (!msg.empty())
|
|
this->SendSingle(msg, nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
void OnShutdown() override
|
|
{
|
|
const auto msg = Config->GetModule(this).Get<const Anope::string>("globaloncycledown");
|
|
if (!msg.empty())
|
|
this->SendSingle(msg, nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
void OnNewServer(Server *s) override
|
|
{
|
|
const auto msg = Config->GetModule(this).Get<const Anope::string>("globaloncycleup");
|
|
if (!msg.empty() && !Me->IsSynced())
|
|
s->Notice(global, msg);
|
|
}
|
|
|
|
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
|
{
|
|
if (!params.empty() || source.c || source.service != *global)
|
|
return EVENT_CONTINUE;
|
|
|
|
source.Reply(_("%s commands:"), global->nick.c_str());
|
|
return EVENT_CONTINUE;
|
|
}
|
|
|
|
bool SendQueue(CommandSource &source, BotInfo *sender, Server *server) override
|
|
{
|
|
// We MUST have an account.
|
|
if (!source.nc)
|
|
return false;
|
|
|
|
// We MUST have a message queue.
|
|
auto *q = queue.Get(source.nc);
|
|
if (!q || q->empty())
|
|
return false;
|
|
|
|
auto success = true;
|
|
for (const auto &message : *q)
|
|
{
|
|
if (!SendSingle(message, &source, sender, server))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
queue.Unset(source.nc);
|
|
return success;
|
|
}
|
|
|
|
bool SendSingle(const Anope::string &message, CommandSource *source, BotInfo* sender, Server* server) override
|
|
{
|
|
// We MUST have a sender.
|
|
if (!sender)
|
|
sender = global;
|
|
if (!sender)
|
|
return false;
|
|
|
|
Anope::string line;
|
|
if (source && !Config->GetModule(this).Get<bool>("anonymousglobal"))
|
|
{
|
|
// A source is available and they're not anonymous.
|
|
line = Anope::Format("[%s] %s", source->GetNick().c_str(), message.c_str());
|
|
}
|
|
else
|
|
{
|
|
// A source isn't available or they're anonymous.
|
|
line = message.empty() ? " " : message;
|
|
}
|
|
|
|
if (server)
|
|
this->ServerGlobal(sender, server, false, line);
|
|
else
|
|
this->ServerGlobal(sender, Servers::GetUplink(), true, line);
|
|
return true;
|
|
}
|
|
|
|
bool Unqueue(NickCore *nc, size_t idx) override
|
|
{
|
|
auto *q = queue.Get(nc);
|
|
if (!q || idx > q->size())
|
|
return false;
|
|
|
|
q->erase(q->begin() + idx);
|
|
if (q->empty())
|
|
queue.Unset(nc);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
MODULE_INIT(GlobalCore)
|