2
* Copyright (C) 2004-2011 See the AUTHORS file for details.
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.
12
class CAutoVoiceUser {
16
CAutoVoiceUser(const CString& sLine) {
20
CAutoVoiceUser(const CString& sUsername, const CString& sHostmask, const CString& sChannels) :
21
m_sUsername(sUsername),
22
m_sHostmask(sHostmask) {
26
virtual ~CAutoVoiceUser() {}
28
const CString& GetUsername() const { return m_sUsername; }
29
const CString& GetHostmask() const { return m_sHostmask; }
31
bool ChannelMatches(const CString& sChan) const {
32
for (set<CString>::const_iterator it = m_ssChans.begin(); it != m_ssChans.end(); ++it) {
33
if (sChan.AsLower().WildCmp(*it)) {
41
bool HostMatches(const CString& sHostmask) {
42
return sHostmask.WildCmp(m_sHostmask);
45
CString GetChannels() const {
48
for (set<CString>::const_iterator it = m_ssChans.begin(); it != m_ssChans.end(); ++it) {
59
void DelChans(const CString& sChans) {
61
sChans.Split(" ", vsChans);
63
for (unsigned int a = 0; a < vsChans.size(); a++) {
64
m_ssChans.erase(vsChans[a].AsLower());
68
void AddChans(const CString& sChans) {
70
sChans.Split(" ", vsChans);
72
for (unsigned int a = 0; a < vsChans.size(); a++) {
73
m_ssChans.insert(vsChans[a].AsLower());
77
CString ToString() const {
80
for (set<CString>::const_iterator it = m_ssChans.begin(); it != m_ssChans.end(); ++it) {
81
if (!sChans.empty()) {
88
return m_sUsername + "\t" + m_sHostmask + "\t" + sChans;
91
bool FromString(const CString& sLine) {
92
m_sUsername = sLine.Token(0, false, "\t");
93
m_sHostmask = sLine.Token(1, false, "\t");
94
sLine.Token(2, false, "\t").Split(" ", m_ssChans);
96
return !m_sHostmask.empty();
102
set<CString> m_ssChans;
105
class CAutoVoiceMod : public CModule {
107
MODCONSTRUCTOR(CAutoVoiceMod) {}
109
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
110
// Load the chans from the command line
113
sArgs.Split(" ", vsChans, false);
115
for (VCString::const_iterator it = vsChans.begin(); it != vsChans.end(); ++it) {
116
CString sName = "Args";
118
AddUser(sName, "*", *it);
121
// Load the saved users
122
for (MCString::iterator it = BeginNV(); it != EndNV(); it++) {
123
const CString& sLine = it->second;
124
CAutoVoiceUser* pUser = new CAutoVoiceUser;
126
if (!pUser->FromString(sLine) || FindUser(pUser->GetUsername().AsLower())) {
129
m_msUsers[pUser->GetUsername().AsLower()] = pUser;
136
virtual ~CAutoVoiceMod() {
137
for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) {
144
virtual void OnJoin(const CNick& Nick, CChan& Channel) {
145
// If we have ops in this chan
146
if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) {
147
for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) {
148
// and the nick who joined is a valid user
149
if (it->second->HostMatches(Nick.GetHostMask()) && it->second->ChannelMatches(Channel.GetName())) {
150
PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick());
157
virtual void OnModCommand(const CString& sLine) {
158
CString sCommand = sLine.Token(0).AsUpper();
160
if (sCommand.Equals("HELP")) {
161
PutModule("Commands are: ListUsers, AddChans, DelChans, AddUser, DelUser");
162
} else if (sCommand.Equals("ADDUSER") || sCommand.Equals("DELUSER")) {
163
CString sUser = sLine.Token(1);
164
CString sHost = sLine.Token(2);
166
if (sCommand.Equals("ADDUSER")) {
168
PutModule("Usage: " + sCommand + " <user> <hostmask> [channels]");
170
CAutoVoiceUser* pUser = AddUser(sUser, sHost, sLine.Token(3, true));
173
SetNV(sUser, pUser->ToString());
180
} else if (sCommand.Equals("LISTUSERS")) {
181
if (m_msUsers.empty()) {
182
PutModule("There are no users defined");
188
Table.AddColumn("User");
189
Table.AddColumn("Hostmask");
190
Table.AddColumn("Channels");
192
for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) {
194
Table.SetCell("User", it->second->GetUsername());
195
Table.SetCell("Hostmask", it->second->GetHostmask());
196
Table.SetCell("Channels", it->second->GetChannels());
200
} else if (sCommand.Equals("ADDCHANS") || sCommand.Equals("DELCHANS")) {
201
CString sUser = sLine.Token(1);
202
CString sChans = sLine.Token(2, true);
204
if (sChans.empty()) {
205
PutModule("Usage: " + sCommand + " <user> <channel> [channel] ...");
209
CAutoVoiceUser* pUser = FindUser(sUser);
212
PutModule("No such user");
216
if (sCommand.Equals("ADDCHANS")) {
217
pUser->AddChans(sChans);
218
PutModule("Channel(s) added to user [" + pUser->GetUsername() + "]");
220
pUser->DelChans(sChans);
221
PutModule("Channel(s) Removed from user [" + pUser->GetUsername() + "]");
224
SetNV(pUser->GetUsername(), pUser->ToString());
226
PutModule("Unknown command, try HELP");
230
CAutoVoiceUser* FindUser(const CString& sUser) {
231
map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.find(sUser.AsLower());
233
return (it != m_msUsers.end()) ? it->second : NULL;
236
CAutoVoiceUser* FindUserByHost(const CString& sHostmask, const CString& sChannel = "") {
237
for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) {
238
CAutoVoiceUser* pUser = it->second;
240
if (pUser->HostMatches(sHostmask) && (sChannel.empty() || pUser->ChannelMatches(sChannel))) {
248
void DelUser(const CString& sUser) {
249
map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.find(sUser.AsLower());
251
if (it == m_msUsers.end()) {
252
PutModule("That user does not exist");
258
PutModule("User [" + sUser + "] removed");
261
CAutoVoiceUser* AddUser(const CString& sUser, const CString& sHost, const CString& sChans) {
262
if (m_msUsers.find(sUser) != m_msUsers.end()) {
263
PutModule("That user already exists");
267
CAutoVoiceUser* pUser = new CAutoVoiceUser(sUser, sHost, sChans);
268
m_msUsers[sUser.AsLower()] = pUser;
269
PutModule("User [" + sUser + "] added with hostmask [" + sHost + "]");
274
map<CString, CAutoVoiceUser*> m_msUsers;
277
MODULEDEFS(CAutoVoiceMod, "Auto voice the good guys")