+class AwayMessage : public ClientProtocol::Message
+{
+ public:
+ AwayMessage(User* user)
+ : ClientProtocol::Message("AWAY", user)
+ {
+ SetParams(user, user->awaymsg);
+ }
+
+ AwayMessage()
+ : ClientProtocol::Message("AWAY")
+ {
+ }
+
+ void SetParams(User* user, const std::string& awaymsg)
+ {
+ // Going away: 1 parameter which is the away reason
+ // Back from away: no parameter
+ if (!awaymsg.empty())
+ PushParam(awaymsg);
+ }
+};
+
+class JoinHook : public ClientProtocol::EventHook
+{
+ ClientProtocol::Events::Join extendedjoinmsg;
+
+ public:
+ const std::string asterisk;
+ ClientProtocol::EventProvider awayprotoev;
+ AwayMessage awaymsg;
+ Cap::Capability extendedjoincap;
+ Cap::Capability awaycap;
+
+ JoinHook(Module* mod)
+ : ClientProtocol::EventHook(mod, "JOIN")
+ , asterisk(1, '*')
+ , awayprotoev(mod, "AWAY")
+ , extendedjoincap(mod, "extended-join")
+ , awaycap(mod, "away-notify")
+ {
+ }
+
+ void OnEventInit(const ClientProtocol::Event& ev) CXX11_OVERRIDE
+ {
+ const ClientProtocol::Events::Join& join = static_cast<const ClientProtocol::Events::Join&>(ev);
+
+ // An extended join has two extra parameters:
+ // First the account name of the joining user or an asterisk if the user is not logged in.
+ // The second parameter is the realname of the joining user.
+
+ Membership* const memb = join.GetMember();
+ const std::string* account = &asterisk;
+ const AccountExtItem* const accountext = GetAccountExtItem();
+ if (accountext)
+ {
+ const std::string* accountname = accountext->get(memb->user);
+ if (accountname)
+ account = accountname;
+ }
+
+ extendedjoinmsg.ClearParams();
+ extendedjoinmsg.SetSource(join);
+ extendedjoinmsg.PushParamRef(memb->chan->name);
+ extendedjoinmsg.PushParamRef(*account);
+ extendedjoinmsg.PushParamRef(memb->user->GetRealName());
+
+ awaymsg.ClearParams();
+ if ((memb->user->IsAway()) && (awaycap.IsActive()))
+ {
+ awaymsg.SetSource(join);
+ awaymsg.SetParams(memb->user, memb->user->awaymsg);
+ }
+ }
+
+ ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) CXX11_OVERRIDE
+ {
+ if (extendedjoincap.get(user))
+ messagelist.front() = &extendedjoinmsg;
+
+ if ((!awaymsg.GetParams().empty()) && (awaycap.get(user)))
+ messagelist.push_back(&awaymsg);
+
+ return MOD_RES_PASSTHRU;
+ }
+};
+