2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2012 Attila Molnar <attilamolnar@hush.com>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "modules/account.h"
21 #include "modules/away.h"
22 #include "modules/cap.h"
23 #include "modules/ircv3.h"
25 class AwayMessage : public ClientProtocol::Message
28 AwayMessage(User* user)
29 : ClientProtocol::Message("AWAY", user)
31 SetParams(user, user->awaymsg);
35 : ClientProtocol::Message("AWAY")
39 void SetParams(User* user, const std::string& awaymsg)
41 // Going away: 1 parameter which is the away reason
42 // Back from away: no parameter
48 class JoinHook : public ClientProtocol::EventHook
50 ClientProtocol::Events::Join extendedjoinmsg;
53 const std::string asterisk;
54 ClientProtocol::EventProvider awayprotoev;
56 Cap::Capability extendedjoincap;
57 Cap::Capability awaycap;
60 : ClientProtocol::EventHook(mod, "JOIN")
62 , awayprotoev(mod, "AWAY")
63 , extendedjoincap(mod, "extended-join")
64 , awaycap(mod, "away-notify")
68 void OnEventInit(const ClientProtocol::Event& ev) CXX11_OVERRIDE
70 const ClientProtocol::Events::Join& join = static_cast<const ClientProtocol::Events::Join&>(ev);
72 // An extended join has two extra parameters:
73 // First the account name of the joining user or an asterisk if the user is not logged in.
74 // The second parameter is the realname of the joining user.
76 Membership* const memb = join.GetMember();
77 const std::string* account = &asterisk;
78 const AccountExtItem* const accountext = GetAccountExtItem();
81 const std::string* accountname = accountext->get(memb->user);
83 account = accountname;
86 extendedjoinmsg.ClearParams();
87 extendedjoinmsg.SetSource(join);
88 extendedjoinmsg.PushParamRef(memb->chan->name);
89 extendedjoinmsg.PushParamRef(*account);
90 extendedjoinmsg.PushParamRef(memb->user->GetRealName());
92 awaymsg.ClearParams();
93 if ((memb->user->IsAway()) && (awaycap.IsActive()))
95 awaymsg.SetSource(join);
96 awaymsg.SetParams(memb->user, memb->user->awaymsg);
100 ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) CXX11_OVERRIDE
102 if (extendedjoincap.get(user))
103 messagelist.front() = &extendedjoinmsg;
105 if ((!awaymsg.GetParams().empty()) && (awaycap.get(user)))
106 messagelist.push_back(&awaymsg);
108 return MOD_RES_PASSTHRU;
114 , public AccountEventListener
115 , public Away::EventListener
117 Cap::Capability cap_accountnotify;
120 ClientProtocol::EventProvider accountprotoev;
124 : AccountEventListener(this)
125 , Away::EventListener(this)
126 , cap_accountnotify(this, "account-notify")
128 , accountprotoev(this, "ACCOUNT")
132 void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
134 ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3");
135 cap_accountnotify.SetActive(conf->getBool("accountnotify", true));
136 joinhook.awaycap.SetActive(conf->getBool("awaynotify", true));
137 joinhook.extendedjoincap.SetActive(conf->getBool("extendedjoin", true));
140 void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE
142 // Logged in: 1 parameter which is the account name
143 // Logged out: 1 parameter which is a "*"
144 ClientProtocol::Message msg("ACCOUNT", user);
145 const std::string& param = (newaccount.empty() ? joinhook.asterisk : newaccount);
146 msg.PushParamRef(param);
147 ClientProtocol::Event accountevent(accountprotoev, msg);
148 IRCv3::WriteNeighborsWithCap(user, accountevent, cap_accountnotify);
151 void OnUserAway(User* user) CXX11_OVERRIDE
153 if (!joinhook.awaycap.IsActive())
156 // Going away: n!u@h AWAY :reason
157 AwayMessage msg(user);
158 ClientProtocol::Event awayevent(joinhook.awayprotoev, msg);
159 IRCv3::WriteNeighborsWithCap(user, awayevent, joinhook.awaycap);
162 void OnUserBack(User* user) CXX11_OVERRIDE
164 if (!joinhook.awaycap.IsActive())
167 // Back from away: n!u@h AWAY
168 AwayMessage msg(user);
169 ClientProtocol::Event awayevent(joinhook.awayprotoev, msg);
170 IRCv3::WriteNeighborsWithCap(user, awayevent, joinhook.awaycap);
173 Version GetVersion() CXX11_OVERRIDE
175 return Version("Provides support for extended-join, away-notify and account-notify CAP capabilities", VF_VENDOR);
179 MODULE_INIT(ModuleIRCv3)