nickcore.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  */
00012 
00013 #include "services.h"
00014 #include "modules.h"
00015 #include "account.h"
00016 #include "config.h"
00017 
00018 Serialize::Checker<nickcore_map> NickCoreList("NickCore");
00019 
00020 NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), chanaccess("ChannelInfo"), aliases("NickAlias")
00021 {
00022         if (coredisplay.empty())
00023                 throw CoreException("Empty display passed to NickCore constructor");
00024 
00025         this->o = NULL;
00026         this->channelcount = 0;
00027         this->lastmail = 0;
00028         this->memos.memomax = Config->MSMaxMemos;
00029         this->language = Config->NSDefLanguage;
00030 
00031         this->display = coredisplay;
00032 
00033         /* Set default nick core flags */
00034         for (std::set<Anope::string>::const_iterator it = Config->NSDefFlags.begin(), it_end = Config->NSDefFlags.end(); it != it_end; ++it)
00035                 this->ExtendMetadata(*it);
00036 
00037         size_t old = NickCoreList->size();
00038         (*NickCoreList)[this->display] = this;
00039         if (old == NickCoreList->size())
00040                 Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?";
00041 }
00042 
00043 NickCore::~NickCore()
00044 {
00045         FOREACH_MOD(I_OnDelCore, OnDelCore(this));
00046 
00047         if (!this->chanaccess->empty())
00048                 Log(LOG_DEBUG) << "Non-empty chanaccess list in destructor!";
00049 
00050         for (std::list<User *>::iterator it = this->users.begin(); it != this->users.end();)
00051         {
00052                 User *user = *it++;
00053                 user->Logout();
00054         }
00055         this->users.clear();
00056 
00057         /* Remove the core from the list */
00058         NickCoreList->erase(this->display);
00059 
00060         /* Clear access before deleting display name, we want to be able to use the display name in the clear access event */
00061         this->ClearAccess();
00062 
00063         if (!this->memos.memos->empty())
00064         {
00065                 for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i)
00066                         delete this->memos.GetMemo(i);
00067                 this->memos.memos->clear();
00068         }
00069 }
00070 
00071 void NickCore::Serialize(Serialize::Data &data) const
00072 {
00073         data["display"] << this->display;
00074         data["pass"] << this->pass;
00075         data["email"] << this->email;
00076         data["greet"] << this->greet;
00077         data["language"] << this->language;
00078         this->ExtensibleSerialize(data);
00079         for (unsigned i = 0; i < this->access.size(); ++i)
00080                 data["access"] << this->access[i] << " ";
00081         for (unsigned i = 0; i < this->cert.size(); ++i)
00082                 data["cert"] << this->cert[i] << " ";
00083         data["memomax"] << this->memos.memomax;
00084         for (unsigned i = 0; i < this->memos.ignores.size(); ++i)
00085                 data["memoignores"] << this->memos.ignores[i] << " ";
00086 }
00087 
00088 Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data)
00089 {
00090         NickCore *nc;
00091 
00092         Anope::string sdisplay;
00093 
00094         data["display"] >> sdisplay;
00095 
00096         if (obj)
00097                 nc = anope_dynamic_static_cast<NickCore *>(obj);
00098         else
00099                 nc = new NickCore(sdisplay);
00100 
00101         data["pass"] >> nc->pass;
00102         data["email"] >> nc->email;
00103         data["greet"] >> nc->greet;
00104         data["language"] >> nc->language;
00105         nc->ExtensibleUnserialize(data);
00106         {
00107                 Anope::string buf;
00108                 data["access"] >> buf;
00109                 spacesepstream sep(buf);
00110                 nc->access.clear();
00111                 while (sep.GetToken(buf))
00112                         nc->access.push_back(buf);
00113         }
00114         {
00115                 Anope::string buf;
00116                 data["cert"] >> buf;
00117                 spacesepstream sep(buf);
00118                 nc->cert.clear();
00119                 while (sep.GetToken(buf))
00120                         nc->cert.push_back(buf);
00121         }
00122         data["memomax"] >> nc->memos.memomax;
00123         {
00124                 Anope::string buf;
00125                 data["memoignores"] >> buf;
00126                 spacesepstream sep(buf);
00127                 nc->memos.ignores.clear();
00128                 while (sep.GetToken(buf))
00129                         nc->memos.ignores.push_back(buf);
00130         }
00131 
00132         /* Compat */
00133         Anope::string sflags;
00134         data["flags"] >> sflags;
00135         spacesepstream sep(sflags);
00136         Anope::string tok;
00137         while (sep.GetToken(tok))
00138                 nc->ExtendMetadata(tok);
00139         /* End compat */
00140 
00141         return nc;
00142 }
00143 
00144 void NickCore::SetDisplay(const NickAlias *na)
00145 {
00146         if (na->nc != this || na->nick == this->display)
00147                 return;
00148 
00149         FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(this, na->nick));
00150 
00151         /* Remove the core from the list */
00152         NickCoreList->erase(this->display);
00153 
00154         this->display = na->nick;
00155 
00156         (*NickCoreList)[this->display] = this;
00157 }
00158 
00159 bool NickCore::IsServicesOper() const
00160 {
00161         return this->o != NULL;
00162 }
00163 
00164 void NickCore::AddAccess(const Anope::string &entry)
00165 {
00166         this->access.push_back(entry);
00167         FOREACH_MOD(I_OnNickAddAccess, OnNickAddAccess(this, entry));
00168 }
00169 
00170 Anope::string NickCore::GetAccess(unsigned entry) const
00171 {
00172         if (this->access.empty() || entry >= this->access.size())
00173                 return "";
00174         return this->access[entry];
00175 }
00176 
00177 bool NickCore::FindAccess(const Anope::string &entry)
00178 {
00179         for (unsigned i = 0, end = this->access.size(); i < end; ++i)
00180                 if (this->access[i] == entry)
00181                         return true;
00182 
00183         return false;
00184 }
00185 
00186 void NickCore::EraseAccess(const Anope::string &entry)
00187 {
00188         for (unsigned i = 0, end = this->access.size(); i < end; ++i)
00189                 if (this->access[i] == entry)
00190                 {
00191                         FOREACH_MOD(I_OnNickEraseAccess, OnNickEraseAccess(this, entry));
00192                         this->access.erase(this->access.begin() + i);
00193                         break;
00194                 }
00195 }
00196 
00197 void NickCore::ClearAccess()
00198 {
00199         FOREACH_MOD(I_OnNickClearAccess, OnNickClearAccess(this));
00200         this->access.clear();
00201 }
00202 
00203 bool NickCore::IsOnAccess(const User *u) const
00204 {
00205         Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3;
00206         if (!u->vhost.empty())
00207                 buf2 = u->GetIdent() + "@" + u->vhost;
00208         if (!u->GetCloakedHost().empty())
00209                 buf3 = u->GetIdent() + "@" + u->GetCloakedHost();
00210 
00211         for (unsigned i = 0, end = this->access.size(); i < end; ++i)
00212         {
00213                 Anope::string a = this->GetAccess(i);
00214                 if (Anope::Match(buf, a) || (!buf2.empty() && Anope::Match(buf2, a)) || (!buf3.empty() && Anope::Match(buf3, a)))
00215                         return true;
00216         }
00217         return false;
00218 }
00219 
00220 void NickCore::AddCert(const Anope::string &entry)
00221 {
00222         this->cert.push_back(entry);
00223         FOREACH_MOD(I_OnNickAddCert, OnNickAddCert(this, entry));
00224 }
00225 
00226 Anope::string NickCore::GetCert(unsigned entry) const
00227 {
00228         if (this->cert.empty() || entry >= this->cert.size())
00229                 return "";
00230         return this->cert[entry];
00231 }
00232 
00233 bool NickCore::FindCert(const Anope::string &entry) const
00234 {
00235         for (unsigned i = 0, end = this->cert.size(); i < end; ++i)
00236                 if (this->cert[i] == entry)
00237                         return true;
00238 
00239         return false;
00240 }
00241 
00242 void NickCore::EraseCert(const Anope::string &entry)
00243 {
00244         for (unsigned i = 0, end = this->cert.size(); i < end; ++i)
00245                 if (this->cert[i] == entry)
00246                 {
00247                         FOREACH_MOD(I_OnNickEraseCert, OnNickEraseCert(this, entry));
00248                         this->cert.erase(this->cert.begin() + i);
00249                         break;
00250                 }
00251 }
00252 
00253 void NickCore::ClearCert()
00254 {
00255         FOREACH_MOD(I_OnNickClearCert, OnNickClearCert(this));
00256         this->cert.clear();
00257 }
00258 
00259 void NickCore::AddChannelReference(ChannelInfo *ci)
00260 {
00261         ++(*this->chanaccess)[ci];
00262 }
00263 
00264 void NickCore::RemoveChannelReference(ChannelInfo *ci)
00265 {
00266         int& i = (*this->chanaccess)[ci];
00267         if (--i <= 0)
00268                 this->chanaccess->erase(ci);
00269 }
00270 
00271 void NickCore::GetChannelReferences(std::deque<ChannelInfo *> &queue)
00272 {
00273         queue.clear();
00274         for (std::map<ChannelInfo *, int>::iterator it = this->chanaccess->begin(), it_end = this->chanaccess->end(); it != it_end; ++it)
00275                 queue.push_back(it->first);
00276 }
00277 
00278 NickCore* NickCore::Find(const Anope::string &nick)
00279 {
00280         nickcore_map::const_iterator it = NickCoreList->find(nick);
00281         if (it != NickCoreList->end())
00282         {
00283                 it->second->QueueUpdate();
00284                 return it->second;
00285         }
00286 
00287         return NULL;
00288 }
00289