1
0
mirror of https://github.com/anope/anope.git synced 2026-06-12 17:04:47 +02:00
Files
2026-01-01 18:07:12 +00:00

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> &params) 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)