X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_chanhistory.cpp;h=3ad6b81e64c90e276b1c3caed9d6da25ff4246c1;hb=HEAD;hp=7a64e56c6c610e98153bf2ae341607d41a544226;hpb=b3d82bb7a89ce550f5a60a668ce36bf2a3a22495;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_chanhistory.cpp b/src/modules/m_chanhistory.cpp index 7a64e56c6..3ad6b81e6 100644 --- a/src/modules/m_chanhistory.cpp +++ b/src/modules/m_chanhistory.cpp @@ -1,6 +1,12 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2018 linuxdaemon + * Copyright (C) 2013, 2017-2021 Sadie Powell + * Copyright (C) 2013 Daniel Vassdal + * Copyright (C) 2012-2015, 2018 Attila Molnar + * Copyright (C) 2012, 2019 Robby + * Copyright (C) 2010 Craig Edwards * Copyright (C) 2009-2010 Daniel De Graaf * * This file is part of InspIRCd. InspIRCd is free software: you can @@ -55,6 +61,18 @@ struct HistoryList , maxtime(time) { } + + size_t Prune() + { + // Prune expired entries from the list. + if (maxtime) + { + time_t mintime = ServerInstance->Time() - maxtime; + while (!lines.empty() && lines.front().ts < mintime) + lines.pop_front(); + } + return lines.size(); + } }; class HistoryMode : public ParamMode > @@ -102,6 +120,7 @@ class HistoryMode : public ParamMode > history->maxlen = len; history->maxtime = time; + history->Prune(); } else { @@ -118,13 +137,25 @@ class HistoryMode : public ParamMode > } }; +class NoHistoryMode : public SimpleUserModeHandler +{ +public: + NoHistoryMode(Module* Creator) + : SimpleUserModeHandler(Creator, "nohistory", 'N') + { + if (!ServerInstance->Config->ConfValue("chanhistory")->getBool("enableumode")) + DisableAutoRegister(); + } +}; + class ModuleChanHistory : public Module , public ServerProtocol::BroadcastEventListener { private: - HistoryMode m; - bool sendnotice; + HistoryMode historymode; + NoHistoryMode nohistorymode; + bool prefixmsg; UserModeReference botmode; bool dobots; IRCv3::Batch::CapReference batchcap; @@ -147,7 +178,7 @@ class ModuleChanHistory } } - void SendHistory(LocalUser* user, Channel* channel, HistoryList* list, time_t mintime) + void SendHistory(LocalUser* user, Channel* channel, HistoryList* list) { if (batchmanager) { @@ -155,19 +186,16 @@ class ModuleChanHistory batch.GetBatchStartMessage().PushParamRef(channel->name); } - for(std::deque::iterator i = list->lines.begin(); i != list->lines.end(); ++i) + for (std::deque::iterator i = list->lines.begin(); i != list->lines.end(); ++i) { HistoryItem& item = *i; - if (item.ts >= mintime) - { - ClientProtocol::Messages::Privmsg msg(ClientProtocol::Messages::Privmsg::nocopy, item.sourcemask, channel, item.text, item.type); - for (HistoryTagMap::iterator iter = item.tags.begin(); iter != item.tags.end(); ++iter) - AddTag(msg, iter->first, iter->second); - if (servertimemanager) - servertimemanager->Set(msg, item.ts); - batch.AddToBatch(msg); - user->Send(ServerInstance->GetRFCEvents().privmsg, msg); - } + ClientProtocol::Messages::Privmsg msg(ClientProtocol::Messages::Privmsg::nocopy, item.sourcemask, channel, item.text, item.type); + for (HistoryTagMap::iterator iter = item.tags.begin(); iter != item.tags.end(); ++iter) + AddTag(msg, iter->first, iter->second); + if (servertimemanager) + servertimemanager->Set(msg, item.ts); + batch.AddToBatch(msg); + user->Send(ServerInstance->GetRFCEvents().privmsg, msg); } if (batchmanager) @@ -177,7 +205,8 @@ class ModuleChanHistory public: ModuleChanHistory() : ServerProtocol::BroadcastEventListener(this) - , m(this) + , historymode(this) + , nohistorymode(this) , botmode(this, "bot") , batchcap(this) , batchmanager(this) @@ -190,29 +219,32 @@ class ModuleChanHistory void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { ConfigTag* tag = ServerInstance->Config->ConfValue("chanhistory"); - m.maxlines = tag->getUInt("maxlines", 50, 1); - sendnotice = tag->getBool("notice", true); + historymode.maxlines = tag->getUInt("maxlines", 50, 1); + prefixmsg = tag->getBool("prefixmsg", tag->getBool("notice", true)); dobots = tag->getBool("bots", true); } ModResult OnBroadcastMessage(Channel* channel, const Server* server) CXX11_OVERRIDE { - return channel->IsModeSet(m) ? MOD_RES_ALLOW : MOD_RES_PASSTHRU; + return channel->IsModeSet(historymode) ? MOD_RES_ALLOW : MOD_RES_PASSTHRU; } void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE { - if ((target.type == MessageTarget::TYPE_CHANNEL) && (target.status == 0)) - { - Channel* c = target.Get(); - HistoryList* list = m.ext.get(c); - if (list) - { - list->lines.push_back(HistoryItem(user, details)); - if (list->lines.size() > list->maxlen) - list->lines.pop_front(); - } - } + if (target.type != MessageTarget::TYPE_CHANNEL || target.status) + return; + + std::string ctcpname; + if (details.IsCTCP(ctcpname) && !irc::equals(ctcpname, "ACTION")) + return; + + HistoryList* list = historymode.ext.get(target.Get()); + if (!list) + return; + + list->lines.push_back(HistoryItem(user, details)); + if (list->lines.size() > list->maxlen) + list->lines.pop_front(); } void OnPostJoin(Membership* memb) CXX11_OVERRIDE @@ -224,28 +256,27 @@ class ModuleChanHistory if (memb->user->IsModeSet(botmode) && !dobots) return; - HistoryList* list = m.ext.get(memb->chan); - if (!list) + if (memb->user->IsModeSet(nohistorymode)) return; - if ((sendnotice) && (!batchcap.get(localuser))) + HistoryList* list = historymode.ext.get(memb->chan); + if (!list || !list->Prune()) + return; + + if ((prefixmsg) && (!batchcap.get(localuser))) { std::string message("Replaying up to " + ConvToStr(list->maxlen) + " lines of pre-join history"); if (list->maxtime > 0) - message.append(" spanning up to " + InspIRCd::DurationString(list->maxtime)); + message.append(" from the last " + InspIRCd::DurationString(list->maxtime)); memb->WriteNotice(message); } - time_t mintime = 0; - if (list->maxtime) - mintime = ServerInstance->Time() - list->maxtime; - - SendHistory(localuser, memb->chan, list, mintime); + SendHistory(localuser, memb->chan, list); } Version GetVersion() CXX11_OVERRIDE { - return Version("Provides channel mode +H, allows for the channel message history to be replayed on join", VF_VENDOR); + return Version("Adds channel mode H (history) which allows message history to be viewed on joining the channel.", VF_VENDOR); } };