2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013, 2018-2019 Sadie Powell <sadie@witchery.services>
5 * Copyright (C) 2012, 2015, 2018 Attila Molnar <attilamolnar@hush.com>
7 * This file is part of InspIRCd. InspIRCd is free software: you can
8 * redistribute it and/or modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation, version 2.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "modules/account.h"
22 #include "modules/away.h"
23 #include "modules/cap.h"
24 #include "modules/ircv3.h"
26 class AwayMessage : public ClientProtocol::Message
29 AwayMessage(User* user)
30 : ClientProtocol::Message("AWAY", user)
32 SetParams(user, user->awaymsg);
36 : ClientProtocol::Message("AWAY")
40 void SetParams(User* user, const std::string& awaymsg)
42 // Going away: 1 parameter which is the away reason
43 // Back from away: no parameter
49 class JoinHook : public ClientProtocol::EventHook
51 ClientProtocol::Events::Join extendedjoinmsg;
54 const std::string asterisk;
55 ClientProtocol::EventProvider awayprotoev;
57 Cap::Capability extendedjoincap;
58 Cap::Capability awaycap;
61 : ClientProtocol::EventHook(mod, "JOIN")
63 , awayprotoev(mod, "AWAY")
64 , extendedjoincap(mod, "extended-join")
65 , awaycap(mod, "away-notify")
69 void OnEventInit(const ClientProtocol::Event& ev) CXX11_OVERRIDE
71 const ClientProtocol::Events::Join& join = static_cast<const ClientProtocol::Events::Join&>(ev);
73 // An extended join has two extra parameters:
74 // First the account name of the joining user or an asterisk if the user is not logged in.
75 // The second parameter is the realname of the joining user.
77 Membership* const memb = join.GetMember();
78 const std::string* account = &asterisk;
79 const AccountExtItem* const accountext = GetAccountExtItem();
82 const std::string* accountname = accountext->get(memb->user);
84 account = accountname;
87 extendedjoinmsg.ClearParams();
88 extendedjoinmsg.SetSource(join);
89 extendedjoinmsg.PushParamRef(memb->chan->name);
90 extendedjoinmsg.PushParamRef(*account);
91 extendedjoinmsg.PushParamRef(memb->user->GetRealName());
93 awaymsg.ClearParams();
94 if ((memb->user->IsAway()) && (awaycap.IsActive()))
96 awaymsg.SetSource(join);
97 awaymsg.SetParams(memb->user, memb->user->awaymsg);
101 ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) CXX11_OVERRIDE
103 if (extendedjoincap.get(user))
104 messagelist.front() = &extendedjoinmsg;
106 if ((!awaymsg.GetParams().empty()) && (awaycap.get(user)))
107 messagelist.push_back(&awaymsg);
109 return MOD_RES_PASSTHRU;
115 , public AccountEventListener
116 , public Away::EventListener
118 Cap::Capability cap_accountnotify;
121 ClientProtocol::EventProvider accountprotoev;
125 : AccountEventListener(this)
126 , Away::EventListener(this)
127 , cap_accountnotify(this, "account-notify")
129 , accountprotoev(this, "ACCOUNT")
133 void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
135 ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3");
136 cap_accountnotify.SetActive(conf->getBool("accountnotify", true));
137 joinhook.awaycap.SetActive(conf->getBool("awaynotify", true));
138 joinhook.extendedjoincap.SetActive(conf->getBool("extendedjoin", true));
141 void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE
143 if (!(user->registered & REG_NICKUSER))
146 // Logged in: 1 parameter which is the account name
147 // Logged out: 1 parameter which is a "*"
148 ClientProtocol::Message msg("ACCOUNT", user);
149 const std::string& param = (newaccount.empty() ? joinhook.asterisk : newaccount);
150 msg.PushParamRef(param);
151 ClientProtocol::Event accountevent(accountprotoev, msg);
152 IRCv3::WriteNeighborsWithCap(user, accountevent, cap_accountnotify);
155 void OnUserAway(User* user) CXX11_OVERRIDE
157 if (!joinhook.awaycap.IsActive())
160 // Going away: n!u@h AWAY :reason
161 AwayMessage msg(user);
162 ClientProtocol::Event awayevent(joinhook.awayprotoev, msg);
163 IRCv3::WriteNeighborsWithCap(user, awayevent, joinhook.awaycap);
166 void OnUserBack(User* user) CXX11_OVERRIDE
168 if (!joinhook.awaycap.IsActive())
171 // Back from away: n!u@h AWAY
172 AwayMessage msg(user);
173 ClientProtocol::Event awayevent(joinhook.awayprotoev, msg);
174 IRCv3::WriteNeighborsWithCap(user, awayevent, joinhook.awaycap);
177 Version GetVersion() CXX11_OVERRIDE
179 return Version("Provides support for extended-join, away-notify and account-notify CAP capabilities", VF_VENDOR);
183 MODULE_INIT(ModuleIRCv3)