diff options
Diffstat (limited to 'include/modules')
29 files changed, 712 insertions, 315 deletions
diff --git a/include/modules/bs_badwords.h b/include/modules/bs_badwords.h index db5e6c461..ae78df8b1 100644 --- a/include/modules/bs_badwords.h +++ b/include/modules/bs_badwords.h @@ -9,6 +9,8 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + /** Flags for badwords */ enum BadWordType @@ -30,27 +32,27 @@ struct BadWord Anope::string word; BadWordType type; - virtual ~BadWord() { } - protected: - BadWord() { } + virtual ~BadWord() = default; +protected: + BadWord() = default; }; struct BadWords { - virtual ~BadWords() { } + virtual ~BadWords() = default; /** Add a badword to the badword list * @param word The badword * @param type The type (SINGLE START END) * @return The badword */ - virtual BadWord* AddBadWord(const Anope::string &word, BadWordType type) = 0; + virtual BadWord *AddBadWord(const Anope::string &word, BadWordType type) = 0; /** Get a badword structure by index * @param index The index * @return The badword */ - virtual BadWord* GetBadWord(unsigned index) const = 0; + virtual BadWord *GetBadWord(unsigned index) const = 0; /** Get how many badwords are on this channel * @return The number of badwords in the vector diff --git a/include/modules/bs_kick.h b/include/modules/bs_kick.h index e9bcc7fdf..8ad44aab5 100644 --- a/include/modules/bs_kick.h +++ b/include/modules/bs_kick.h @@ -9,6 +9,8 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + /* Indices for TTB (Times To Ban) */ enum { @@ -35,10 +37,10 @@ struct KickerData bool dontkickops, dontkickvoices; - protected: - KickerData() { } +protected: + KickerData() = default; - public: - virtual ~KickerData() { } +public: + virtual ~KickerData() = default; virtual void Check(ChannelInfo *ci) = 0; }; diff --git a/include/modules/cs_entrymsg.h b/include/modules/cs_entrymsg.h index a7ec337e0..2672f8ac0 100644 --- a/include/modules/cs_entrymsg.h +++ b/include/modules/cs_entrymsg.h @@ -6,6 +6,8 @@ * Please read COPYING and README for further details. */ +#pragma once + struct EntryMsg { Anope::string chan; @@ -13,22 +15,23 @@ struct EntryMsg Anope::string message; time_t when; - virtual ~EntryMsg() { } - protected: - EntryMsg() { } + virtual ~EntryMsg() = default; +protected: + EntryMsg() = default; }; -struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> > +struct EntryMessageList + : Serialize::Checker<std::vector<EntryMsg *> > { - protected: +protected: EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { } - public: +public: virtual ~EntryMessageList() { for (unsigned i = (*this)->size(); i > 0; --i) delete (*this)->at(i - 1); } - virtual EntryMsg* Create() = 0; + virtual EntryMsg *Create() = 0; }; diff --git a/include/modules/cs_log.h b/include/modules/cs_log.h index 1615c5b9f..f9549126b 100644 --- a/include/modules/cs_log.h +++ b/include/modules/cs_log.h @@ -9,6 +9,8 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + struct LogSetting { Anope::string chan; @@ -22,21 +24,22 @@ struct LogSetting Anope::string creator; time_t created; - virtual ~LogSetting() { } - protected: - LogSetting() { } + virtual ~LogSetting() = default; +protected: + LogSetting() = default; }; -struct LogSettings : Serialize::Checker<std::vector<LogSetting *> > +struct LogSettings + : Serialize::Checker<std::vector<LogSetting *> > { typedef std::vector<LogSetting *>::iterator iterator; - protected: +protected: LogSettings() : Serialize::Checker<std::vector<LogSetting *> >("LogSetting") { } - public: - virtual ~LogSettings() { } +public: + virtual ~LogSettings() = default; virtual LogSetting *Create() = 0; }; diff --git a/include/modules/cs_mode.h b/include/modules/cs_mode.h index 9ef04da68..f3668c004 100644 --- a/include/modules/cs_mode.h +++ b/include/modules/cs_mode.h @@ -9,6 +9,8 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + struct ModeLock { Anope::string ci; @@ -18,16 +20,16 @@ struct ModeLock Anope::string setter; time_t created; - virtual ~ModeLock() { } - protected: - ModeLock() { } + virtual ~ModeLock() = default; +protected: + ModeLock() = default; }; struct ModeLocks { typedef std::vector<ModeLock *> ModeList; - virtual ~ModeLocks() { } + virtual ~ModeLocks() = default; /** Check if a mode is mlocked * @param mode The mode diff --git a/include/modules/dns.h b/include/modules/dns.h index 1aee0623e..1ab18a20f 100644 --- a/include/modules/dns.h +++ b/include/modules/dns.h @@ -9,8 +9,7 @@ * Based on the original code of Services by Andy Church. */ -#ifndef DNS_H -#define DNS_H +#pragma once namespace DNS { @@ -73,14 +72,14 @@ namespace DNS struct Question { Anope::string name; - QueryType type; - unsigned short qclass; + QueryType type = QUERY_NONE; + unsigned short qclass = 0; - Question() : type(QUERY_NONE), qclass(0) { } + Question() = default; Question(const Anope::string &n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { } inline bool operator==(const Question & other) const { return name == other.name && type == other.type && qclass == other.qclass; } - struct hash + struct hash final { size_t operator()(const Question &q) const { @@ -89,14 +88,15 @@ namespace DNS }; }; - struct ResourceRecord : Question + struct ResourceRecord final + : Question { - unsigned int ttl; + unsigned int ttl = 0; Anope::string rdata; time_t created; - ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(Anope::CurTime) { } - ResourceRecord(const Question &q) : Question(q), ttl(0), created(Anope::CurTime) { } + ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), created(Anope::CurTime) { } + ResourceRecord(const Question &q) : Question(q), created(Anope::CurTime) { } }; struct Query @@ -114,11 +114,12 @@ namespace DNS /** DNS manager */ - class Manager : public Service + class Manager + : public Service { - public: + public: Manager(Module *creator) : Service(creator, "DNS::Manager", "dns/manager") { } - virtual ~Manager() { } + virtual ~Manager() = default; virtual void Process(Request *req) = 0; virtual void RemoveRequest(Request *req) = 0; @@ -132,19 +133,27 @@ namespace DNS /** A DNS query. */ - class Request : public Timer, public Question + class Request + : public Timer + , public Question { Manager *manager; - public: + public: /* Use result cache if available */ bool use_cache; /* Request id */ - unsigned short id; + unsigned short id = 0; /* Creator of this request */ Module *creator; - Request(Manager *mgr, Module *c, const Anope::string &addr, QueryType qt, bool cache = false) : Timer(0), Question(addr, qt), manager(mgr), - use_cache(cache), id(0), creator(c) { } + Request(Manager *mgr, Module *c, const Anope::string &addr, QueryType qt, bool cache = false) + : Timer(0) + , Question(addr, qt) + , manager(mgr) + , use_cache(cache) + , creator(c) + { + } virtual ~Request() { @@ -164,7 +173,7 @@ namespace DNS /** Used to time out the query, xalls OnError and lets the TimerManager * delete this request. */ - void Tick(time_t) anope_override + void Tick() override { Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name; Query rr(*this); @@ -174,5 +183,3 @@ namespace DNS }; } // namespace DNS - -#endif // DNS_H diff --git a/include/modules/encryption.h b/include/modules/encryption.h index 7f8988c09..9c5b58627 100644 --- a/include/modules/encryption.h +++ b/include/modules/encryption.h @@ -9,27 +9,139 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + namespace Encryption { - typedef std::pair<const unsigned char *, size_t> Hash; - typedef std::pair<const uint32_t *, size_t> IV; - + /** Base class for encryption contexts. */ class Context { - public: - virtual ~Context() { } + public: + virtual ~Context() = default; + + /** Updates the encryption context with the specified data. + * @param str The data to update the context with. + */ + inline void Update(const Anope::string &str) + { + Update(reinterpret_cast<const unsigned char *>(str.c_str()), str.length()); + } + + /** Updates the encryption context with the specified data. + * @param data The data to update the context with. + * @param len The length of the data. + */ virtual void Update(const unsigned char *data, size_t len) = 0; - virtual void Finalize() = 0; - virtual Hash GetFinalizedHash() = 0; + + /** Finalises the encryption context and returns the digest. */ + virtual Anope::string Finalize() = 0; + }; + + /** Provider of encryption contexts. */ + class Provider + : public Service + { + public: + /** The byte size of the block cipher. */ + const size_t block_size; + + /** The byte size of the resulting digest. */ + const size_t digest_size; + + /** Creates a provider of encryption contexts. + * @param creator The module that created this provider. + * @param algorithm The name of the encryption algorithm. + * @param bs The byte size of the block cipher. + * @param ds The byte size of the resulting digest. + */ + Provider(Module *creator, const Anope::string &algorithm, size_t bs, size_t ds) + : Service(creator, "Encryption::Provider", algorithm) + , block_size(bs) + , digest_size(ds) + { + } + + virtual ~Provider() = default; + + /** Checks whether a plain text value matches a hash created by this provider. */ + virtual bool Compare(const Anope::string &hash, const Anope::string &plain) + { + return !hash.empty() && hash.equals_cs(ToPrintable(Encrypt(plain))); + } + + /** Called on initialising a encryption provider to check it works properly. */ + void Check(const Anope::map<Anope::string> &checks) + { + for (const auto &[hash, plain] : checks) + { + if (!Compare(hash, plain)) + throw ModuleException("BUG: unable to generate " + this->name + " hashes safely! Please report this!"); + } + Log(LOG_DEBUG) << "The " << this->name << " encryption provider appears to be working correctly."; + } + + /** Creates a new encryption context. */ + virtual std::unique_ptr<Context> CreateContext() = 0; + + /** Quickly encrypts the specified values and returns the digest. */ + template<typename... Args> + Anope::string Encrypt(Args &&...args) + { + auto context = CreateContext(); + context->Update(std::forward<Args>(args)...); + return context->Finalize(); + } + + /** Calculates the RFC 2104 hash-based message authentication code for the specified data. */ + inline Anope::string HMAC(const Anope::string &key, const Anope::string &data) + { + if (!block_size) + return {}; + + auto keybuf = key.length() > block_size ? Encrypt(key) : key; + keybuf.resize(block_size); + + Anope::string hmac1; + Anope::string hmac2; + for (size_t i = 0; i < block_size; ++i) + { + hmac1.push_back(static_cast<char>(keybuf[i] ^ 0x5C)); + hmac2.push_back(static_cast<char>(keybuf[i] ^ 0x36)); + } + hmac2.append(data); + hmac1.append(Encrypt(hmac2)); + + return Encrypt(hmac1); + } + + /** Converts a hash to its printable form. */ + virtual Anope::string ToPrintable(const Anope::string &hash) + { + return Anope::Hex(hash); + } }; - class Provider : public Service + /** Helper template for creating simple providers of encryption contexts. */ + template <typename T> + class SimpleProvider final + : public Provider { - public: - Provider(Module *creator, const Anope::string &sname) : Service(creator, "Encryption::Provider", sname) { } - virtual ~Provider() { } + public: + /** Creates a simple provider of encryption contexts. + * @param creator The module that created this provider. + * @param algorithm The name of the encryption algorithm. + * @param bs The byte size of the block cipher. + * @param ds The byte size of the resulting digest. + */ + SimpleProvider(Module *creator, const Anope::string &algorithm, size_t bs, size_t ds) + : Provider(creator, algorithm, bs, ds) + { + } - virtual Context *CreateContext(IV * = NULL) = 0; - virtual IV GetDefaultIV() = 0; + /** @copydoc Encryption::Provider::CreateContext. */ + std::unique_ptr<Context> CreateContext() override + { + return std::make_unique<T>(); + } }; } diff --git a/include/modules/hs_request.h b/include/modules/hs_request.h new file mode 100644 index 000000000..a1805a298 --- /dev/null +++ b/include/modules/hs_request.h @@ -0,0 +1,23 @@ +/* + * + * (C) 2003-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +class HostRequest +{ +protected: + HostRequest() = default; + +public: + Anope::string nick; + Anope::string ident; + Anope::string host; + time_t time = 0; + + virtual ~HostRequest() = default; +}; diff --git a/include/modules/httpd.h b/include/modules/httpd.h index bd2bde4a0..5b555fbab 100644 --- a/include/modules/httpd.h +++ b/include/modules/httpd.h @@ -6,8 +6,7 @@ * Please read COPYING and README for further details. */ -#ifndef ANOPE_HTTPD_H -#define ANOPE_HTTPD_H +#pragma once enum HTTPError { @@ -19,34 +18,35 @@ enum HTTPError }; /* A message to someone */ -struct HTTPReply +struct HTTPReply final { - HTTPError error; + HTTPError error = HTTP_ERROR_OK; Anope::string content_type; std::map<Anope::string, Anope::string, ci::less> headers; typedef std::list<std::pair<Anope::string, Anope::string> > cookie; std::vector<cookie> cookies; - HTTPReply() : error(HTTP_ERROR_OK), length(0) { } + HTTPReply() = default; + HTTPReply &operator=(const HTTPReply &) = default; - HTTPReply(const HTTPReply& other) : error(other.error), length(other.length) + HTTPReply(const HTTPReply &other) : error(other.error), length(other.length) { content_type = other.content_type; headers = other.headers; cookies = other.cookies; - for (unsigned i = 0; i < other.out.size(); ++i) - out.push_back(new Data(other.out[i]->buf, other.out[i]->len)); + for (const auto &datum : other.out) + out.push_back(new Data(datum->buf, datum->len)); } ~HTTPReply() { - for (unsigned i = 0; i < out.size(); ++i) - delete out[i]; + for (const auto *datum : out) + delete datum; out.clear(); } - struct Data + struct Data final { char *buf; size_t len; @@ -65,7 +65,7 @@ struct HTTPReply }; std::deque<Data *> out; - size_t length; + size_t length = 0; void Write(const Anope::string &message) { @@ -81,7 +81,7 @@ struct HTTPReply }; /* A message from someone */ -struct HTTPMessage +struct HTTPMessage final { std::map<Anope::string, Anope::string> headers; std::map<Anope::string, Anope::string> cookies; @@ -93,12 +93,13 @@ struct HTTPMessage class HTTPClient; class HTTPProvider; -class HTTPPage : public Base +class HTTPPage + : public virtual Base { Anope::string url; Anope::string content_type; - public: +public: HTTPPage(const Anope::string &u, const Anope::string &ct = "text/html") : url(u), content_type(ct) { } const Anope::string &GetURL() const { return this->url; } @@ -115,15 +116,18 @@ class HTTPPage : public Base virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; }; -class HTTPClient : public ClientSocket, public BinarySocket, public Base +class HTTPClient + : public ClientSocket + , public BinarySocket + , public Base { - protected: +protected: void WriteClient(const Anope::string &message) { BinarySocket::Write(message + "\r\n"); } - public: +public: HTTPClient(ListenSocket *l, int f, const sockaddrs &a) : ClientSocket(l, a), BinarySocket() { } virtual const Anope::string GetIP() @@ -135,12 +139,14 @@ class HTTPClient : public ClientSocket, public BinarySocket, public Base virtual void SendReply(HTTPReply *) = 0; }; -class HTTPProvider : public ListenSocket, public Service +class HTTPProvider + : public ListenSocket + , public Service { Anope::string ip; unsigned short port; bool ssl; - public: +public: std::vector<Anope::string> ext_ips; std::vector<Anope::string> ext_headers; @@ -163,7 +169,7 @@ class HTTPProvider : public ListenSocket, public Service virtual bool RegisterPage(HTTPPage *page) = 0; virtual void UnregisterPage(HTTPPage *page) = 0; - virtual HTTPPage* FindPage(const Anope::string &name) = 0; + virtual HTTPPage *FindPage(const Anope::string &name) = 0; }; namespace HTTPUtils @@ -174,7 +180,7 @@ namespace HTTPUtils for (unsigned i = 0; i < url.length(); ++i) { - const char& c = url[i]; + const char &c = url[i]; if (c == '%' && i + 2 < url.length()) { @@ -196,10 +202,8 @@ namespace HTTPUtils { Anope::string encoded; - for (unsigned i = 0; i < url.length(); ++i) + for (const auto c : url) { - const char& c = url[i]; - if (isalnum(c) || c == '.' || c == '-' || c == '*' || c == '_') encoded += c; else if (c == ' ') @@ -215,9 +219,9 @@ namespace HTTPUtils { Anope::string dst; - for (unsigned i = 0; i < src.length(); ++i) + for (const auto c : src) { - switch (src[i]) + switch (c) { case '<': dst += "<"; @@ -232,12 +236,10 @@ namespace HTTPUtils dst += "&"; break; default: - dst += src[i]; + dst += c; } } return dst; } } - -#endif // ANOPE_HTTPD_H diff --git a/include/modules/info.h b/include/modules/info.h new file mode 100644 index 000000000..c38cf0b72 --- /dev/null +++ b/include/modules/info.h @@ -0,0 +1,49 @@ +/* + * + * (C) 2003-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +class OperInfo +{ +protected: + OperInfo() = default; + + OperInfo(const Anope::string &t, const Anope::string &i, const Anope::string &a, time_t c) + : target(t) + , info(i) + , adder(a) + , created(c) + { + } + +public: + Anope::string target; + Anope::string info; + Anope::string adder; + time_t created = 0; + + virtual ~OperInfo() = default; +}; + +class OperInfoList + : public Serialize::Checker<std::vector<OperInfo *>> +{ +public: + OperInfoList() + : Serialize::Checker<std::vector<OperInfo *>>("OperInfo") + { + } + + virtual ~OperInfoList() + { + for (auto *info : *(*this)) + delete info; + } + + virtual OperInfo *Create() = 0; +}; diff --git a/include/modules/ldap.h b/include/modules/ldap.h index cc5a21b34..f982ea1ca 100644 --- a/include/modules/ldap.h +++ b/include/modules/ldap.h @@ -6,18 +6,17 @@ * Please read COPYING and README for further details. */ -#ifndef ANOPE_LDAP_H -#define ANOPE_LDAP_H +#pragma once -class LDAPException : public ModuleException +class DllExport LDAPException : public ModuleException { - public: +public: LDAPException(const Anope::string &reason) : ModuleException(reason) { } - virtual ~LDAPException() throw() { } + virtual ~LDAPException() noexcept = default; }; -struct LDAPModification +struct LDAPModification final { enum LDAPOperation { @@ -32,7 +31,8 @@ struct LDAPModification }; typedef std::vector<LDAPModification> LDAPMods; -struct LDAPAttributes : public std::map<Anope::string, std::vector<Anope::string> > +struct LDAPAttributes final + : public std::map<Anope::string, std::vector<Anope::string>> { size_t size(const Anope::string &attr) const { @@ -43,8 +43,8 @@ struct LDAPAttributes : public std::map<Anope::string, std::vector<Anope::string const std::vector<Anope::string> keys() const { std::vector<Anope::string> k; - for (const_iterator it = this->begin(), it_end = this->end(); it != it_end; ++it) - k.push_back(it->first); + for (const auto &[key, _] : *this) + k.push_back(key); return k; } @@ -75,7 +75,7 @@ enum QueryType QUERY_MODIFY }; -struct LDAPResult +struct LDAPResult final { std::vector<LDAPAttributes> messages; Anope::string error; @@ -112,20 +112,21 @@ struct LDAPResult class LDAPInterface { - public: +public: Module *owner; LDAPInterface(Module *m) : owner(m) { } - virtual ~LDAPInterface() { } + virtual ~LDAPInterface() = default; virtual void OnResult(const LDAPResult &r) = 0; virtual void OnError(const LDAPResult &err) = 0; virtual void OnDelete() { } }; -class LDAPProvider : public Service +class LDAPProvider + : public Service { - public: +public: LDAPProvider(Module *c, const Anope::string &n) : Service(c, "LDAPProvider", n) { } /** Attempt to bind to the LDAP server as an admin @@ -167,5 +168,3 @@ class LDAPProvider : public Service */ virtual void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) = 0; }; - -#endif // ANOPE_LDAP_H diff --git a/include/modules/ns_cert.h b/include/modules/ns_cert.h index 3fbe6b087..9462d66a0 100644 --- a/include/modules/ns_cert.h +++ b/include/modules/ns_cert.h @@ -9,12 +9,14 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + struct NSCertList { - protected: - NSCertList() { } - public: - virtual ~NSCertList() { } +protected: + NSCertList() = default; +public: + virtual ~NSCertList() = default; /** Add an entry to the nick's certificate list * @@ -52,6 +54,15 @@ struct NSCertList */ virtual void EraseCert(const Anope::string &entry) = 0; + /** Replaces a fingerprint in the nick's certificate list + * + * @param oldentry The old fingerprint to remove + * @param newentry The new fingerprint to add + * + * Replaces the specified fingerprint in the cert list. + */ + virtual void ReplaceCert(const Anope::string &oldentry, const Anope::string &newentry) = 0; + /** Clears the entire nick's cert list * * Deletes all the memory allocated in the certificate list vector and then clears the vector. @@ -61,10 +72,12 @@ struct NSCertList virtual void Check() = 0; }; -class CertService : public Service +class CertService + : public Service { - public: +public: CertService(Module *c) : Service(c, "CertService", "certs") { } - virtual NickCore* FindAccountFromCert(const Anope::string &cert) = 0; + virtual NickCore *FindAccountFromCert(const Anope::string &cert) = 0; + virtual void ReplaceCert(const Anope::string &oldcert, const Anope::string &newcert) = 0; }; diff --git a/include/modules/os_forbid.h b/include/modules/os_forbid.h index da3f8f62c..5c2f9d05c 100644 --- a/include/modules/os_forbid.h +++ b/include/modules/os_forbid.h @@ -6,8 +6,7 @@ * Please read COPYING and README for further details. */ -#ifndef OS_FORBID_H -#define OS_FORBID_H +#pragma once enum ForbidType { @@ -23,25 +22,26 @@ struct ForbidData Anope::string mask; Anope::string creator; Anope::string reason; - time_t created; - time_t expires; + time_t created = 0; + time_t expires = 0; ForbidType type; - virtual ~ForbidData() { } - protected: - ForbidData() : created(0), expires(0) { } + virtual ~ForbidData() = default; +protected: + ForbidData() = default; }; -class ForbidService : public Service +class ForbidService + : public Service { - public: +public: ForbidService(Module *m) : Service(m, "ForbidService", "forbid") { } virtual void AddForbid(ForbidData *d) = 0; virtual void RemoveForbid(ForbidData *d) = 0; - virtual ForbidData* CreateForbid() = 0; + virtual ForbidData *CreateForbid() = 0; virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0; @@ -51,5 +51,3 @@ class ForbidService : public Service }; static ServiceReference<ForbidService> forbid_service("ForbidService", "forbid"); - -#endif diff --git a/include/modules/os_ignore.h b/include/modules/os_ignore.h index a36d8264d..8a60a044f 100644 --- a/include/modules/os_ignore.h +++ b/include/modules/os_ignore.h @@ -9,24 +9,27 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + struct IgnoreData { Anope::string mask; Anope::string creator; Anope::string reason; - time_t time; /* When do we stop ignoring them? */ + time_t time = 0; /* When do we stop ignoring them? */ - virtual ~IgnoreData() { } - protected: - IgnoreData() : time(0) { } + virtual ~IgnoreData() = default; +protected: + IgnoreData() = default; }; -class IgnoreService : public Service +class IgnoreService + : public Service { - protected: +protected: IgnoreService(Module *c) : Service(c, "IgnoreService", "ignore") { } - public: +public: virtual void AddIgnore(IgnoreData *) = 0; virtual void DelIgnore(IgnoreData *) = 0; diff --git a/include/modules/os_news.h b/include/modules/os_news.h index 2c488babf..815c71db6 100644 --- a/include/modules/os_news.h +++ b/include/modules/os_news.h @@ -6,8 +6,7 @@ * Please read COPYING and README for further details. */ -#ifndef OS_NEWS -#define OS_NEWS +#pragma once enum NewsType { @@ -16,14 +15,15 @@ enum NewsType NEWS_OPER }; -struct NewsMessages +struct NewsMessages final { NewsType type; Anope::string name; const char *msgs[10]; }; -struct NewsItem : Serializable +struct NewsItem + : Serializable { NewsType type; Anope::string text; @@ -33,9 +33,10 @@ struct NewsItem : Serializable NewsItem() : Serializable("NewsItem") { } }; -class NewsService : public Service +class NewsService + : public Service { - public: +public: NewsService(Module *m) : Service(m, "NewsService", "news") { } virtual NewsItem *CreateNewsItem() = 0; @@ -48,5 +49,3 @@ class NewsService : public Service }; static ServiceReference<NewsService> news_service("NewsService", "news"); - -#endif // OS_NEWS diff --git a/include/modules/os_oper.h b/include/modules/os_oper.h new file mode 100644 index 000000000..154b6af08 --- /dev/null +++ b/include/modules/os_oper.h @@ -0,0 +1,46 @@ +/* + * + * (C) 2011-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +struct MyOper final + : Oper + , Serializable +{ + MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { } + + void Serialize(Serialize::Data &data) const override + { + data.Store("name", this->name); + data.Store("type", this->ot->GetName()); + } + + static Serializable *Unserialize(Serializable *obj, Serialize::Data &data) + { + Anope::string stype, sname; + + data["type"] >> stype; + data["name"] >> sname; + + OperType *ot = OperType::Find(stype); + if (ot == NULL) + return NULL; + NickCore *nc = NickCore::Find(sname); + if (nc == NULL) + return NULL; + + MyOper *myo; + if (obj) + myo = anope_dynamic_static_cast<MyOper *>(obj); + else + myo = new MyOper(nc->display, ot); + nc->o = myo; + Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName(); + return myo; + } +}; diff --git a/include/modules/os_session.h b/include/modules/os_session.h index 0bdec8a2b..0f25f669e 100644 --- a/include/modules/os_session.h +++ b/include/modules/os_session.h @@ -6,19 +6,19 @@ * Please read COPYING and README for further details. */ -#ifndef OS_SESSION_H -#define OS_SESSION_H +#pragma once -struct Session +struct Session final { cidr addr; /* A cidr (sockaddrs + len) representing this session */ - unsigned count; /* Number of clients with this host */ - unsigned hits; /* Number of subsequent kills for a host */ + unsigned count = 1; /* Number of clients with this host */ + unsigned hits = 0; /* Number of subsequent kills for a host */ - Session(const sockaddrs &ip, int len) : addr(ip, len), count(1), hits(0) { } + Session(const sockaddrs &ip, int len) : addr(ip, len) { } }; -struct Exception : Serializable +struct Exception final + : Serializable { Anope::string mask; /* Hosts to which this exception applies */ unsigned limit; /* Session limit for exception */ @@ -28,14 +28,15 @@ struct Exception : Serializable time_t expires; /* Time when it expires. 0 == no expiry */ Exception() : Serializable("Exception") { } - void Serialize(Serialize::Data &data) const anope_override; - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); + void Serialize(Serialize::Data &data) const override; + static Serializable *Unserialize(Serializable *obj, Serialize::Data &data); }; -class SessionService : public Service +class SessionService + : public Service { - public: - typedef TR1NS::unordered_map<cidr, Session *, cidr::hash> SessionMap; +public: + typedef std::unordered_map<cidr, Session *, cidr::hash> SessionMap; typedef std::vector<Exception *> ExceptionVector; SessionService(Module *m) : Service(m, "SessionService", "session") { } @@ -61,15 +62,15 @@ static ServiceReference<SessionService> session_service("SessionService", "sessi void Exception::Serialize(Serialize::Data &data) const { - data["mask"] << this->mask; - data["limit"] << this->limit; - data["who"] << this->who; - data["reason"] << this->reason; - data["time"] << this->time; - data["expires"] << this->expires; + data.Store("mask", this->mask); + data.Store("limit", this->limit); + data.Store("who", this->who); + data.Store("reason", this->reason); + data.Store("time", this->time); + data.Store("expires", this->expires); } -Serializable* Exception::Unserialize(Serializable *obj, Serialize::Data &data) +Serializable *Exception::Unserialize(Serializable *obj, Serialize::Data &data) { if (!session_service) return NULL; @@ -90,5 +91,3 @@ Serializable* Exception::Unserialize(Serializable *obj, Serialize::Data &data) session_service->AddException(ex); return ex; } - -#endif diff --git a/include/modules/pseudoclients/chanserv.h b/include/modules/pseudoclients/chanserv.h index 7e32da755..5bef94340 100644 --- a/include/modules/pseudoclients/chanserv.h +++ b/include/modules/pseudoclients/chanserv.h @@ -6,12 +6,12 @@ * Please read COPYING and README for further details. */ -#ifndef CHANSERV_H -#define CHANSERV_H +#pragma once -class ChanServService : public Service +class ChanServService + : public Service { - public: +public: ChanServService(Module *m) : Service(m, "ChanServService", "ChanServ") { } @@ -21,5 +21,3 @@ class ChanServService : public Service */ virtual void Hold(Channel *c) = 0; }; - -#endif // CHANSERV_H diff --git a/include/modules/pseudoclients/global.h b/include/modules/pseudoclients/global.h index 77da218ba..01149d48e 100644 --- a/include/modules/pseudoclients/global.h +++ b/include/modules/pseudoclients/global.h @@ -6,25 +6,70 @@ * Please read COPYING and README for further details. */ -#ifndef GLOBAL_H -#define GLOBAL_H +#pragma once -class GlobalService : public Service +#define GLOBAL_NO_MESSAGE _("You do not have any messages queued and did not specify a message to send.") +#define GLOBAL_QUEUE_CONFLICT _("You can not send a single message while you have messages queued.") + +class GlobalService + : public Service { - public: - GlobalService(Module *m) : Service(m, "GlobalService", "Global") +public: + GlobalService(Module *m) + : Service(m, "GlobalService", "Global") { } /** Retrieves the bot which sends global messages unless otherwise specified. */ - virtual Reference<BotInfo> GetDefaultSender() = 0; + virtual Reference<BotInfo> GetDefaultSender() const = 0; - /** Send out a global message to all users - * @param sender Our client which should send the global - * @param source The sender of the global - * @param message The message + /** Clears any queued messages for the specified account. + * @param nc The account to clear queued messages for. */ - virtual void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0; -}; + virtual void ClearQueue(NickCore *nc) = 0; + + /** Retrieves the size of the messages queue for the specified user. + * @param nc The account to count queued messages for. + */ + inline size_t CountQueue(NickCore* nc) const + { + auto *q = GetQueue(nc); + return q ? q->size() : 0; + } + + /** Retrieves the messages queue for the specified user. + * @param nc The account to retrieve queued messages for. + */ + virtual const std::vector<Anope::string> *GetQueue(NickCore* nc) const = 0; -#endif // GLOBAL_H + /** Queues a message to be sent later. + * @param nc The account to queue the message for. + * @param message The message to queue. + * @return The new number of messages in the queue. + */ + virtual size_t Queue(NickCore *nc, const Anope::string &message) = 0; + + /** Sends a single message to all users on the network. + * @param message The message to send. + * @param source If non-nullptr then the source of the message. + * @param sender If non-nullptr then the bot to send the message from. + * @param server If non-nullptr then the server to send messages to. + * @return If the message was sent then true; otherwise, false. + */ + virtual bool SendSingle(const Anope::string &message, CommandSource *source = nullptr, BotInfo *sender = nullptr, Server *server = nullptr) = 0; + + /** Sends a message queue to all users on the network. + * @param source The source of the message. + * @param sender If non-nullptr then the bot to send the message from. + * @param server If non-nullptr then the server to send messages to. + * @return If the message queue was sent then true; otherwise, false. + */ + virtual bool SendQueue(CommandSource &source, BotInfo *sender = nullptr, Server *server = nullptr) = 0; + + /** Unqueues a message from the message queue. + * @param nc The account to unqueue the message from. + * @param idx The index of the item to remove. + * @return Whether the message was removed from the queue. + */ + virtual bool Unqueue(NickCore *nc, size_t idx) = 0; +}; diff --git a/include/modules/pseudoclients/memoserv.h b/include/modules/pseudoclients/memoserv.h index bca26df43..c1ff4af7d 100644 --- a/include/modules/pseudoclients/memoserv.h +++ b/include/modules/pseudoclients/memoserv.h @@ -6,12 +6,12 @@ * Please read COPYING and README for further details. */ -#ifndef MEMOSERV_H -#define MEMOSERV_H +#pragma once -class MemoServService : public Service +class MemoServService + : public Service { - public: +public: enum MemoResult { MEMO_SUCCESS, @@ -37,5 +37,3 @@ class MemoServService : public Service */ virtual void Check(User *u) = 0; }; - -#endif // MEMOSERV_H diff --git a/include/modules/pseudoclients/nickserv.h b/include/modules/pseudoclients/nickserv.h index 14502e7a8..2c659501e 100644 --- a/include/modules/pseudoclients/nickserv.h +++ b/include/modules/pseudoclients/nickserv.h @@ -6,12 +6,12 @@ * Please read COPYING and README for further details. */ -#ifndef NICKSERV_H -#define NICKSERV_H +#pragma once -class NickServService : public Service +class NickServService + : public Service { - public: +public: NickServService(Module *m) : Service(m, "NickServService", "NickServ") { } @@ -19,6 +19,5 @@ class NickServService : public Service virtual void Validate(User *u) = 0; virtual void Collide(User *u, NickAlias *na) = 0; virtual void Release(NickAlias *na) = 0; + virtual bool IsGuestNick(const Anope::string &nick) const = 0; }; - -#endif // NICKSERV_H diff --git a/include/modules/redis.h b/include/modules/redis.h index 346738492..6683997e0 100644 --- a/include/modules/redis.h +++ b/include/modules/redis.h @@ -6,9 +6,11 @@ * Please read COPYING and README for further details. */ +#pragma once + namespace Redis { - struct Reply + struct Reply final { enum Type { @@ -30,8 +32,8 @@ namespace Redis i = 0; bulk.clear(); multi_bulk_size = 0; - for (unsigned j = 0; j < multi_bulk.size(); ++j) - delete multi_bulk[j]; + for (const auto *reply : multi_bulk) + delete reply; multi_bulk.clear(); } @@ -43,19 +45,20 @@ namespace Redis class Interface { - public: + public: Module *owner; Interface(Module *m) : owner(m) { } - virtual ~Interface() { } + virtual ~Interface() = default; virtual void OnResult(const Reply &r) = 0; virtual void OnError(const Anope::string &error) { Log(owner) << error; } }; - class Provider : public Service + class Provider + : public Service { - public: + public: Provider(Module *c, const Anope::string &n) : Service(c, "Redis::Provider", n) { } virtual bool IsSocketDead() = 0; diff --git a/include/modules/rpc.h b/include/modules/rpc.h new file mode 100644 index 000000000..35db305c7 --- /dev/null +++ b/include/modules/rpc.h @@ -0,0 +1,128 @@ +/* + * + * (C) 2010-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +#include "httpd.h" + +#include <variant> + +class RPCBlock +{ +public: + /** Represents possible types of RPC value. */ + using RPCValue = std::variant<RPCBlock, Anope::string, std::nullptr_t, bool, double, int64_t, uint64_t>; + + /** Retrieves the list of RPC replies. */ + inline const auto &GetReplies() const { return this->replies; } + + template <typename Stringable> + inline RPCBlock &Reply(const Anope::string &key, const Stringable &value) + { + this->replies.emplace(key, Anope::ToString(value)); + return *this; + } + + inline RPCBlock &ReplyBlock(const Anope::string &key) + { + auto it = this->replies.emplace(key, RPCBlock()); + return std::get<RPCBlock>(it.first->second); + } + + inline RPCBlock &ReplyBool(const Anope::string &key, bool value) + { + this->replies.emplace(key, value); + return *this; + } + + inline RPCBlock &ReplyFloat(const Anope::string &key, double value) + { + this->replies.emplace(key, value); + return *this; + } + + inline RPCBlock &ReplyInt(const Anope::string &key, int64_t value) + { + this->replies.emplace(key, value); + return *this; + } + + inline RPCBlock &ReplyNull(const Anope::string &key) + { + this->replies.emplace(key, nullptr); + return *this; + } + + inline RPCBlock &ReplyUInt(const Anope::string &key, uint64_t value) + { + this->replies.emplace(key, value); + return *this; + } + +private: + Anope::map<RPCValue> replies; +}; + +class RPCRequest final + : public RPCBlock +{ +private: + std::optional<std::pair<int64_t, Anope::string>> error; + +public: + Anope::string name; + Anope::string id; + std::deque<Anope::string> data; + HTTPReply &reply; + + RPCRequest(HTTPReply &r) + : reply(r) + { + } + + inline void Error(uint64_t errcode, const Anope::string &errstr) + { + this->error.emplace(errcode, errstr); + } + + inline const auto &GetError() const { return this->error; } +}; + +class RPCServiceInterface; + +class RPCEvent +{ +private: + Anope::string event; + +protected: + RPCEvent(const Anope::string& e) + : event(e) + { + } + +public: + virtual ~RPCEvent() = default; + + const auto &GetEvent() const { return event; } + + virtual bool Run(RPCServiceInterface *iface, HTTPClient *client, RPCRequest &request) = 0; +}; + +class RPCServiceInterface + : public Service +{ +public: + RPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "RPCServiceInterface", sname) { } + + virtual bool Register(RPCEvent *event) = 0; + + virtual bool Unregister(RPCEvent *event) = 0; + + virtual void Reply(RPCRequest &request) = 0; +}; diff --git a/include/modules/sasl.h b/include/modules/sasl.h index bbd0f2f3d..e5786b524 100644 --- a/include/modules/sasl.h +++ b/include/modules/sasl.h @@ -6,30 +6,32 @@ * Please read COPYING and README for further details. */ +#pragma once + namespace SASL { - struct Message + struct Message final { Anope::string source; Anope::string target; Anope::string type; - Anope::string data; - Anope::string ext; + std::vector<Anope::string> data; }; class Mechanism; struct Session; - class Service : public ::Service + class Service + : public ::Service { - public: + public: Service(Module *o) : ::Service(o, "SASL::Service", "sasl") { } virtual void ProcessMessage(const Message &) = 0; virtual Anope::string GetAgent() = 0; - virtual Session* GetSession(const Anope::string &uid) = 0; + virtual Session *GetSession(const Anope::string &uid) = 0; virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) = 0; @@ -58,14 +60,15 @@ namespace SASL }; /* PLAIN, EXTERNAL, etc */ - class Mechanism : public ::Service + class Mechanism + : public ::Service { - public: + public: Mechanism(Module *o, const Anope::string &sname) : Service(o, "SASL::Mechanism", sname) { } - virtual Session* CreateSession(const Anope::string &uid) { return new Session(this, uid); } + virtual Session *CreateSession(const Anope::string &uid) { return new Session(this, uid); } - virtual void ProcessMessage(Session *session, const Message &) = 0; + virtual bool ProcessMessage(Session *session, const Message &) = 0; virtual ~Mechanism() { @@ -74,15 +77,16 @@ namespace SASL } }; - class IdentifyRequest : public ::IdentifyRequest + class IdentifyRequest + : public ::IdentifyRequest { Anope::string uid; Anope::string hostname, ip; - public: + public: IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass, const Anope::string &h, const Anope::string &i) : ::IdentifyRequest(m, acc, pass), uid(id), hostname(h), ip(i) { } - void OnSuccess() anope_override + void OnSuccess() override { if (!sasl) return; @@ -108,7 +112,7 @@ namespace SASL } } - void OnFail() anope_override + void OnFail() override { if (!sasl) return; diff --git a/include/modules/set_misc.h b/include/modules/set_misc.h index 38fa08818..2b93543c6 100644 --- a/include/modules/set_misc.h +++ b/include/modules/set_misc.h @@ -6,12 +6,15 @@ * Please read COPYING and README for further details. */ +#pragma once + struct MiscData { Anope::string object; Anope::string name; Anope::string data; - MiscData() { } - virtual ~MiscData() { } + virtual ~MiscData() = default; +protected: + MiscData() = default; }; diff --git a/include/modules/sql.h b/include/modules/sql.h index 9c5e4fc4b..81af2e597 100644 --- a/include/modules/sql.h +++ b/include/modules/sql.h @@ -6,22 +6,27 @@ * Please read COPYING and README for further details. */ +#pragma once + +#include <stdexcept> + namespace SQL { - class Data : public Serialize::Data + class Data final + : public Serialize::Data { - public: + public: typedef std::map<Anope::string, std::stringstream *> Map; Map data; - std::map<Anope::string, Type> types; + std::map<Anope::string, Serialize::DataType> types; ~Data() { Clear(); } - std::iostream& operator[](const Anope::string &key) anope_override + std::iostream &operator[](const Anope::string &key) override { std::stringstream *&ss = data[key]; if (!ss) @@ -29,72 +34,66 @@ namespace SQL return *ss; } - std::set<Anope::string> KeySet() const anope_override - { - std::set<Anope::string> keys; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - keys.insert(it->first); - return keys; - } - - size_t Hash() const anope_override + size_t Hash() const override { size_t hash = 0; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - if (!it->second->str().empty()) - hash ^= Anope::hash_cs()(it->second->str()); + for (const auto &[_, value] : this->data) + { + if (!value->str().empty()) + hash ^= Anope::hash_cs()(value->str()); + } return hash; } std::map<Anope::string, std::iostream *> GetData() const { std::map<Anope::string, std::iostream *> d; - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - d[it->first] = it->second; + for (const auto &[key, value] : this->data) + d[key] = value; return d; } void Clear() { - for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) - delete it->second; + for (const auto &[_, value] : this->data) + delete value; this->data.clear(); } - void SetType(const Anope::string &key, Type t) anope_override + void SetType(const Anope::string &key, Serialize::DataType dt) override { - this->types[key] = t; + this->types[key] = dt; } - Type GetType(const Anope::string &key) const anope_override + Serialize::DataType GetType(const Anope::string &key) const override { - std::map<Anope::string, Type>::const_iterator it = this->types.find(key); + auto it = this->types.find(key); if (it != this->types.end()) return it->second; - return DT_TEXT; + return Serialize::DataType::TEXT; } }; /** A SQL exception, can be thrown at various points */ - class Exception : public ModuleException + class DllExport Exception : public ModuleException { - public: + public: Exception(const Anope::string &reason) : ModuleException(reason) { } - virtual ~Exception() throw() { } + virtual ~Exception() noexcept = default; }; /** A SQL query */ - struct QueryData + struct QueryData final { Anope::string data; bool escape; }; - struct Query + struct Query final { Anope::string query; std::map<Anope::string, QueryData> parameters; @@ -102,7 +101,7 @@ namespace SQL Query() { } Query(const Anope::string &q) : query(q) { } - Query& operator=(const Anope::string &q) + Query &operator=(const Anope::string &q) { this->query = q; this->parameters.clear(); @@ -119,15 +118,14 @@ namespace SQL return !(*this == other); } - template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true) + template<typename T> void SetValue(const Anope::string &key, const T &value, bool escape = true) { - try - { - Anope::string string_value = stringify(value); - this->parameters[key].data = string_value; - this->parameters[key].escape = escape; - } - catch (const ConvertException &ex) { } + auto str = Anope::TryString(value); + if (!str.has_value()) + return; + + this->parameters[key].data = str.value(); + this->parameters[key].escape = escape; } }; @@ -135,16 +133,16 @@ namespace SQL */ class Result { - protected: + protected: /* Rows, column, item */ std::vector<std::map<Anope::string, Anope::string> > entries; Query query; Anope::string error; - public: - unsigned int id; + public: + unsigned int id = 0; Anope::string finished_query; - Result() : id(0) { } + Result() = default; Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { } inline operator bool() const { return this->error.empty(); } @@ -183,11 +181,11 @@ namespace SQL */ class Interface { - public: + public: Module *owner; Interface(Module *m) : owner(m) { } - virtual ~Interface() { } + virtual ~Interface() = default; virtual void OnResult(const Result &r) = 0; virtual void OnError(const Result &r) = 0; @@ -195,9 +193,10 @@ namespace SQL /** Class providing the SQL service, modules call this to execute queries */ - class Provider : public Service + class Provider + : public Service { - public: + public: Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { } virtual void Run(Interface *i, const Query &query) = 0; diff --git a/include/modules/ssl.h b/include/modules/ssl.h index 744cd46dd..a6dda0c52 100644 --- a/include/modules/ssl.h +++ b/include/modules/ssl.h @@ -6,9 +6,12 @@ * Please read COPYING and README for further details. */ -class SSLService : public Service +#pragma once + +class SSLService + : public Service { - public: +public: SSLService(Module *o, const Anope::string &n) : Service(o, "SSLService", n) { } virtual void Init(Socket *s) = 0; diff --git a/include/modules/suspend.h b/include/modules/suspend.h index 92523f7cf..f973baea4 100644 --- a/include/modules/suspend.h +++ b/include/modules/suspend.h @@ -9,11 +9,13 @@ * Based on the original code of Services by Andy Church. */ +#pragma once + struct SuspendInfo { Anope::string what, by, reason; time_t when, expires; - SuspendInfo() { } - virtual ~SuspendInfo() { } + SuspendInfo() = default; + virtual ~SuspendInfo() = default; }; diff --git a/include/modules/xmlrpc.h b/include/modules/xmlrpc.h deleted file mode 100644 index 01847d3f0..000000000 --- a/include/modules/xmlrpc.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * (C) 2010-2025 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "httpd.h" - -class XMLRPCRequest -{ - std::map<Anope::string, Anope::string> replies; - - public: - Anope::string name; - Anope::string id; - std::deque<Anope::string> data; - HTTPReply& r; - - XMLRPCRequest(HTTPReply &_r) : r(_r) { } - inline void reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.insert(std::make_pair(dname, ddata)); } - inline const std::map<Anope::string, Anope::string> &get_replies() { return this->replies; } -}; - -class XMLRPCServiceInterface; - -class XMLRPCEvent -{ - public: - virtual ~XMLRPCEvent() { } - virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) = 0; -}; - -class XMLRPCServiceInterface : public Service -{ - public: - XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "XMLRPCServiceInterface", sname) { } - - virtual void Register(XMLRPCEvent *event) = 0; - - virtual void Unregister(XMLRPCEvent *event) = 0; - - virtual Anope::string Sanitize(const Anope::string &string) = 0; - - virtual void Reply(XMLRPCRequest &request) = 0; -}; |