1.1.3
by Joey Hess
Import upstream version 0.052 |
1 |
/*
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
2 |
* Copyright (C) 2004-2011 See the AUTHORS file for details.
|
1.1.3
by Joey Hess
Import upstream version 0.052 |
3 |
*
|
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 |
*/
|
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
8 |
|
1
by Joey Hess
Import upstream version 0.045 |
9 |
#include "Chan.h" |
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
10 |
#include "FileUtils.h" |
1.1.4
by Joey Hess
Import upstream version 0.054 |
11 |
#include "IRCSock.h" |
12 |
#include "User.h" |
|
1
by Joey Hess
Import upstream version 0.045 |
13 |
#include "znc.h" |
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
14 |
#include "Config.h" |
1
by Joey Hess
Import upstream version 0.045 |
15 |
|
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
16 |
CChan::CChan(const CString& sName, CUser* pUser, bool bInConfig, CConfig *pConfig) { |
1
by Joey Hess
Import upstream version 0.045 |
17 |
m_sName = sName.Token(0); |
18 |
m_sKey = sName.Token(1); |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
19 |
m_pUser = pUser; |
1
by Joey Hess
Import upstream version 0.045 |
20 |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
21 |
if (!m_pUser->IsChan(m_sName)) { |
1
by Joey Hess
Import upstream version 0.045 |
22 |
m_sName = "#" + m_sName; |
23 |
}
|
|
24 |
||
25 |
m_bInConfig = bInConfig; |
|
26 |
m_Nick.SetUser(pUser); |
|
27 |
m_bDetached = false; |
|
28 |
m_uBufferCount = m_pUser->GetBufferCount(); |
|
29 |
m_bKeepBuffer = m_pUser->KeepBuffer(); |
|
1.1.2
by Joey Hess
Import upstream version 0.050 |
30 |
m_bDisabled = false; |
1
by Joey Hess
Import upstream version 0.045 |
31 |
Reset(); |
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
32 |
|
33 |
if (pConfig) { |
|
34 |
CString sValue; |
|
35 |
if (pConfig->FindStringEntry("buffer", sValue)) |
|
36 |
SetBufferCount(sValue.ToUInt(), true); |
|
37 |
if (pConfig->FindStringEntry("keepbuffer", sValue)) |
|
38 |
SetKeepBuffer(sValue.ToBool()); |
|
39 |
if (pConfig->FindStringEntry("detached", sValue)) |
|
40 |
SetDetached(sValue.ToBool()); |
|
41 |
if (pConfig->FindStringEntry("autocycle", sValue)) |
|
42 |
if (sValue.Equals("true")) |
|
43 |
CUtils::PrintError("WARNING: AutoCycle has been removed, instead try -> LoadModule = autocycle " + sName); |
|
44 |
if (pConfig->FindStringEntry("key", sValue)) |
|
45 |
SetKey(sValue); |
|
46 |
if (pConfig->FindStringEntry("modes", sValue)) |
|
47 |
SetDefaultModes(sValue); |
|
48 |
}
|
|
1
by Joey Hess
Import upstream version 0.045 |
49 |
}
|
1.1.2
by Joey Hess
Import upstream version 0.050 |
50 |
|
1
by Joey Hess
Import upstream version 0.045 |
51 |
CChan::~CChan() { |
52 |
ClearNicks(); |
|
53 |
}
|
|
54 |
||
55 |
void CChan::Reset() { |
|
56 |
m_bIsOn = false; |
|
57 |
m_musModes.clear(); |
|
58 |
m_sTopic = ""; |
|
59 |
m_sTopicOwner = ""; |
|
60 |
m_ulTopicDate = 0; |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
61 |
m_ulCreationDate = 0; |
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
62 |
m_Nick.Reset(); |
1
by Joey Hess
Import upstream version 0.045 |
63 |
ClearNicks(); |
1.1.2
by Joey Hess
Import upstream version 0.050 |
64 |
ResetJoinTries(); |
1
by Joey Hess
Import upstream version 0.045 |
65 |
}
|
66 |
||
67 |
bool CChan::WriteConfig(CFile& File) { |
|
68 |
if (!InConfig()) { |
|
69 |
return false; |
|
70 |
}
|
|
71 |
||
1.2.1
by Patrick Matthäi
Import upstream version 0.066 |
72 |
File.Write("\t<Chan " + GetName().FirstLine() + ">\n"); |
1
by Joey Hess
Import upstream version 0.045 |
73 |
|
1.1.4
by Joey Hess
Import upstream version 0.054 |
74 |
if (m_pUser->GetBufferCount() != GetBufferCount()) |
1.2.1
by Patrick Matthäi
Import upstream version 0.066 |
75 |
m_pUser->PrintLine(File, "\tBuffer", CString(GetBufferCount())); |
1.1.4
by Joey Hess
Import upstream version 0.054 |
76 |
if (m_pUser->KeepBuffer() != KeepBuffer()) |
1.2.1
by Patrick Matthäi
Import upstream version 0.066 |
77 |
m_pUser->PrintLine(File, "\tKeepBuffer", CString(KeepBuffer())); |
1.1.4
by Joey Hess
Import upstream version 0.054 |
78 |
if (IsDetached()) |
1.2.1
by Patrick Matthäi
Import upstream version 0.066 |
79 |
m_pUser->PrintLine(File, "\tDetached", "true"); |
80 |
if (!GetKey().empty()) |
|
81 |
m_pUser->PrintLine(File, "\tKey", GetKey()); |
|
82 |
if (!GetDefaultModes().empty()) |
|
83 |
m_pUser->PrintLine(File, "\tModes", GetDefaultModes()); |
|
1
by Joey Hess
Import upstream version 0.045 |
84 |
|
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
85 |
File.Write("\t</Chan>\n"); |
1
by Joey Hess
Import upstream version 0.045 |
86 |
return true; |
87 |
}
|
|
88 |
||
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
89 |
void CChan::Clone(CChan& chan) { |
90 |
// We assume that m_sName and m_pUser are equal
|
|
1.3.8
by Patrick Matthäi
Import upstream version 0.094 |
91 |
SetBufferCount(chan.GetBufferCount(), true); |
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
92 |
SetKeepBuffer(chan.KeepBuffer()); |
93 |
SetKey(chan.GetKey()); |
|
94 |
SetDefaultModes(chan.GetDefaultModes()); |
|
95 |
||
96 |
if (IsDetached() != chan.IsDetached()) { |
|
97 |
// Only send something if it makes sense
|
|
98 |
// (= Only detach if client is on the channel
|
|
99 |
// and only attach if we are on the channel)
|
|
100 |
if (IsOn()) { |
|
101 |
if (IsDetached()) { |
|
102 |
JoinUser(false, ""); |
|
103 |
} else { |
|
104 |
DetachUser(); |
|
105 |
}
|
|
106 |
}
|
|
107 |
SetDetached(chan.IsDetached()); |
|
108 |
}
|
|
1
by Joey Hess
Import upstream version 0.045 |
109 |
}
|
110 |
||
1.3.8
by Patrick Matthäi
Import upstream version 0.094 |
111 |
bool CChan::SetBufferCount(unsigned int u, bool bForce) { |
112 |
if (!bForce && u > CZNC::Get().GetMaxBufferSize()) |
|
113 |
return false; |
|
114 |
m_uBufferCount = u; |
|
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
115 |
TrimBuffer(m_uBufferCount); |
1.3.8
by Patrick Matthäi
Import upstream version 0.094 |
116 |
return true; |
117 |
}
|
|
118 |
||
1
by Joey Hess
Import upstream version 0.045 |
119 |
void CChan::Cycle() const { |
120 |
m_pUser->PutIRC("PART " + GetName() + "\r\nJOIN " + GetName() + " " + GetKey()); |
|
121 |
}
|
|
122 |
||
123 |
void CChan::JoinUser(bool bForce, const CString& sKey, CClient* pClient) { |
|
124 |
if (!bForce && (!IsOn() || !IsDetached())) { |
|
125 |
m_pUser->PutIRC("JOIN " + GetName() + " " + ((sKey.empty()) ? GetKey() : sKey)); |
|
20
by Patrick Matthäi
* Merge 0.092-1~bpo50+1 changelog. |
126 |
SetDetached(false); |
1
by Joey Hess
Import upstream version 0.045 |
127 |
return; |
128 |
}
|
|
129 |
||
130 |
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " JOIN :" + GetName(), pClient); |
|
131 |
||
132 |
if (!GetTopic().empty()) { |
|
133 |
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 332 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :" + GetTopic(), pClient); |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
134 |
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 333 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " " + GetTopicOwner() + " " + CString(GetTopicDate()), pClient); |
1
by Joey Hess
Import upstream version 0.045 |
135 |
}
|
136 |
||
1.1.1
by Joey Hess
Import upstream version 0.047 |
137 |
CString sPre = ":" + m_pUser->GetIRCServer() + " 353 " + m_pUser->GetIRCNick().GetNick() + " " + GetModeForNames() + " " + GetName() + " :"; |
1
by Joey Hess
Import upstream version 0.045 |
138 |
CString sLine = sPre; |
1.1.1
by Joey Hess
Import upstream version 0.047 |
139 |
CString sPerm, sNick; |
140 |
||
141 |
vector<CClient*>& vpClients = m_pUser->GetClients(); |
|
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
142 |
for (vector<CClient*>::iterator it = vpClients.begin(); it != vpClients.end(); ++it) { |
1.1.1
by Joey Hess
Import upstream version 0.047 |
143 |
CClient* pThisClient; |
144 |
if (!pClient) |
|
145 |
pThisClient = *it; |
|
146 |
else
|
|
147 |
pThisClient = pClient; |
|
148 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
149 |
for (map<CString,CNick>::iterator a = m_msNicks.begin(); a != m_msNicks.end(); ++a) { |
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
150 |
if (pThisClient->HasNamesx()) { |
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
151 |
sPerm = a->second.GetPermStr(); |
1.1.1
by Joey Hess
Import upstream version 0.047 |
152 |
} else { |
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
153 |
char c = a->second.GetPermChar(); |
1.1.1
by Joey Hess
Import upstream version 0.047 |
154 |
sPerm = ""; |
155 |
if (c != '\0') { |
|
156 |
sPerm += c; |
|
157 |
}
|
|
158 |
}
|
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
159 |
if (pThisClient->HasUHNames() && !a->second.GetIdent().empty() && !a->second.GetHost().empty()) { |
160 |
sNick = a->first + "!" + a->second.GetIdent() + "@" + a->second.GetHost(); |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
161 |
} else { |
162 |
sNick = a->first; |
|
163 |
}
|
|
164 |
||
165 |
sLine += sPerm + sNick; |
|
166 |
||
167 |
if (sLine.size() >= 490 || a == (--m_msNicks.end())) { |
|
168 |
m_pUser->PutUser(sLine, pThisClient); |
|
169 |
sLine = sPre; |
|
170 |
} else { |
|
171 |
sLine += " "; |
|
172 |
}
|
|
173 |
}
|
|
174 |
||
175 |
if (pClient) // We only want to do this for one client |
|
176 |
break; |
|
1
by Joey Hess
Import upstream version 0.045 |
177 |
}
|
178 |
||
179 |
m_pUser->PutUser(":" + m_pUser->GetIRCServer() + " 366 " + m_pUser->GetIRCNick().GetNick() + " " + GetName() + " :End of /NAMES list.", pClient); |
|
180 |
m_bDetached = false; |
|
181 |
||
182 |
// Send Buffer
|
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
183 |
SendBuffer(pClient); |
1
by Joey Hess
Import upstream version 0.045 |
184 |
}
|
185 |
||
186 |
void CChan::DetachUser() { |
|
187 |
if (!m_bDetached) { |
|
188 |
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " PART " + GetName()); |
|
189 |
m_bDetached = true; |
|
190 |
}
|
|
191 |
}
|
|
192 |
||
193 |
void CChan::AttachUser() { |
|
194 |
if (m_bDetached) { |
|
195 |
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " JOIN " + GetName()); |
|
196 |
m_bDetached = false; |
|
197 |
}
|
|
198 |
}
|
|
199 |
||
200 |
CString CChan::GetModeString() const { |
|
201 |
CString sModes, sArgs; |
|
202 |
||
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
203 |
for (map<unsigned char, CString>::const_iterator it = m_musModes.begin(); it != m_musModes.end(); ++it) { |
1
by Joey Hess
Import upstream version 0.045 |
204 |
sModes += it->first; |
205 |
if (it->second.size()) { |
|
206 |
sArgs += " " + it->second; |
|
207 |
}
|
|
208 |
}
|
|
209 |
||
1.1.2
by Joey Hess
Import upstream version 0.050 |
210 |
return sModes.empty() ? sModes : CString("+" + sModes + sArgs); |
1
by Joey Hess
Import upstream version 0.045 |
211 |
}
|
212 |
||
1.1.1
by Joey Hess
Import upstream version 0.047 |
213 |
CString CChan::GetModeForNames() const { |
214 |
CString sMode; |
|
1.1.4
by Joey Hess
Import upstream version 0.054 |
215 |
|
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
216 |
for (map<unsigned char, CString>::const_iterator it = m_musModes.begin(); it != m_musModes.end(); ++it) { |
1.1.1
by Joey Hess
Import upstream version 0.047 |
217 |
if (it->first == 's') { |
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
218 |
sMode = "@"; |
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
219 |
} else if ((it->first == 'p') && sMode.empty()) { |
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
220 |
sMode = "*"; |
1.1.1
by Joey Hess
Import upstream version 0.047 |
221 |
}
|
222 |
}
|
|
223 |
||
224 |
return (sMode.empty() ? "=" : sMode); |
|
225 |
}
|
|
1.1.4
by Joey Hess
Import upstream version 0.054 |
226 |
|
1
by Joey Hess
Import upstream version 0.045 |
227 |
void CChan::SetModes(const CString& sModes) { |
228 |
m_musModes.clear(); |
|
229 |
ModeChange(sModes); |
|
230 |
}
|
|
231 |
||
232 |
void CChan::OnWho(const CString& sNick, const CString& sIdent, const CString& sHost) { |
|
233 |
CNick* pNick = FindNick(sNick); |
|
234 |
||
235 |
if (pNick) { |
|
236 |
pNick->SetIdent(sIdent); |
|
237 |
pNick->SetHost(sHost); |
|
238 |
}
|
|
239 |
}
|
|
240 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
241 |
void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { |
1
by Joey Hess
Import upstream version 0.045 |
242 |
CString sModeArg = sModes.Token(0); |
243 |
CString sArgs = sModes.Token(1, true); |
|
244 |
bool bAdd = true; |
|
245 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
246 |
/* Try to find a CNick* from this channel so that pOpNick->HasPerm()
|
247 |
* works as expected. */
|
|
248 |
if (pOpNick) { |
|
249 |
CNick* OpNick = FindNick(pOpNick->GetNick()); |
|
250 |
/* If nothing was found, use the original pOpNick, else use the
|
|
251 |
* CNick* from FindNick() */
|
|
252 |
if (OpNick) |
|
253 |
pOpNick = OpNick; |
|
254 |
}
|
|
1
by Joey Hess
Import upstream version 0.045 |
255 |
|
256 |
if (pOpNick) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
257 |
MODULECALL(OnRawMode(*pOpNick, *this, sModeArg, sArgs), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
258 |
}
|
259 |
||
260 |
for (unsigned int a = 0; a < sModeArg.size(); a++) { |
|
261 |
const unsigned char& uMode = sModeArg[a]; |
|
262 |
||
263 |
if (uMode == '+') { |
|
264 |
bAdd = true; |
|
265 |
} else if (uMode == '-') { |
|
266 |
bAdd = false; |
|
267 |
} else if (m_pUser->GetIRCSock()->IsPermMode(uMode)) { |
|
268 |
CString sArg = GetModeArg(sArgs); |
|
269 |
CNick* pNick = FindNick(sArg); |
|
270 |
if (pNick) { |
|
271 |
unsigned char uPerm = m_pUser->GetIRCSock()->GetPermFromMode(uMode); |
|
272 |
||
273 |
if (uPerm) { |
|
274 |
if (bAdd) { |
|
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
275 |
pNick->AddPerm(uPerm); |
1
by Joey Hess
Import upstream version 0.045 |
276 |
|
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
277 |
if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { |
1
by Joey Hess
Import upstream version 0.045 |
278 |
AddPerm(uPerm); |
279 |
}
|
|
280 |
} else { |
|
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
281 |
pNick->RemPerm(uPerm); |
1
by Joey Hess
Import upstream version 0.045 |
282 |
|
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
283 |
if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { |
1
by Joey Hess
Import upstream version 0.045 |
284 |
RemPerm(uPerm); |
285 |
}
|
|
286 |
}
|
|
287 |
bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); |
|
288 |
||
289 |
if (uMode && pOpNick) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
290 |
MODULECALL(OnChanPermission(*pOpNick, *pNick, *this, uMode, bAdd, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
291 |
|
292 |
if (uMode == CChan::M_Op) { |
|
293 |
if (bAdd) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
294 |
MODULECALL(OnOp(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
295 |
} else { |
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
296 |
MODULECALL(OnDeop(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
297 |
}
|
298 |
} else if (uMode == CChan::M_Voice) { |
|
299 |
if (bAdd) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
300 |
MODULECALL(OnVoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
301 |
} else { |
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
302 |
MODULECALL(OnDevoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
303 |
}
|
304 |
}
|
|
305 |
}
|
|
306 |
}
|
|
307 |
}
|
|
308 |
} else { |
|
309 |
bool bList = false; |
|
310 |
CString sArg; |
|
311 |
||
312 |
switch (m_pUser->GetIRCSock()->GetModeType(uMode)) { |
|
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
313 |
case CIRCSock::ListArg: |
314 |
bList = true; |
|
315 |
sArg = GetModeArg(sArgs); |
|
316 |
break; |
|
317 |
case CIRCSock::HasArg: |
|
318 |
sArg = GetModeArg(sArgs); |
|
319 |
break; |
|
320 |
case CIRCSock::NoArg: |
|
321 |
break; |
|
322 |
case CIRCSock::ArgWhenSet: |
|
323 |
if (bAdd) { |
|
324 |
sArg = GetModeArg(sArgs); |
|
325 |
}
|
|
1
by Joey Hess
Import upstream version 0.045 |
326 |
|
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
327 |
break; |
1
by Joey Hess
Import upstream version 0.045 |
328 |
}
|
329 |
||
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
330 |
bool bNoChange; |
331 |
if (bList) { |
|
332 |
bNoChange = false; |
|
333 |
} else if (bAdd) { |
|
334 |
bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; |
|
335 |
} else { |
|
336 |
bNoChange = !HasMode(uMode); |
|
1
by Joey Hess
Import upstream version 0.045 |
337 |
}
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
338 |
MODULECALL(OnMode(*pOpNick, *this, uMode, sArg, bAdd, bNoChange), m_pUser, NULL, NOTHING); |
1
by Joey Hess
Import upstream version 0.045 |
339 |
|
340 |
if (!bList) { |
|
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
341 |
(bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); |
1
by Joey Hess
Import upstream version 0.045 |
342 |
}
|
343 |
}
|
|
344 |
}
|
|
345 |
}
|
|
346 |
||
347 |
CString CChan::GetOptions() const { |
|
348 |
CString sRet; |
|
349 |
||
350 |
if (IsDetached()) { |
|
351 |
sRet += (sRet.empty()) ? "Detached" : ", Detached"; |
|
352 |
}
|
|
353 |
||
354 |
if (KeepBuffer()) { |
|
355 |
sRet += (sRet.empty()) ? "KeepBuffer" : ", KeepBuffer"; |
|
356 |
}
|
|
357 |
||
358 |
return sRet; |
|
359 |
}
|
|
360 |
||
361 |
CString CChan::GetModeArg(unsigned char uMode) const { |
|
362 |
if (uMode) { |
|
363 |
map<unsigned char, CString>::const_iterator it = m_musModes.find(uMode); |
|
364 |
||
365 |
if (it != m_musModes.end()) { |
|
366 |
return it->second; |
|
367 |
}
|
|
368 |
}
|
|
369 |
||
370 |
return ""; |
|
371 |
}
|
|
372 |
||
373 |
bool CChan::HasMode(unsigned char uMode) const { |
|
374 |
return (uMode && m_musModes.find(uMode) != m_musModes.end()); |
|
375 |
}
|
|
376 |
||
377 |
bool CChan::AddMode(unsigned char uMode, const CString& sArg) { |
|
378 |
m_musModes[uMode] = sArg; |
|
379 |
return true; |
|
380 |
}
|
|
381 |
||
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
382 |
bool CChan::RemMode(unsigned char uMode) { |
1
by Joey Hess
Import upstream version 0.045 |
383 |
if (!HasMode(uMode)) { |
384 |
return false; |
|
385 |
}
|
|
386 |
||
387 |
m_musModes.erase(uMode); |
|
388 |
return true; |
|
389 |
}
|
|
390 |
||
391 |
CString CChan::GetModeArg(CString& sArgs) const { |
|
392 |
CString sRet = sArgs.substr(0, sArgs.find(' ')); |
|
393 |
sArgs = (sRet.size() < sArgs.size()) ? sArgs.substr(sRet.size() +1) : ""; |
|
394 |
return sRet; |
|
395 |
}
|
|
396 |
||
397 |
void CChan::ClearNicks() { |
|
398 |
m_msNicks.clear(); |
|
399 |
}
|
|
400 |
||
401 |
int CChan::AddNicks(const CString& sNicks) { |
|
402 |
int iRet = 0; |
|
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
403 |
VCString vsNicks; |
404 |
VCString::iterator it; |
|
405 |
||
406 |
sNicks.Split(" ", vsNicks, false); |
|
407 |
||
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
408 |
for (it = vsNicks.begin(); it != vsNicks.end(); ++it) { |
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
409 |
if (AddNick(*it)) { |
1
by Joey Hess
Import upstream version 0.045 |
410 |
iRet++; |
411 |
}
|
|
412 |
}
|
|
413 |
||
414 |
return iRet; |
|
415 |
}
|
|
416 |
||
417 |
bool CChan::AddNick(const CString& sNick) { |
|
418 |
const char* p = sNick.c_str(); |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
419 |
CString sPrefix, sTmp, sIdent, sHost; |
1
by Joey Hess
Import upstream version 0.045 |
420 |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
421 |
while (m_pUser->GetIRCSock()->IsPermChar(*p)) { |
422 |
sPrefix += *p; |
|
1
by Joey Hess
Import upstream version 0.045 |
423 |
|
424 |
if (!*++p) { |
|
425 |
return false; |
|
426 |
}
|
|
427 |
}
|
|
428 |
||
1.1.1
by Joey Hess
Import upstream version 0.047 |
429 |
sTmp = p; |
1.2.4
by Patrick Matthäi
Import upstream version 0.074 |
430 |
|
431 |
// The UHNames extension gets us nick!ident@host instead of just plain nick
|
|
432 |
sIdent = sTmp.Token(1, true, "!"); |
|
433 |
sHost = sIdent.Token(1, true, "@"); |
|
434 |
sIdent = sIdent.Token(0, false, "@"); |
|
435 |
// Get the nick
|
|
436 |
sTmp = sTmp.Token(0, false, "!"); |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
437 |
|
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
438 |
CNick tmpNick(sTmp); |
1.1.1
by Joey Hess
Import upstream version 0.047 |
439 |
CNick* pNick = FindNick(sTmp); |
1
by Joey Hess
Import upstream version 0.045 |
440 |
if (!pNick) { |
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
441 |
pNick = &tmpNick; |
1
by Joey Hess
Import upstream version 0.045 |
442 |
pNick->SetUser(m_pUser); |
443 |
}
|
|
444 |
||
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
445 |
if (!sIdent.empty()) |
1.1.1
by Joey Hess
Import upstream version 0.047 |
446 |
pNick->SetIdent(sIdent); |
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
447 |
if (!sHost.empty()) |
1.1.1
by Joey Hess
Import upstream version 0.047 |
448 |
pNick->SetHost(sHost); |
449 |
||
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
450 |
for (CString::size_type i = 0; i < sPrefix.length(); i++) { |
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
451 |
pNick->AddPerm(sPrefix[i]); |
1
by Joey Hess
Import upstream version 0.045 |
452 |
}
|
453 |
||
1.1.9
by Patrick Matthäi
Import upstream version 0.062 |
454 |
if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { |
1.1.5
by Patrick Matthäi
Import upstream version 0.056 |
455 |
for (CString::size_type i = 0; i < sPrefix.length(); i++) { |
1.1.1
by Joey Hess
Import upstream version 0.047 |
456 |
AddPerm(sPrefix[i]); |
457 |
}
|
|
1
by Joey Hess
Import upstream version 0.045 |
458 |
}
|
459 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
460 |
m_msNicks[pNick->GetNick()] = *pNick; |
1
by Joey Hess
Import upstream version 0.045 |
461 |
|
462 |
return true; |
|
463 |
}
|
|
464 |
||
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
465 |
map<char, unsigned int> CChan::GetPermCounts() const { |
466 |
map<char, unsigned int> mRet; |
|
467 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
468 |
map<CString,CNick>::const_iterator it; |
1.3.5
by Patrick Matthäi
Import upstream version 0.090~rc1 |
469 |
for (it = m_msNicks.begin(); it != m_msNicks.end(); ++it) { |
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
470 |
CString sPerms = it->second.GetPermStr(); |
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
471 |
|
472 |
for (unsigned int p = 0; p < sPerms.size(); p++) { |
|
473 |
mRet[sPerms[p]]++; |
|
1
by Joey Hess
Import upstream version 0.045 |
474 |
}
|
475 |
}
|
|
1.1.10
by Patrick Matthäi
Import upstream version 0.064 |
476 |
|
477 |
return mRet; |
|
1
by Joey Hess
Import upstream version 0.045 |
478 |
}
|
479 |
||
480 |
bool CChan::RemNick(const CString& sNick) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
481 |
map<CString,CNick>::iterator it; |
1.1.4
by Joey Hess
Import upstream version 0.054 |
482 |
set<unsigned char>::iterator it2; |
483 |
||
484 |
it = m_msNicks.find(sNick); |
|
1
by Joey Hess
Import upstream version 0.045 |
485 |
if (it == m_msNicks.end()) { |
486 |
return false; |
|
487 |
}
|
|
488 |
||
489 |
m_msNicks.erase(it); |
|
490 |
||
491 |
return true; |
|
492 |
}
|
|
493 |
||
494 |
bool CChan::ChangeNick(const CString& sOldNick, const CString& sNewNick) { |
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
495 |
map<CString,CNick>::iterator it = m_msNicks.find(sOldNick); |
1
by Joey Hess
Import upstream version 0.045 |
496 |
|
497 |
if (it == m_msNicks.end()) { |
|
498 |
return false; |
|
499 |
}
|
|
500 |
||
501 |
// Rename this nick
|
|
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
502 |
it->second.SetNick(sNewNick); |
1
by Joey Hess
Import upstream version 0.045 |
503 |
|
504 |
// Insert a new element into the map then erase the old one, do this to change the key to the new nick
|
|
505 |
m_msNicks[sNewNick] = it->second; |
|
506 |
m_msNicks.erase(it); |
|
507 |
||
508 |
return true; |
|
509 |
}
|
|
510 |
||
1.3.10
by Patrick Matthäi
Import upstream version 0.098 |
511 |
const CNick* CChan::FindNick(const CString& sNick) const { |
512 |
map<CString,CNick>::const_iterator it = m_msNicks.find(sNick); |
|
513 |
return (it != m_msNicks.end()) ? &it->second : NULL; |
|
514 |
}
|
|
515 |
||
516 |
CNick* CChan::FindNick(const CString& sNick) { |
|
517 |
map<CString,CNick>::iterator it = m_msNicks.find(sNick); |
|
518 |
return (it != m_msNicks.end()) ? &it->second : NULL; |
|
1
by Joey Hess
Import upstream version 0.045 |
519 |
}
|
520 |
||
521 |
int CChan::AddBuffer(const CString& sLine) { |
|
522 |
// Todo: revisit the buffering
|
|
523 |
if (!m_uBufferCount) { |
|
524 |
return 0; |
|
525 |
}
|
|
526 |
||
527 |
if (m_vsBuffer.size() >= m_uBufferCount) { |
|
528 |
m_vsBuffer.erase(m_vsBuffer.begin()); |
|
529 |
}
|
|
530 |
||
531 |
m_vsBuffer.push_back(sLine); |
|
532 |
return m_vsBuffer.size(); |
|
533 |
}
|
|
534 |
||
535 |
void CChan::ClearBuffer() { |
|
536 |
m_vsBuffer.clear(); |
|
537 |
}
|
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
538 |
|
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
539 |
void CChan::TrimBuffer(const unsigned int uMax) { |
540 |
if (m_vsBuffer.size() > uMax) { |
|
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
541 |
m_vsBuffer.erase(m_vsBuffer.begin(), m_vsBuffer.begin() + (m_vsBuffer.size() - uMax)); |
1.3.11
by Patrick Matthäi
Import upstream version 0.200 |
542 |
}
|
543 |
}
|
|
544 |
||
1.1.1
by Joey Hess
Import upstream version 0.047 |
545 |
void CChan::SendBuffer(CClient* pClient) { |
546 |
if (m_pUser && m_pUser->IsUserAttached()) { |
|
547 |
const vector<CString>& vsBuffer = GetBuffer(); |
|
548 |
||
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
549 |
// in the event that pClient is NULL, need to send this to all clients for the user
|
550 |
// I'm presuming here that pClient is listed inside vClients thus vClients at this
|
|
551 |
// point can't be empty.
|
|
552 |
//
|
|
553 |
// This loop has to be cycled twice to maintain the existing behavior which is
|
|
554 |
// 1. OnChanBufferStarting
|
|
555 |
// 2. OnChanBufferPlayLine
|
|
556 |
// 3. ClearBuffer() if not keeping the buffer
|
|
557 |
// 4. OnChanBufferEnding
|
|
558 |
//
|
|
559 |
// With the exception of ClearBuffer(), this needs to happen per client, and
|
|
560 |
// if pClient is not NULL, the loops break after the first iteration.
|
|
561 |
//
|
|
562 |
// Rework this if you like ...
|
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
563 |
if (vsBuffer.size()) { |
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
564 |
const vector<CClient*> & vClients = m_pUser->GetClients(); |
565 |
for( size_t uClient = 0; uClient < vClients.size(); ++uClient ) { |
|
566 |
||
567 |
CClient * pUseClient = ( pClient ? pClient : vClients[uClient] ); |
|
568 |
bool bSkipStatusMsg = false; |
|
569 |
MODULECALL(OnChanBufferStarting(*this, *pUseClient), m_pUser, NULL, bSkipStatusMsg = true); |
|
570 |
||
571 |
if (!bSkipStatusMsg) { |
|
572 |
m_pUser->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + " :Buffer Playback...", pUseClient); |
|
573 |
}
|
|
574 |
||
575 |
for (unsigned int a = 0; a < vsBuffer.size(); a++) { |
|
576 |
CString sLine(vsBuffer[a]); |
|
577 |
MODULECALL(OnChanBufferPlayLine(*this, *pUseClient, sLine), m_pUser, NULL, continue); |
|
578 |
m_pUser->PutUser(sLine, pUseClient); |
|
579 |
}
|
|
580 |
||
581 |
if( pClient ) |
|
582 |
break; |
|
583 |
||
1.1.1
by Joey Hess
Import upstream version 0.047 |
584 |
}
|
585 |
||
586 |
if (!KeepBuffer()) { |
|
587 |
ClearBuffer(); |
|
588 |
}
|
|
589 |
||
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
590 |
for( size_t uClient = 0; uClient < vClients.size(); ++uClient ) { |
591 |
||
592 |
CClient * pUseClient = ( pClient ? pClient : vClients[uClient] ); |
|
593 |
bool bSkipStatusMsg = false; |
|
594 |
MODULECALL(OnChanBufferEnding(*this, *pUseClient), m_pUser, NULL, bSkipStatusMsg = true); |
|
595 |
||
596 |
if (!bSkipStatusMsg) { |
|
597 |
m_pUser->PutUser(":***!znc@znc.in PRIVMSG " + GetName() + " :Playback Complete.", pUseClient); |
|
598 |
}
|
|
599 |
||
600 |
if( pClient ) |
|
601 |
break; |
|
1.2.3
by Patrick Matthäi
Import upstream version 0.070 |
602 |
}
|
1.3.12
by Patrick Matthäi
Import upstream version 0.202 |
603 |
|
1.1.1
by Joey Hess
Import upstream version 0.047 |
604 |
}
|
605 |
}
|
|
606 |
}
|