cs_set_misc.cpp

Go to the documentation of this file.
00001 /*
00002  * (C) 2003-2013 Anope Team
00003  * Contact us at team@anope.org
00004  *
00005  * Please read COPYING and README for further details.
00006  *
00007  * Based on the original code of Epona by Lara.
00008  * Based on the original code of Services by Andy Church.
00009  */
00010 
00011 /*************************************************************************/
00012 
00013 #include "module.h"
00014 
00015 static std::map<Anope::string, Anope::string> descriptions;
00016 
00017 struct CSMiscData : ExtensibleItem, Serializable
00018 {
00019         Serialize::Reference<ChannelInfo> ci;
00020         Anope::string name;
00021         Anope::string data;
00022 
00023         CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : Serializable("CSMiscData"), ci(c), name(n), data(d)
00024         {
00025         }
00026 
00027         void Serialize(Serialize::Data &sdata) const anope_override
00028         {
00029                 sdata["ci"] << this->ci->name;
00030                 sdata["name"] << this->name;
00031                 sdata["data"] << this->data;
00032         }
00033 
00034         static Serializable* Unserialize(Serializable *obj, Serialize::Data &data)
00035         {
00036                 Anope::string sci, sname, sdata;
00037 
00038                 data["ci"] >> sci;
00039                 data["name"] >> sname;
00040                 data["data"] >> sdata;
00041 
00042                 ChannelInfo *ci = ChannelInfo::Find(sci);
00043                 if (ci == NULL)
00044                         return NULL;
00045 
00046                 CSMiscData *d;
00047                 if (obj)
00048                 {
00049                         d = anope_dynamic_static_cast<CSMiscData *>(obj);
00050                         d->ci = ci;
00051                         data["name"] >> d->name;
00052                         data["data"] >> d->data;
00053                 }
00054                 else
00055                 {
00056                         d = new CSMiscData(ci, sname, sdata);
00057                         ci->Extend(sname, d);
00058                 }
00059 
00060                 return d;
00061         }
00062 };
00063 
00064 static Anope::string GetAttribute(const Anope::string &command)
00065 {
00066         size_t sp = command.rfind(' ');
00067         if (sp != Anope::string::npos)
00068                 return command.substr(sp + 1);
00069         return command;
00070 }
00071 
00072 class CommandCSSetMisc : public Command
00073 {
00074  public:
00075         CommandCSSetMisc(Module *creator, const Anope::string &cname = "chanserv/set/misc") : Command(creator, cname, 1, 2)
00076         {
00077                 this->SetSyntax(_("\037channel\037 [\037parameters\037]"));
00078         }
00079 
00080         void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00081         {
00082                 ChannelInfo *ci = ChannelInfo::Find(params[0]);
00083                 if (ci == NULL)
00084                 {
00085                         source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
00086                         return;
00087                 }
00088 
00089                 EventReturn MOD_RESULT;
00090                 FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1]));
00091                 if (MOD_RESULT == EVENT_STOP)
00092                         return;
00093 
00094                 if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET"))
00095                 {
00096                         source.Reply(ACCESS_DENIED);
00097                         return;
00098                 }
00099 
00100                 Anope::string scommand = GetAttribute(source.command);
00101                 Anope::string key = "cs_set_misc:" + scommand;
00102                 ci->Shrink(key);
00103                 if (params.size() > 1)
00104                 {
00105                         ci->Extend(key, new CSMiscData(ci, key, params[1]));
00106                         source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str());
00107                 }
00108                 else
00109                         source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str());
00110         }
00111 
00112         void OnServHelp(CommandSource &source) anope_override
00113         {
00114                 if (descriptions.count(source.command))
00115                 {
00116                         this->SetDesc(descriptions[source.command]);
00117                         Command::OnServHelp(source);
00118                 }
00119         }
00120 
00121         bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
00122         {
00123                 if (descriptions.count(source.command))
00124                 {
00125                         source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str()));
00126                         return true;
00127                 }
00128                 return false;
00129         }
00130 };
00131 
00132 class CSSetMisc : public Module
00133 {
00134         Serialize::Type csmiscdata_type;
00135         CommandCSSetMisc commandcssetmisc;
00136 
00137  public:
00138         CSSetMisc(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00139                 csmiscdata_type("CSMiscData", CSMiscData::Unserialize), commandcssetmisc(this)
00140         {
00141                 this->SetAuthor("Anope");
00142 
00143                 Implementation i[] = { I_OnReload, I_OnChanInfo };
00144                 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
00145 
00146                 this->OnReload();
00147         }
00148 
00149         void OnReload()
00150         {
00151                 ConfigReader config;
00152 
00153                 descriptions.clear();
00154 
00155                 for (int i = 0; i < config.Enumerate("command"); ++i)
00156                 {
00157                         if (config.ReadValue("command", "command", "", i) != "chanserv/set/misc")
00158                                 continue;
00159 
00160                         Anope::string cname = config.ReadValue("command", "name", "", i);
00161                         Anope::string desc = config.ReadValue("command", "misc_description", "", i);
00162 
00163                         if (cname.empty() || desc.empty())
00164                                 continue;
00165 
00166                         descriptions[cname] = desc;
00167                 }
00168         }
00169 
00170         void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool ShowHidden) anope_override
00171         {
00172                 std::deque<Anope::string> list;
00173                 ci->GetExtList(list);
00174 
00175                 for (unsigned i = 0; i < list.size(); ++i)
00176                 {
00177                         if (list[i].find("cs_set_misc:") != 0)
00178                                 continue;
00179                         
00180                         CSMiscData *data = ci->GetExt<CSMiscData *>(list[i]);
00181                         if (data != NULL)
00182                                 info[list[i].substr(12).replace_all_cs("_", " ")] = data->data;
00183                 }
00184         }
00185 };
00186 
00187 MODULE_INIT(CSSetMisc)