updated on Sun Jan 22 16:00:49 UTC 2012
[aur-mirror.git] / znc-amsgfilter / amsgfilter.cpp
blobde4cb67980e3081e576b7487c749f0123a699494
1 /*
2 * Copyright (C) 2008 kroimon
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation.
7 */
9 #include "User.h"
10 #include "Modules.h"
11 #include "string.h"
12 #include "Chan.h"
14 class CAmsgFilterModule : public CModule {
15 public:
16 MODCONSTRUCTOR(CAmsgFilterModule) {}
17 virtual ~CAmsgFilterModule() {}
19 virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
20 unsigned int i = 0;
21 CString sChan = sArgs.Token(i++);
22 while (!sChan.empty()) {
23 if (!Add(sChan))
24 PutModule("Unable to add [" + sChan + "]");
25 sChan = sArgs.Token(i++);
28 // Load our saved settings, ignore errors
29 for (MCString::iterator it = BeginNV(); it != EndNV(); it++)
30 Add(it->first);
32 return true;
35 virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) {
36 SCString sTargets;
37 sTarget.Split(",", sTargets);
39 if (IsAmsg(sTargets)) {
40 sTarget.clear();
41 for (SCString::iterator itTarget = sTargets.begin(); itTarget != sTargets.end(); itTarget++) {
42 if (!IsFiltered(*itTarget)) {
43 if (!sTarget.empty())
44 sTarget.append(",");
45 sTarget.append(*itTarget);
46 } else {
47 PutUser(":" + GetModNick() + " PRIVMSG " + *itTarget + " :amsg blocked in this channel: " + sMessage);
52 return CONTINUE;
55 virtual void OnModCommand(const CString& sLine) {
56 CString sCommand = sLine.Token(0).AsLower();
58 if (sCommand == "add") {
59 CString sChan = sLine.Token(1);
60 if (AlreadyAdded(sChan)) {
61 PutModule(sChan + " is already added");
62 } else if (Add(sChan)) {
63 PutModule("Added " + sChan + " to amsg filter list");
64 } else {
65 PutModule("Usage: Add [!]<#chan>");
68 } else if (sCommand == "del") {
69 CString sChan = sLine.Token(1);
70 if (Del(sChan))
71 PutModule("Removed " + sChan + " from amsg filter list");
72 else
73 PutModule("Usage: Del [!]<#chan>");
75 } else if (sCommand == "list") {
76 CTable Table;
77 Table.AddColumn("Channel");
79 for (unsigned int i = 0; i < vsChans.size(); i++) {
80 Table.AddRow();
81 Table.SetCell("Channel", vsChans[i]);
84 for (unsigned int i = 0; i < vsNegChans.size(); i++) {
85 Table.AddRow();
86 Table.SetCell("Channel", "!" + vsNegChans[i]);
89 if (Table.size()) {
90 unsigned int i = 0;
91 CString sTmp;
92 while (Table.GetLine(i++, sTmp))
93 PutModule(sTmp);
94 } else
95 PutModule("You have no amsg filters");
97 } else if (sCommand == "help") {
98 CTable Table;
99 Table.AddColumn("Command");
100 Table.AddColumn("Description");
102 Table.AddRow();
103 Table.SetCell("Command", "Add");
104 Table.SetCell("Description", "Add an entry, use !#chan to negate and * for wildcards");
106 Table.AddRow();
107 Table.SetCell("Command", "Del");
108 Table.SetCell("Description", "Remove an entry, needs to be an exact match");
110 Table.AddRow();
111 Table.SetCell("Command", "List");
112 Table.SetCell("Description", "List all entries");
114 unsigned int uTableIdx = 0;
115 CString sTmp;
117 while (Table.GetLine(uTableIdx++, sTmp))
118 PutModule(sTmp);
123 private:
124 VCString vsChans;
125 VCString vsNegChans;
127 bool IsAmsg(SCString& sTargets) {
128 /* amsgs can't go to just one channel */
129 if (sTargets.size() == 1)
130 return false;
132 /* check that sTargets includes all attached channels */
133 const vector<CChan*>& vChans = m_pUser->GetChans();
134 for (unsigned int i = 0; i < vChans.size(); i++) {
135 CChan* pChan = vChans[i];
136 if (pChan->IsDetached())
137 continue;
138 SCString::iterator it = sTargets.find(pChan->GetName());
139 if (it == sTargets.end())
140 return false;
143 return true;
146 bool IsFiltered(const CString& sChan) {
147 for (unsigned int i = 0; i < vsNegChans.size(); i++)
148 if (sChan.WildCmp(vsNegChans[i]))
149 return false;
150 for (unsigned int i = 0; i < vsChans.size(); i++)
151 if (sChan.WildCmp(vsChans[i]))
152 return true;
153 return false;
156 bool AlreadyAdded(const CString& sInput) {
157 VCString::iterator it;
159 if (sInput.Left(1) == "!") {
160 CString sChan = sInput.substr(1);
161 for (it = vsNegChans.begin(); it != vsNegChans.end(); it++)
162 if (*it == sChan)
163 return true;
164 } else {
165 for (it = vsChans.begin(); it != vsChans.end(); it++)
166 if (*it == sInput)
167 return true;
169 return false;
172 bool Add(const CString& sChan) {
173 if (sChan.empty() || sChan == "!")
174 return false;
176 if (sChan.Left(1) == "!")
177 vsNegChans.push_back(sChan.substr(1));
178 else
179 vsChans.push_back(sChan);
181 // Also save it for next module load
182 SetNV(sChan, "");
184 return true;
187 bool Del(const CString& sChan) {
188 VCString::iterator it, end;
190 if (sChan.empty() || sChan == "!")
191 return false;
193 if (sChan.Left(1) == "!") {
194 CString sTmp = sChan.substr(1);
195 it = vsNegChans.begin();
196 end = vsNegChans.end();
198 for (; it != end; it++)
199 if (*it == sTmp)
200 break;
202 if (it == end)
203 return false;
205 vsNegChans.erase(it);
206 } else {
207 it = vsChans.begin();
208 end = vsChans.end();
210 for (; it != end; it++)
211 if (*it == sChan)
212 break;
214 if (it == end)
215 return false;
217 vsChans.erase(it);
220 DelNV(sChan);
222 return true;
227 MODULEDEFS(CAmsgFilterModule, "Excludes channels from amsgs")