#include "inspircd.h"
#include "modules/exemption.h"
+#include "modules/who.h"
class AuditoriumMode : public SimpleChannelModeHandler
{
}
};
-class ModuleAuditorium : public Module
+class ModuleAuditorium;
+
+namespace
+{
+
+/** Hook handler for join client protocol events.
+ * This allows us to block join protocol events completely, including all associated messages (e.g. MODE, away-notify AWAY).
+ * This is not the same as OnUserJoin() because that runs only when a real join happens but this runs also when a module
+ * such as delayjoin or hostcycle generates a join.
+ */
+class JoinHook : public ClientProtocol::EventHook
+{
+ ModuleAuditorium* const parentmod;
+ bool active;
+
+ public:
+ JoinHook(ModuleAuditorium* mod);
+ void OnEventInit(const ClientProtocol::Event& ev) CXX11_OVERRIDE;
+ ModResult OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist) CXX11_OVERRIDE;
+};
+
+}
+
+class ModuleAuditorium
+ : public Module
+ , public Who::EventListener
{
CheckExemption::EventProvider exemptionprov;
AuditoriumMode aum;
bool OpsVisible;
bool OpsCanSee;
bool OperCanSee;
+ JoinHook joinhook;
public:
ModuleAuditorium()
- : exemptionprov(this)
+ : Who::EventListener(this)
+ , exemptionprov(this)
, aum(this)
+ , joinhook(this)
{
}
}
}
- void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) CXX11_OVERRIDE
- {
- BuildExcept(memb, excepts);
- }
-
void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts) CXX11_OVERRIDE
{
BuildExcept(memb, excepts);
}
}
- ModResult OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Membership* memb, Numeric::Numeric& numeric) CXX11_OVERRIDE
+ ModResult OnWhoLine(const Who::Request& request, LocalUser* source, User* user, Membership* memb, Numeric::Numeric& numeric) CXX11_OVERRIDE
{
if (!memb)
return MOD_RES_PASSTHRU;
}
};
+JoinHook::JoinHook(ModuleAuditorium* mod)
+ : ClientProtocol::EventHook(mod, "JOIN", 10)
+ , parentmod(mod)
+{
+}
+
+void JoinHook::OnEventInit(const ClientProtocol::Event& ev)
+{
+ const ClientProtocol::Events::Join& join = static_cast<const ClientProtocol::Events::Join&>(ev);
+ active = !parentmod->IsVisible(join.GetMember());
+}
+
+ModResult JoinHook::OnPreEventSend(LocalUser* user, const ClientProtocol::Event& ev, ClientProtocol::MessageList& messagelist)
+{
+ if (!active)
+ return MOD_RES_PASSTHRU;
+
+ const ClientProtocol::Events::Join& join = static_cast<const ClientProtocol::Events::Join&>(ev);
+ return ((parentmod->CanSee(user, join.GetMember())) ? MOD_RES_PASSTHRU : MOD_RES_DENY);
+}
+
MODULE_INIT(ModuleAuditorium)