+int FilterBase::OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line)
+{
+ flags = 0;
+ if ((validated == 1) && (IS_LOCAL(user)))
+ {
+ std::string checkline;
+ int replacepoint = 0;
+ bool parting = false;
+
+ if (command == "QUIT")
+ {
+ /* QUIT with no reason: nothing to do */
+ if (pcnt < 1)
+ return 0;
+
+ checkline = parameters[0];
+ replacepoint = 0;
+ parting = false;
+ flags = FLAG_QUIT;
+ }
+ else if (command == "PART")
+ {
+ /* PART with no reason: nothing to do */
+ if (pcnt < 2)
+ return 0;
+
+ checkline = parameters[1];
+ replacepoint = 1;
+ parting = true;
+ flags = FLAG_PART;
+ }
+ else
+ /* We're only messing with PART and QUIT */
+ return 0;
+
+ FilterResult* f = NULL;
+
+ if (flags)
+ f = this->FilterMatch(user, checkline, flags);
+
+ if (!f)
+ /* PART or QUIT reason doesnt match a filter */
+ return 0;
+
+ /* We cant block a part or quit, so instead we change the reason to 'Reason filtered' */
+ command_t* c = ServerInstance->Parser->GetHandler(command);
+ if (c)
+ {
+ const char* params[MAXPARAMETERS];
+ for (int item = 0; item < pcnt; item++)
+ params[item] = parameters[item];
+ params[replacepoint] = "Reason filtered";
+
+ /* We're blocking, OR theyre quitting and its a KILL action
+ * (we cant kill someone whos already quitting, so filter them anyway)
+ */
+ if ((f->action == "block") || (((!parting) && (f->action == "kill"))) || (f->action == "silent"))
+ {
+ c->Handle(params, pcnt, user);
+ return 1;
+ }
+ else
+ {
+ /* Are they parting, if so, kill is applicable */
+ if ((parting) && (f->action == "kill"))
+ {
+ user->WriteServ("NOTICE %s :*** Your PART message was filtered: %s", user->nick, f->reason.c_str());
+ userrec::QuitUser(ServerInstance, user, "Filtered: " + f->reason);
+ }
+ if (f->action == "gline")
+ {
+ /* Note: We gline *@IP so that if their host doesnt resolve the gline still applies. */
+ std::string wild = "*@";
+ wild.append(user->GetIPString());
+
+ if (ServerInstance->XLines->add_gline(f->gline_time, ServerInstance->Config->ServerName, f->reason.c_str(), wild.c_str()))
+ {
+ ServerInstance->XLines->apply_lines(APPLY_GLINES);
+ FOREACH_MOD(I_OnAddGLine,OnAddGLine(f->gline_time, NULL, f->reason, user->MakeHostIP()));
+ }
+ }
+ return 1;
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+void FilterBase::OnRehash(userrec* user, const std::string ¶meter)