00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "services.h"
00014 #include "modules.h"
00015 #include "regchannel.h"
00016 #include "account.h"
00017 #include "access.h"
00018 #include "channels.h"
00019 #include "config.h"
00020 #include "bots.h"
00021 #include "language.h"
00022 #include "servers.h"
00023
00024 Serialize::Checker<registered_channel_map> RegisteredChannelList("ChannelInfo");
00025
00026 BadWord::BadWord() : Serializable("BadWord")
00027 {
00028 }
00029
00030 BadWord::~BadWord()
00031 {
00032 if (this->ci)
00033 {
00034 std::vector<BadWord *>::iterator it = std::find(this->ci->badwords->begin(), this->ci->badwords->end(), this);
00035 if (it != this->ci->badwords->end())
00036 this->ci->badwords->erase(it);
00037 }
00038 }
00039
00040 void BadWord::Serialize(Serialize::Data &data) const
00041 {
00042 data["ci"] << this->ci->name;
00043 data["word"] << this->word;
00044 data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type;
00045 }
00046
00047 Serializable* BadWord::Unserialize(Serializable *obj, Serialize::Data &data)
00048 {
00049 Anope::string sci, sword;
00050
00051 data["ci"] >> sci;
00052 data["word"] >> sword;
00053
00054 ChannelInfo *ci = ChannelInfo::Find(sci);
00055 if (!ci)
00056 return NULL;
00057
00058 unsigned int n;
00059 data["type"] >> n;
00060
00061 BadWord *bw;
00062 if (obj)
00063 {
00064 bw = anope_dynamic_static_cast<BadWord *>(obj);
00065 data["word"] >> bw->word;
00066 bw->type = static_cast<BadWordType>(n);
00067 }
00068 else
00069 bw = ci->AddBadWord(sword, static_cast<BadWordType>(n));
00070
00071 return bw;
00072 }
00073
00074 AutoKick::AutoKick() : Serializable("AutoKick")
00075 {
00076 }
00077
00078 AutoKick::~AutoKick()
00079 {
00080 if (this->ci)
00081 {
00082 std::vector<AutoKick *>::iterator it = std::find(this->ci->akick->begin(), this->ci->akick->end(), this);
00083 if (it != this->ci->akick->end())
00084 this->ci->akick->erase(it);
00085
00086 const NickAlias *na = NickAlias::Find(this->mask);
00087 if (na != NULL)
00088 na->nc->RemoveChannelReference(this->ci);
00089 }
00090 }
00091
00092 void AutoKick::Serialize(Serialize::Data &data) const
00093 {
00094 data["ci"] << this->ci->name;
00095 if (this->nc)
00096 data["nc"] << this->nc->display;
00097 else
00098 data["mask"] << this->mask;
00099 data["reason"] << this->reason;
00100 data["creator"] << this->creator;
00101 data.SetType("addtime", Serialize::Data::DT_INT); data["addtime"] << this->addtime;
00102 data.SetType("last_used", Serialize::Data::DT_INT); data["last_used"] << this->last_used;
00103 }
00104
00105 Serializable* AutoKick::Unserialize(Serializable *obj, Serialize::Data &data)
00106 {
00107 Anope::string sci, snc;
00108
00109 data["ci"] >> sci;
00110 data["nc"] >> snc;
00111
00112 ChannelInfo *ci = ChannelInfo::Find(sci);
00113 if (!ci)
00114 return NULL;
00115
00116 AutoKick *ak;
00117 NickCore *nc = NickCore::Find(snc);
00118 if (obj)
00119 {
00120 ak = anope_dynamic_static_cast<AutoKick *>(obj);
00121 data["creator"] >> ak->creator;
00122 data["reason"] >> ak->reason;
00123 ak->nc = NickCore::Find(snc);
00124 data["mask"] >> ak->mask;
00125 data["addtime"] >> ak->addtime;
00126 data["last_used"] >> ak->last_used;
00127 }
00128 else
00129 {
00130 time_t addtime, lastused;
00131 data["addtime"] >> addtime;
00132 data["last_used"] >> lastused;
00133
00134 Anope::string screator, sreason, smask;
00135
00136 data["creator"] >> screator;
00137 data["reason"] >> sreason;
00138 data["mask"] >> smask;
00139
00140 if (nc)
00141 ak = ci->AddAkick(screator, nc, sreason, addtime, lastused);
00142 else
00143 ak = ci->AddAkick(screator, smask, sreason, addtime, lastused);
00144 }
00145
00146 return ak;
00147 }
00148
00149 ModeLock::ModeLock(ChannelInfo *ch, bool s, const Anope::string &n, const Anope::string &p, const Anope::string &se, time_t c) : Serializable("ModeLock"), ci(ch), set(s), name(n), param(p), setter(se), created(c)
00150 {
00151 }
00152
00153 ModeLock::~ModeLock()
00154 {
00155 if (this->ci)
00156 this->ci->RemoveMLock(this);
00157 }
00158
00159 void ModeLock::Serialize(Serialize::Data &data) const
00160 {
00161 if (!this->ci)
00162 return;
00163
00164 data["ci"] << this->ci->name;
00165 data["set"] << this->set;
00166 data["name"] << this->name;
00167 data["param"] << this->param;
00168 data["setter"] << this->setter;
00169 data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
00170 }
00171
00172 Serializable* ModeLock::Unserialize(Serializable *obj, Serialize::Data &data)
00173 {
00174 Anope::string sci;
00175
00176 data["ci"] >> sci;
00177
00178 ChannelInfo *ci = ChannelInfo::Find(sci);
00179 if (!ci)
00180 return NULL;
00181
00182 ModeLock *ml;
00183 if (obj)
00184 {
00185 ml = anope_dynamic_static_cast<ModeLock *>(obj);
00186
00187 data["set"] >> ml->set;
00188 data["name"] >> ml->name;
00189 data["param"] >> ml->param;
00190 data["setter"] >> ml->setter;
00191 data["created"] >> ml->created;
00192 return ml;
00193 }
00194 else
00195 {
00196 bool set;
00197 data["set"] >> set;
00198
00199 time_t created;
00200 data["created"] >> created;
00201
00202 Anope::string setter;
00203 data["setter"] >> setter;
00204
00205 Anope::string sname;
00206 data["name"] >> sname;
00207
00208 ml = new ModeLock(ci, set, sname, "", setter, created);
00209 data["param"] >> ml->param;
00210
00211 ci->mode_locks->insert(std::make_pair(ml->name, ml));
00212 return ml;
00213 }
00214 }
00215
00216 void LogSetting::Serialize(Serialize::Data &data) const
00217 {
00218 if (!ci)
00219 return;
00220
00221 data["ci"] << ci->name;
00222 data["service_name"] << service_name;
00223 data["command_service"] << command_service;
00224 data["command_name"] << command_name;
00225 data["method"] << method;
00226 data["extra"] << extra;
00227 data["creator"] << creator;
00228 data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
00229 }
00230
00231 Serializable* LogSetting::Unserialize(Serializable *obj, Serialize::Data &data)
00232 {
00233 Anope::string sci;
00234
00235 data["ci"] >> sci;
00236
00237 ChannelInfo *ci = ChannelInfo::Find(sci);
00238 if (ci == NULL)
00239 return NULL;
00240
00241 LogSetting *ls;
00242 if (obj)
00243 ls = anope_dynamic_static_cast<LogSetting *>(obj);
00244 else
00245 {
00246 ls = new LogSetting();
00247 ci->log_settings->push_back(ls);
00248 }
00249
00250 ls->ci = ci;
00251 data["service_name"] >> ls->service_name;
00252 data["command_service"] >> ls->command_service;
00253 data["command_name"] >> ls->command_name;
00254 data["method"] >> ls->method;
00255 data["extra"] >> ls->extra;
00256 data["creator"] >> ls->creator;
00257 data["created"] >> ls->created;
00258
00259 return ls;
00260 }
00261
00262 ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInfo"),
00263 access("ChanAccess"), akick("AutoKick"),
00264 badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting")
00265 {
00266 if (chname.empty())
00267 throw CoreException("Empty channel passed to ChannelInfo constructor");
00268
00269 this->founder = NULL;
00270 this->successor = NULL;
00271 this->c = Channel::Find(chname);
00272 if (this->c)
00273 this->c->ci = this;
00274 this->capsmin = this->capspercent = 0;
00275 this->floodlines = this->floodsecs = 0;
00276 this->repeattimes = 0;
00277 this->bi = NULL;
00278
00279 this->last_topic_setter = Config->ChanServ;
00280 this->last_topic_time = Anope::CurTime;
00281
00282 this->name = chname;
00283
00284
00285 for (std::set<Anope::string>::const_iterator it = Config->CSDefFlags.begin(), it_end = Config->CSDefFlags.end(); it != it_end; ++it)
00286 this->ExtendMetadata(*it);
00287
00288
00289 for (std::set<Anope::string>::const_iterator it = Config->BSDefFlags.begin(), it_end = Config->BSDefFlags.end(); it != it_end; ++it)
00290 this->ExtendMetadata(*it);
00291
00292 this->bantype = Config->CSDefBantype;
00293 this->memos.memomax = Config->MSMaxMemos;
00294 this->last_used = this->time_registered = Anope::CurTime;
00295
00296 for (int i = 0; i < TTB_SIZE; ++i)
00297 this->ttb[i] = 0;
00298
00299 size_t old = RegisteredChannelList->size();
00300 (*RegisteredChannelList)[this->name] = this;
00301 if (old == RegisteredChannelList->size())
00302 Log(LOG_DEBUG) << "Duplicate channel " << this->name << " in registered channel table?";
00303
00304 FOREACH_MOD(I_OnCreateChan, OnCreateChan(this));
00305 }
00306
00307 ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
00308 access("ChanAccess"), akick("AutoKick"),
00309 badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting")
00310 {
00311 *this = ci;
00312
00313 if (this->founder)
00314 --this->founder->channelcount;
00315
00316 this->access->clear();
00317 this->akick->clear();
00318 this->badwords->clear();
00319
00320 for (int i = 0; i < TTB_SIZE; ++i)
00321 this->ttb[i] = ci.ttb[i];
00322
00323 for (unsigned i = 0; i < ci.GetAccessCount(); ++i)
00324 {
00325 const ChanAccess *taccess = ci.GetAccess(i);
00326 AccessProvider *provider = taccess->provider;
00327
00328 ChanAccess *newaccess = provider->Create();
00329 newaccess->ci = this;
00330 newaccess->mask = taccess->mask;
00331 newaccess->creator = taccess->creator;
00332 newaccess->last_seen = taccess->last_seen;
00333 newaccess->created = taccess->created;
00334 newaccess->AccessUnserialize(taccess->AccessSerialize());
00335
00336 this->AddAccess(newaccess);
00337 }
00338
00339 for (unsigned i = 0; i < ci.GetAkickCount(); ++i)
00340 {
00341 const AutoKick *takick = ci.GetAkick(i);
00342 if (takick->nc)
00343 this->AddAkick(takick->creator, takick->nc, takick->reason, takick->addtime, takick->last_used);
00344 else
00345 this->AddAkick(takick->creator, takick->mask, takick->reason, takick->addtime, takick->last_used);
00346 }
00347 for (unsigned i = 0; i < ci.GetBadWordCount(); ++i)
00348 {
00349 const BadWord *bw = ci.GetBadWord(i);
00350 this->AddBadWord(bw->word, bw->type);
00351 }
00352
00353 for (unsigned i = 0; i < ci.log_settings->size(); ++i)
00354 {
00355 LogSetting *l = new LogSetting(*ci.log_settings->at(i));
00356 l->ci = this;
00357 this->log_settings->push_back(l);
00358 }
00359 }
00360
00361 ChannelInfo::~ChannelInfo()
00362 {
00363 FOREACH_MOD(I_OnDelChan, OnDelChan(this));
00364
00365 Log(LOG_DEBUG) << "Deleting channel " << this->name;
00366
00367 if (this->c)
00368 {
00369 if (this->bi && this->c->FindUser(this->bi))
00370 this->bi->Part(this->c);
00371 this->c->ci = NULL;
00372 }
00373
00374 RegisteredChannelList->erase(this->name);
00375
00376 this->SetFounder(NULL);
00377 this->SetSuccessor(NULL);
00378
00379 this->ClearAccess();
00380 this->ClearAkick();
00381 this->ClearBadWords();
00382
00383 for (unsigned i = 0; i < this->log_settings->size(); ++i)
00384 delete this->log_settings->at(i);
00385 this->log_settings->clear();
00386
00387 while (!this->mode_locks->empty())
00388 delete this->mode_locks->begin()->second;
00389
00390 if (!this->memos.memos->empty())
00391 {
00392 for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i)
00393 delete this->memos.GetMemo(i);
00394 this->memos.memos->clear();
00395 }
00396
00397 if (this->founder)
00398 --this->founder->channelcount;
00399 }
00400
00401 void ChannelInfo::Serialize(Serialize::Data &data) const
00402 {
00403 data["name"] << this->name;
00404 if (this->founder)
00405 data["founder"] << this->founder->display;
00406 if (this->successor)
00407 data["successor"] << this->successor->display;
00408 data["description"] << this->desc;
00409 data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
00410 data.SetType("last_used", Serialize::Data::DT_INT); data["last_used"] << this->last_used;
00411 data["last_topic"] << this->last_topic;
00412 data["last_topic_setter"] << this->last_topic_setter;
00413 data.SetType("last_topic_time", Serialize::Data::DT_INT); data["last_topic_time"] << this->last_topic_time;
00414 data.SetType("bantype", Serialize::Data::DT_INT); data["bantype"] << this->bantype;
00415 this->ExtensibleSerialize(data);
00416 {
00417 Anope::string levels_buffer;
00418 for (std::map<Anope::string, int16_t>::const_iterator it = this->levels.begin(), it_end = this->levels.end(); it != it_end; ++it)
00419 levels_buffer += it->first + " " + stringify(it->second) + " ";
00420 data["levels"] << levels_buffer;
00421 }
00422 if (this->bi)
00423 data["bi"] << this->bi->nick;
00424 for (int i = 0; i < TTB_SIZE; ++i)
00425 data["ttb"] << this->ttb[i] << " ";
00426 data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << this->capsmin;
00427 data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << this->capspercent;
00428 data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << this->floodlines;
00429 data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << this->floodsecs;
00430 data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << this->repeattimes;
00431 data["memomax"] << this->memos.memomax;
00432 for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
00433 data["memoignores"] << this->memos.ignores[i] << " ";
00434 }
00435
00436 Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
00437 {
00438 Anope::string sname, sfounder, ssuccessor, slevels, sbi;
00439
00440 data["name"] >> sname;
00441 data["founder"] >> sfounder;
00442 data["successor"] >> ssuccessor;
00443 data["levels"] >> slevels;
00444 data["bi"] >> sbi;
00445
00446 ChannelInfo *ci;
00447 if (obj)
00448 ci = anope_dynamic_static_cast<ChannelInfo *>(obj);
00449 else
00450 ci = new ChannelInfo(sname);
00451
00452 ci->ExtensibleUnserialize(data);
00453
00454 ci->SetFounder(NickCore::Find(sfounder));
00455 ci->SetSuccessor(NickCore::Find(ssuccessor));
00456
00457 data["description"] >> ci->desc;
00458 data["time_registered"] >> ci->time_registered;
00459 data["last_used"] >> ci->last_used;
00460 data["last_topic"] >> ci->last_topic;
00461 data["last_topic_setter"] >> ci->last_topic_setter;
00462 data["last_topic_time"] >> ci->last_topic_time;
00463 data["bantype"] >> ci->bantype;
00464 {
00465 std::vector<Anope::string> v;
00466 spacesepstream(slevels).GetTokens(v);
00467 for (unsigned i = 0; i + 1 < v.size(); i += 2)
00468 ci->levels[v[i]] = convertTo<int16_t>(v[i + 1]);
00469 }
00470 BotInfo *bi = BotInfo::Find(sbi);
00471 if (*ci->bi != bi)
00472 {
00473 if (ci->bi)
00474 ci->bi->UnAssign(NULL, ci);
00475 ci->bi = bi;
00476 if (ci->bi)
00477 ci->bi->Assign(NULL, ci);
00478 }
00479 data["capsmin"] >> ci->capsmin;
00480 data["capspercent"] >> ci->capspercent;
00481 data["floodlines"] >> ci->floodlines;
00482 data["floodsecs"] >> ci->floodsecs;
00483 data["repeattimes"] >> ci->repeattimes;
00484 data["memomax"] >> ci->memos.memomax;
00485 {
00486 Anope::string buf;
00487 data["memoignores"] >> buf;
00488 spacesepstream sep(buf);
00489 ci->memos.ignores.clear();
00490 while (sep.GetToken(buf))
00491 ci->memos.ignores.push_back(buf);
00492 }
00493
00494
00495 Anope::string sflags, sbotflags;
00496 data["flags"] >> sflags;
00497 data["botflags"] >> sbotflags;
00498 spacesepstream sep(sflags);
00499 Anope::string tok;
00500 while (sep.GetToken(tok))
00501 ci->ExtendMetadata(tok);
00502 spacesepstream sep2(sbotflags);
00503 while (sep2.GetToken(tok))
00504 ci->ExtendMetadata("BS_" + tok);
00505
00506
00507 return ci;
00508 }
00509
00510
00511 void ChannelInfo::SetFounder(NickCore *nc)
00512 {
00513 if (this->founder)
00514 {
00515 --this->founder->channelcount;
00516 this->founder->RemoveChannelReference(this);
00517 }
00518
00519 this->founder = nc;
00520
00521 if (this->founder)
00522 {
00523 ++this->founder->channelcount;
00524 this->founder->AddChannelReference(this);
00525 }
00526 }
00527
00528 NickCore *ChannelInfo::GetFounder() const
00529 {
00530 return this->founder;
00531 }
00532
00533 void ChannelInfo::SetSuccessor(NickCore *nc)
00534 {
00535 if (this->successor)
00536 this->successor->RemoveChannelReference(this);
00537 this->successor = nc;
00538 if (this->successor)
00539 this->successor->AddChannelReference(this);
00540 }
00541
00542 NickCore *ChannelInfo::GetSuccessor() const
00543 {
00544 return this->successor;
00545 }
00546
00547 BotInfo *ChannelInfo::WhoSends() const
00548 {
00549 if (this && this->bi)
00550 return this->bi;
00551 else if (ChanServ)
00552 return ChanServ;
00553 else if (!BotListByNick->empty())
00554 return BotListByNick->begin()->second;
00555 return NULL;
00556 }
00557
00558 void ChannelInfo::AddAccess(ChanAccess *taccess)
00559 {
00560 this->access->push_back(taccess);
00561
00562 const NickAlias *na = NickAlias::Find(taccess->mask);
00563 if (na != NULL)
00564 na->nc->AddChannelReference(this);
00565 }
00566
00567 ChanAccess *ChannelInfo::GetAccess(unsigned index) const
00568 {
00569 if (this->access->empty() || index >= this->access->size())
00570 return NULL;
00571
00572 ChanAccess *acc = (*this->access)[index];
00573 acc->QueueUpdate();
00574 return acc;
00575 }
00576
00577 AccessGroup ChannelInfo::AccessFor(const User *u)
00578 {
00579 AccessGroup group;
00580
00581 if (u == NULL)
00582 return group;
00583
00584 const NickCore *nc = u->Account();
00585 if (nc == NULL && u->IsRecognized())
00586 {
00587 const NickAlias *na = NickAlias::Find(u->nick);
00588 if (na != NULL)
00589 nc = na->nc;
00590 }
00591
00592 group.super_admin = u->super_admin;
00593 group.founder = IsFounder(u, this);
00594 group.ci = this;
00595 group.nc = nc;
00596
00597 for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
00598 if (this->GetAccess(i)->Matches(u, nc))
00599 group.push_back(this->GetAccess(i));
00600
00601 if (group.founder || !group.empty())
00602 {
00603 this->last_used = Anope::CurTime;
00604
00605 for (unsigned i = 0; i < group.size(); ++i)
00606 group[i]->last_seen = Anope::CurTime;
00607 }
00608
00609 return group;
00610 }
00611
00612 AccessGroup ChannelInfo::AccessFor(const NickCore *nc)
00613 {
00614 AccessGroup group;
00615
00616 group.founder = (this->founder && this->founder == nc);
00617 group.ci = this;
00618 group.nc = nc;
00619
00620 for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
00621 if (this->GetAccess(i)->Matches(NULL, nc))
00622 group.push_back(this->GetAccess(i));
00623
00624 if (group.founder || !group.empty())
00625 {
00626 this->last_used = Anope::CurTime;
00627
00628 for (unsigned i = 0; i < group.size(); ++i)
00629 group[i]->last_seen = Anope::CurTime;
00630 }
00631
00632 return group;
00633 }
00634
00635 unsigned ChannelInfo::GetAccessCount() const
00636 {
00637 return this->access->size();
00638 }
00639
00640 void ChannelInfo::EraseAccess(unsigned index)
00641 {
00642 if (this->access->empty() || index >= this->access->size())
00643 return;
00644
00645 delete this->access->at(index);
00646 }
00647
00648 void ChannelInfo::ClearAccess()
00649 {
00650 for (unsigned i = this->access->size(); i > 0; --i)
00651 delete this->GetAccess(i - 1);
00652 }
00653
00654 AutoKick *ChannelInfo::AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t, time_t lu)
00655 {
00656 AutoKick *autokick = new AutoKick();
00657 autokick->ci = this;
00658 autokick->nc = akicknc;
00659 autokick->reason = reason;
00660 autokick->creator = user;
00661 autokick->addtime = t;
00662 autokick->last_used = lu;
00663
00664 this->akick->push_back(autokick);
00665
00666 akicknc->AddChannelReference(this);
00667
00668 return autokick;
00669 }
00670
00671 AutoKick *ChannelInfo::AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t, time_t lu)
00672 {
00673 AutoKick *autokick = new AutoKick();
00674 autokick->ci = this;
00675 autokick->mask = mask;
00676 autokick->nc = NULL;
00677 autokick->reason = reason;
00678 autokick->creator = user;
00679 autokick->addtime = t;
00680 autokick->last_used = lu;
00681
00682 this->akick->push_back(autokick);
00683
00684 return autokick;
00685 }
00686
00687 AutoKick *ChannelInfo::GetAkick(unsigned index) const
00688 {
00689 if (this->akick->empty() || index >= this->akick->size())
00690 return NULL;
00691
00692 AutoKick *ak = (*this->akick)[index];
00693 ak->QueueUpdate();
00694 return ak;
00695 }
00696
00697 unsigned ChannelInfo::GetAkickCount() const
00698 {
00699 return this->akick->size();
00700 }
00701
00702 void ChannelInfo::EraseAkick(unsigned index)
00703 {
00704 if (this->akick->empty() || index >= this->akick->size())
00705 return;
00706
00707 delete this->GetAkick(index);
00708 }
00709
00710 void ChannelInfo::ClearAkick()
00711 {
00712 while (!this->akick->empty())
00713 delete this->akick->back();
00714 }
00715
00716 BadWord* ChannelInfo::AddBadWord(const Anope::string &word, BadWordType type)
00717 {
00718 BadWord *bw = new BadWord();
00719 bw->ci = this;
00720 bw->word = word;
00721 bw->type = type;
00722
00723 this->badwords->push_back(bw);
00724
00725 FOREACH_MOD(I_OnBadWordAdd, OnBadWordAdd(this, bw));
00726
00727 return bw;
00728 }
00729
00730 BadWord* ChannelInfo::GetBadWord(unsigned index) const
00731 {
00732 if (this->badwords->empty() || index >= this->badwords->size())
00733 return NULL;
00734
00735 BadWord *bw = (*this->badwords)[index];
00736 bw->QueueUpdate();
00737 return bw;
00738 }
00739
00740 unsigned ChannelInfo::GetBadWordCount() const
00741 {
00742 return this->badwords->size();
00743 }
00744
00745 void ChannelInfo::EraseBadWord(unsigned index)
00746 {
00747 if (this->badwords->empty() || index >= this->badwords->size())
00748 return;
00749
00750 FOREACH_MOD(I_OnBadWordDel, OnBadWordDel(this, (*this->badwords)[index]));
00751
00752 delete this->badwords->at(index);
00753 }
00754
00755 void ChannelInfo::ClearBadWords()
00756 {
00757 while (!this->badwords->empty())
00758 delete this->badwords->back();
00759 }
00760
00761 bool ChannelInfo::HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const
00762 {
00763 std::multimap<Anope::string, ModeLock *>::const_iterator it = this->mode_locks->find(mode->name);
00764
00765 if (it != this->mode_locks->end())
00766 {
00767 if (mode->type != MODE_REGULAR)
00768 {
00769 std::multimap<Anope::string, ModeLock *>::const_iterator it_end = this->mode_locks->upper_bound(mode->name);
00770
00771 for (; it != it_end; ++it)
00772 {
00773 const ModeLock *ml = it->second;
00774 if (ml->param == param)
00775 return true;
00776 }
00777 }
00778 else
00779 return it->second->set == status;
00780 }
00781 return false;
00782 }
00783
00784 bool ChannelInfo::SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m, Anope::string setter, time_t created)
00785 {
00786 if (setter.empty())
00787 setter = this->founder ? this->founder->display : "Unknown";
00788 std::pair<Anope::string, ModeLock *> ml = std::make_pair(mode->name, new ModeLock(this, status, mode->name, param, setter, created));
00789
00790 EventReturn MOD_RESULT;
00791 FOREACH_RESULT(I_OnMLock, OnMLock(this, ml.second));
00792 if (MOD_RESULT == EVENT_STOP)
00793 return false;
00794
00795
00796 if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM)
00797 {
00798 for (ChannelInfo::ModeList::const_iterator it; (it = this->mode_locks->find(mode->name)) != this->mode_locks->end();)
00799 delete it->second;
00800 this->mode_locks->erase(mode->name);
00801 }
00802 else
00803 {
00804
00805 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name);
00806 if (it != this->mode_locks->end())
00807 {
00808 ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name);
00809 for (; it != it_end; ++it)
00810 {
00811 const ModeLock *modelock = it->second;
00812 if (modelock->param == param)
00813 {
00814 delete it->second;
00815 break;
00816 }
00817 }
00818 }
00819 }
00820
00821 this->mode_locks->insert(ml);
00822
00823 return true;
00824 }
00825
00826 bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m)
00827 {
00828 if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM)
00829 {
00830 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name), it_end = this->mode_locks->upper_bound(mode->name), it_next = it;
00831 if (it != this->mode_locks->end())
00832 for (; it != it_end; it = it_next)
00833 {
00834 const ModeLock *ml = it->second;
00835 ++it_next;
00836
00837 if (status != ml->set)
00838 continue;
00839
00840 EventReturn MOD_RESULT;
00841 FOREACH_RESULT(I_OnUnMLock, OnUnMLock(this, it->second));
00842 if (MOD_RESULT != EVENT_STOP)
00843 {
00844 delete it->second;
00845 return true;
00846 }
00847 }
00848 return false;
00849 }
00850 else
00851 {
00852
00853 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name);
00854 if (it != this->mode_locks->end())
00855 {
00856 ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name);
00857 for (; it != it_end; ++it)
00858 {
00859 const ModeLock *ml = it->second;
00860 if (ml->set == status && ml->param == param)
00861 {
00862 EventReturn MOD_RESULT;
00863 FOREACH_RESULT(I_OnUnMLock, OnUnMLock(this, it->second));
00864 if (MOD_RESULT == EVENT_STOP)
00865 return false;
00866 delete it->second;
00867 return true;
00868 }
00869 }
00870 }
00871
00872 return false;
00873 }
00874 }
00875
00876 void ChannelInfo::RemoveMLock(ModeLock *mlock)
00877 {
00878 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mlock->name);
00879 if (it != this->mode_locks->end())
00880 for (; it != this->mode_locks->upper_bound(mlock->name); ++it)
00881 if (it->second == mlock)
00882 {
00883 this->mode_locks->erase(it);
00884 break;
00885 }
00886 }
00887
00888 void ChannelInfo::ClearMLock()
00889 {
00890 while (!this->mode_locks->empty())
00891 delete this->mode_locks->begin()->second;
00892 this->mode_locks->clear();
00893 }
00894
00895 const ChannelInfo::ModeList &ChannelInfo::GetMLock() const
00896 {
00897 return this->mode_locks;
00898 }
00899
00900 std::pair<ChannelInfo::ModeList::iterator, ChannelInfo::ModeList::iterator> ChannelInfo::GetModeList(const Anope::string &mname)
00901 {
00902 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mname), it_end = it;
00903 if (it != this->mode_locks->end())
00904 it_end = this->mode_locks->upper_bound(mname);
00905 return std::make_pair(it, it_end);
00906 }
00907
00908 const ModeLock *ChannelInfo::GetMLock(const Anope::string &mname, const Anope::string ¶m)
00909 {
00910 ChannelInfo::ModeList::iterator it = this->mode_locks->find(mname);
00911 if (it != this->mode_locks->end())
00912 {
00913 if (param.empty())
00914 return it->second;
00915 else
00916 {
00917 ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mname);
00918 for (; it != it_end; ++it)
00919 {
00920 if (Anope::Match(param, it->second->param))
00921 return it->second;
00922 }
00923 }
00924 }
00925
00926 return NULL;
00927 }
00928
00929 Anope::string ChannelInfo::GetMLockAsString(bool complete) const
00930 {
00931 Anope::string pos = "+", neg = "-", params;
00932
00933 for (ChannelInfo::ModeList::const_iterator it = this->GetMLock().begin(), it_end = this->GetMLock().end(); it != it_end; ++it)
00934 {
00935 const ModeLock *ml = it->second;
00936 ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
00937 if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
00938 continue;
00939
00940 if (ml->set)
00941 pos += cm->mchar;
00942 else
00943 neg += cm->mchar;
00944
00945 if (complete && !ml->param.empty() && cm->type == MODE_PARAM)
00946 params += " " + ml->param;
00947 }
00948
00949 if (pos.length() == 1)
00950 pos.clear();
00951 if (neg.length() == 1)
00952 neg.clear();
00953
00954 return pos + neg + params;
00955 }
00956
00957 bool ChannelInfo::CheckKick(User *user)
00958 {
00959 if (!user || !this->c)
00960 return false;
00961
00962 if (user->super_admin)
00963 return false;
00964
00965
00966
00967 if (user->server->IsULined())
00968 return false;
00969
00970 if (user->IsProtected())
00971 return false;
00972
00973 Anope::string mask, reason;
00974
00975 EventReturn MOD_RESULT;
00976 FOREACH_RESULT(I_OnCheckKick, OnCheckKick(user, this, mask, reason));
00977 if (MOD_RESULT != EVENT_STOP)
00978 return false;
00979
00980 if (mask.empty())
00981 mask = this->GetIdealBan(user);
00982 if (reason.empty())
00983 reason = Language::Translate(user->Account(), CHAN_NOT_ALLOWED_TO_JOIN);
00984
00985 Log(LOG_DEBUG) << "Autokicking " << user->nick << " (" << mask << ") from " << this->name;
00986
00987
00988
00989
00990
00991
00992 if (this->c->users.size() == (this->bi && this->c->FindUser(this->bi) ? 2 : 1) && !this->c->HasExt("INHABIT") && !this->c->HasExt("SYNCING"))
00993 {
00994
00995 c->SetMode(NULL, "NOEXTERNAL");
00996 c->SetMode(NULL, "TOPIC");
00997 c->SetMode(NULL, "SECRET");
00998 c->SetMode(NULL, "INVITE");
00999
01000
01001 this->c->Hold();
01002 }
01003
01004 this->c->SetMode(NULL, "BAN", mask);
01005 this->c->Kick(NULL, user, "%s", reason.c_str());
01006
01007 return true;
01008 }
01009
01010 void ChannelInfo::CheckTopic()
01011 {
01012 if (!this->c)
01013 return;
01014
01015
01016
01017
01018
01019
01020 if (this->HasExt("TOPICLOCK") && this->last_topic != this->c->topic)
01021 {
01022 this->c->ChangeTopic(this->last_topic_setter, this->last_topic, this->last_topic_time);
01023 }
01024 else
01025 {
01026 this->last_topic = this->c->topic;
01027 this->last_topic_setter = this->c->topic_setter;
01028 this->last_topic_time = this->c->topic_ts;
01029 }
01030 }
01031
01032 void ChannelInfo::RestoreTopic()
01033 {
01034 if (!this->c)
01035 return;
01036
01037 if ((this->HasExt("KEEPTOPIC") || this->HasExt("TOPICLOCK")) && this->last_topic != this->c->topic)
01038 {
01039 this->c->ChangeTopic(!this->last_topic_setter.empty() ? this->last_topic_setter : this->WhoSends()->nick, this->last_topic, this->last_topic_time ? this->last_topic_time : Anope::CurTime);
01040 }
01041 }
01042
01043 int16_t ChannelInfo::GetLevel(const Anope::string &priv) const
01044 {
01045 if (PrivilegeManager::FindPrivilege(priv) == NULL)
01046 {
01047 Log(LOG_DEBUG) << "Unknown privilege " + priv;
01048 return ACCESS_INVALID;
01049 }
01050
01051 std::map<Anope::string, int16_t>::const_iterator it = this->levels.find(priv);
01052 if (it == this->levels.end())
01053 return 0;
01054 return it->second;
01055 }
01056
01057 void ChannelInfo::SetLevel(const Anope::string &priv, int16_t level)
01058 {
01059 this->levels[priv] = level;
01060 }
01061
01062 void ChannelInfo::RemoveLevel(const Anope::string &priv)
01063 {
01064 this->levels.erase(priv);
01065 }
01066
01067 void ChannelInfo::ClearLevels()
01068 {
01069 this->levels.clear();
01070 }
01071
01072 Anope::string ChannelInfo::GetIdealBan(User *u) const
01073 {
01074 switch (this->bantype)
01075 {
01076 case 0:
01077 return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
01078 case 1:
01079 if (u->GetVIdent()[0] == '~')
01080 return "*!*" + u->GetVIdent() + "@" + u->GetDisplayedHost();
01081 else
01082 return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost();
01083 case 3:
01084 return "*!" + u->Mask();
01085 case 2:
01086 default:
01087 return "*!*@" + u->GetDisplayedHost();
01088 }
01089 }
01090
01091 ChannelInfo* ChannelInfo::Find(const Anope::string &name)
01092 {
01093 registered_channel_map::const_iterator it = RegisteredChannelList->find(name);
01094 if (it != RegisteredChannelList->end())
01095 {
01096 it->second->QueueUpdate();
01097 return it->second;
01098 }
01099
01100 return NULL;
01101 }
01102
01103 bool IsFounder(const User *user, const ChannelInfo *ci)
01104 {
01105 if (!user || !ci)
01106 return false;
01107
01108 if (user->super_admin)
01109 return true;
01110
01111 if (user->Account() && user->Account() == ci->GetFounder())
01112 return true;
01113
01114 return false;
01115 }
01116