X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_permchannels.cpp;h=60c4578c5053aea61c6166dd63a964f9a7fe62f1;hb=2a924db786cfb2531126f56a8227bd46c63e444c;hp=2190a5206cf82f0c49bd98010ec2bc8fd278b21b;hpb=992674362c5f64bdb8e1942eeaa7612524529cd6;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp index 2190a5206..60c4578c5 100644 --- a/src/modules/m_permchannels.cpp +++ b/src/modules/m_permchannels.cpp @@ -23,12 +23,6 @@ #include -struct ListModeData -{ - std::string modes; - std::string params; -}; - /** Handles the +P channel mode */ class PermChannel : public ModeHandler @@ -63,7 +57,7 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list * So, let's write to a temporary file, flush it, then rename the file.. * -- w00t */ - + // If the user has not specified a configuration file then we don't write one. if (permchannelsconf.empty()) return true; @@ -76,11 +70,12 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list ServerInstance->SNO->WriteToSnoMask('a', "database: cannot create new db: %s (%d)", strerror(errno), errno); return false; } - + stream << "# This file is automatically generated by m_permchannels. Any changes will be overwritten." << std::endl << "" << std::endl; - for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++) + const chan_hash& chans = ServerInstance->GetChans(); + for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); ++i) { Channel* chan = i->second; if (!chan->IsModeSet(permchanmode)) @@ -89,33 +84,45 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list std::string chanmodes = chan->ChanModes(true); if (save_listmodes) { - ListModeData lm; + std::string modes; + std::string params; - // Bans are managed by the core, so we have to process them separately - static_cast(*ban)->DoSyncChannel(chan, mod, &lm); + const ModeParser::ListModeList& listmodes = ServerInstance->Modes->GetListModes(); + for (ModeParser::ListModeList::const_iterator j = listmodes.begin(); j != listmodes.end(); ++j) + { + ListModeBase* lm = *j; + ListModeBase::ModeList* list = lm->GetList(chan); + if (!list || list->empty()) + continue; - // All other listmodes are managed by modules, so we need to ask them (call their - // OnSyncChannel() handler) to give our ProtoSendMode() a list of modes that are - // set on the channel. The ListModeData struct is passed as an opaque pointer - // that will be passed back to us by the module handling the mode. - FOREACH_MOD(OnSyncChannel, (chan, mod, &lm)); + size_t n = 0; + // Append the parameters + for (ListModeBase::ModeList::const_iterator k = list->begin(); k != list->end(); ++k, n++) + { + params += k->mask; + params += ' '; + } - if (!lm.modes.empty()) + // Append the mode letters (for example "IIII", "gg") + modes.append(n, lm->GetModeChar()); + } + + if (!params.empty()) { // Remove the last space - lm.params.erase(lm.params.end()-1); + params.erase(params.end()-1); // If there is at least a space in chanmodes (that is, a non-listmode has a parameter) // insert the listmode mode letters before the space. Otherwise just append them. std::string::size_type p = chanmodes.find(' '); if (p == std::string::npos) - chanmodes += lm.modes; + chanmodes += modes; else - chanmodes.insert(p, lm.modes); + chanmodes.insert(p, modes); // Append the listmode parameters (the masks themselves) chanmodes += ' '; - chanmodes += lm.params; + chanmodes += params; } } @@ -137,12 +144,7 @@ static bool WriteDatabase(PermChannel& permchanmode, Module* mod, bool save_list stream.close(); #ifdef _WIN32 - if (remove(permchannelsconf.c_str())) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Cannot remove old database! %s (%d)", strerror(errno), errno); - ServerInstance->SNO->WriteToSnoMask('a', "database: cannot remove old database: %s (%d)", strerror(errno), errno); - return false; - } + remove(permchannelsconf.c_str()); #endif // Use rename to move temporary to new db - this is guarenteed not to fuck up, even in case of a crash. if (rename(permchannelsnewconf.c_str(), permchannelsconf.c_str()) < 0) @@ -159,37 +161,13 @@ class ModulePermanentChannels : public Module { PermChannel p; bool dirty; + bool loaded; bool save_listmodes; public: - ModulePermanentChannels() : p(this), dirty(false) - { - } - - CullResult cull() + ModulePermanentChannels() + : p(this), dirty(false), loaded(false) { - /* - * DelMode can't remove the +P mode on empty channels, or it will break - * merging modes with remote servers. Remove the empty channels now as - * we know this is not the case. - */ - chan_hash::iterator iter = ServerInstance->chanlist->begin(); - while (iter != ServerInstance->chanlist->end()) - { - Channel* c = iter->second; - if (c->GetUserCounter() == 0) - { - chan_hash::iterator at = iter; - iter++; - FOREACH_MOD(OnChannelDelete, (c)); - ServerInstance->chanlist->erase(at); - ServerInstance->GlobalCulls.AddItem(c); - } - else - iter++; - } - ServerInstance->Modes->DelMode(&p); - return Module::cull(); } void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE @@ -197,6 +175,9 @@ public: ConfigTag* tag = ServerInstance->Config->ConfValue("permchanneldb"); permchannelsconf = tag->getString("filename"); save_listmodes = tag->getBool("listmodes"); + + if (!permchannelsconf.empty()) + permchannelsconf = ServerInstance->Config->Paths.PrependConfig(permchannelsconf); } void LoadDatabase() @@ -267,9 +248,9 @@ public: } } - ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string ¶m, bool adding, int pcnt) CXX11_OVERRIDE + ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding) CXX11_OVERRIDE { - if (chan && (chan->IsModeSet(p) || mode == p.GetModeChar())) + if (chan && (chan->IsModeSet(p) || mh == &p)) dirty = true; return MOD_RES_PASSTHRU; @@ -295,8 +276,6 @@ public: // to be able to set the modes they provide (e.g.: m_stripcolor is inited after us) // Prioritize() is called after all module initialization is complete, consequently // all modes are available now - - static bool loaded = false; if (loaded) return; @@ -320,25 +299,6 @@ public: } } - void ProtoSendMode(void* opaque, TargetTypeFlags type, void* target, const std::vector& modes, const std::vector& translate) - { - // We never pass an empty modelist but better be sure - if (modes.empty()) - return; - - ListModeData* lm = static_cast(opaque); - - // Append the mode letters without the trailing '+' (for example "IIII", "gg") - lm->modes.append(modes[0].begin()+1, modes[0].end()); - - // Append the parameters - for (std::vector::const_iterator i = modes.begin()+1; i != modes.end(); ++i) - { - lm->params += *i; - lm->params += ' '; - } - } - Version GetVersion() CXX11_OVERRIDE { return Version("Provides support for channel mode +P to provide permanent channels",VF_VENDOR);