- virtual void OnRehash(userrec* user, const std::string ¶meter)
- {
- /* Create a configreader class and read our flag,
- * in old versions this was heap-allocated and the
- * object was kept between rehashes...now we just
- * stack-allocate it locally.
- */
- ConfigReader Conf(ServerInstance);
-
- bool old_qa = QAPrefixes;
-
- FirstInGetsFounder = Conf.ReadFlag("options","noservices",0);
- QAPrefixes = Conf.ReadFlag("options","qaprefixes",0);
- DeprivSelf = Conf.ReadFlag("options","deprotectself",0);
- DeprivOthers = Conf.ReadFlag("options","deprotectothers",0);
-
- /* Did the user change the QA prefixes on the fly?
- * If so, remove all instances of the mode, and reinit
- * the module with prefixes enabled.
- */
- if ((old_qa != QAPrefixes) && (!booting))
- {
- ServerInstance->Modes->DelMode(cp);
- ServerInstance->Modes->DelMode(cf);
- DELETE(cp);
- DELETE(cf);
- cp = new ChanProtect(ServerInstance,QAPrefixes,DeprivSelf,DeprivOthers);
- cf = new ChanFounder(ServerInstance,QAPrefixes,DeprivSelf,DeprivOthers);
- /* These wont fail, we already owned the mode characters before */
- ServerInstance->AddMode(cp, 'a');
- ServerInstance->AddMode(cf, 'q');
- ServerInstance->WriteOpers("*** WARNING: +qa prefixes were enabled or disabled via a REHASH. Clients will probably need to reconnect to pick up this change.");
- }
- }
-
- virtual void OnUserJoin(userrec* user, chanrec* channel)
- {
- // if the user is the first user into the channel, mark them as the founder, but only if
- // the config option for it is set
- if (FirstInGetsFounder)
- {
- if (channel->GetUserCounter() == 1)
- {
- // we're using Extensible::Extend to add data into user objects.
- // this way is best as it adds data thats accessible to other modules
- // (so long as you document your code properly) without breaking anything
- // because its encapsulated neatly in a map.
-
- // Change requested by katsklaw... when the first in is set to get founder,
- // to make it clearer that +q has been given, send that one user the +q notice
- // so that their client's syncronization and their sanity are left intact.
- user->WriteServ("MODE %s +q %s",channel->name,user->nick);
- user->Extend("cm_founder_"+std::string(channel->name),fakevalue);
- }
- }
- }
-
- virtual int OnAccessCheck(userrec* source,userrec* dest,chanrec* channel,int access_type)
- {
- // here we perform access checks, this is the important bit that actually stops kicking/deopping
- // etc of protected users. There are many types of access check, we're going to handle
- // a relatively small number of them relevent to our module using a switch statement.
- // don't allow action if:
- // (A) Theyre founder (no matter what)
- // (B) Theyre protected, and you're not
- // always allow the action if:
- // (A) The source is ulined
-
-
- // firstly, if a ulined nick, or a server, is setting the mode, then allow them to set the mode
- // without any access checks, we're not worthy :p
- if ((ServerInstance->ULine(source->nick)) || (ServerInstance->ULine(source->server)) || (!*source->server))
- return ACR_ALLOW;
-
- std::string founder = "cm_founder_"+std::string(channel->name);
- std::string protect = "cm_protect_"+std::string(channel->name);
-
- switch (access_type)
- {
- // a user has been deopped. Do we let them? hmmm...
- case AC_DEOP:
- if (dest->GetExt(founder,dummyptr))
- {
- source->WriteServ("484 "+std::string(source->nick)+" "+std::string(channel->name)+" :Can't deop "+std::string(dest->nick)+" as they're a channel founder");
- return ACR_DENY;
- }
- if ((dest->GetExt(protect,dummyptr)) && (!source->GetExt(protect,dummyptr)))
- {
- source->WriteServ("484 "+std::string(source->nick)+" "+std::string(channel->name)+" :Can't deop "+std::string(dest->nick)+" as they're protected (+a)");
- return ACR_DENY;
- }
- break;