From: Peter Powell Date: Mon, 13 Aug 2018 20:44:11 +0000 (+0100) Subject: Add support for the IRCv3 server-time specification. X-Git-Url: https://git.netwichtig.de/gitweb/?a=commitdiff_plain;h=224952435591734d8308fd2b612d51c030416e53;p=user%2Fhenk%2Fcode%2Finspircd.git Add support for the IRCv3 server-time specification. Co-authored-by: Attila Molnar --- diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 50a43021a..5995580f9 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1067,6 +1067,11 @@ # another user into a channel. This respects . # +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# IRCv3 server-time module. Adds the 'time' tag which adds a timestamp +# to all messages received from the server. +# + #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # IRCv3 Strict Transport Security module: Provides the sts IRCv3.2 # extension which allows clients connecting insecurely to upgrade their diff --git a/include/modules/ircv3_servertime.h b/include/modules/ircv3_servertime.h new file mode 100644 index 000000000..b917531a0 --- /dev/null +++ b/include/modules/ircv3_servertime.h @@ -0,0 +1,88 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2016 Attila Molnar + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#pragma once + +namespace IRCv3 +{ + namespace ServerTime + { + class Manager; + class API; + + /** Format a unix timestamp into the format used by server-time. + * @param t Time to format. + * @return Time in server-time format, as a string. + */ + inline std::string FormatTime(time_t t) + { + return InspIRCd::TimeString(t, "%Y-%m-%dT%H:%M:%S.000Z", true); + } + } +} + +/** Implements manipulating the server time on messages. + * A timestamp can be attached to outgoing client protocol messages to indicate the time when the message + * was generated by us. If a message has server time attached then recipient clients who have negotiated + * the appropriate protocol extension will receive it. + */ +class IRCv3::ServerTime::Manager : public DataProvider +{ + protected: + ClientProtocol::MessageTagProvider* tagprov; + + public: + /** Constructor. + * @param mod Module that owns the Manager. + */ + Manager(Module* mod) + : DataProvider(mod, "servertimeapi") + { + } + + /** Set the server time on a message. + * @param msg Message to set the time on. No-op if the message already has server time set. + * @param t Unix timestamp to set. + */ + void Set(ClientProtocol::Message& msg, time_t t) + { + Set(msg, FormatTime(t)); + } + + /** Set the server time on a message. + * @param msg Message to set the time on. No-op if the message already has server time set. + * @param timestr Timestamp to set. Must be in server time format. + * The FormatTime() function can be used to convert unix timestamps into the required format. + */ + void Set(ClientProtocol::Message& msg, const std::string& timestr) + { + msg.AddTag("time", tagprov, timestr); + } +}; + +/** Server time API. Use this to access the Manager. + */ +class IRCv3::ServerTime::API : public dynamic_reference_nocheck +{ + public: + API(Module* mod) + : dynamic_reference_nocheck(mod, "servertimeapi") + { + } +}; diff --git a/src/modules/m_chanhistory.cpp b/src/modules/m_chanhistory.cpp index 0c3945346..57db002a8 100644 --- a/src/modules/m_chanhistory.cpp +++ b/src/modules/m_chanhistory.cpp @@ -18,6 +18,7 @@ #include "inspircd.h" +#include "modules/ircv3_servertime.h" struct HistoryItem { @@ -122,8 +123,13 @@ class ModuleChanHistory : public Module bool sendnotice; UserModeReference botmode; bool dobots; + IRCv3::ServerTime::API servertimemanager; + public: - ModuleChanHistory() : m(this), botmode(this, "bot") + ModuleChanHistory() + : m(this) + , botmode(this, "bot") + , servertimemanager(this) { } @@ -180,6 +186,8 @@ class ModuleChanHistory : public Module if (item.ts >= mintime) { ClientProtocol::Messages::Privmsg msg(ClientProtocol::Messages::Privmsg::nocopy, item.sourcemask, memb->chan, item.text); + if (servertimemanager) + servertimemanager->Set(msg, item.ts); localuser->Send(ServerInstance->GetRFCEvents().privmsg, msg); } } diff --git a/src/modules/m_ircv3_servertime.cpp b/src/modules/m_ircv3_servertime.cpp new file mode 100644 index 000000000..1c35c422b --- /dev/null +++ b/src/modules/m_ircv3_servertime.cpp @@ -0,0 +1,72 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2016 Attila Molnar + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "inspircd.h" +#include "modules/ircv3.h" +#include "modules/ircv3_servertime.h" + +class ServerTimeTag : public IRCv3::ServerTime::Manager, public IRCv3::CapTag +{ + time_t lasttime; + std::string lasttimestring; + + void RefreshTimeString() + { + const time_t currtime = ServerInstance->Time(); + if (currtime != lasttime) + { + lasttime = currtime; + // Cache the string so it's not recreated every time a message is sent + lasttimestring = IRCv3::ServerTime::FormatTime(currtime); + } + } + + public: + ServerTimeTag(Module* mod) + : IRCv3::ServerTime::Manager(mod) + , IRCv3::CapTag(mod, "server-time", "time") + , lasttime(0) + { + tagprov = this; + } + + const std::string* GetValue(const ClientProtocol::Message& msg) + { + RefreshTimeString(); + return &lasttimestring; + } +}; + +class ModuleIRCv3ServerTime : public Module +{ + ServerTimeTag tag; + + public: + ModuleIRCv3ServerTime() + : tag(this) + { + } + + Version GetVersion() CXX11_OVERRIDE + { + return Version("Provides the server-time IRCv3 extension", VF_VENDOR); + } +}; + +MODULE_INIT(ModuleIRCv3ServerTime)