00001
00002
00003
00004
00005
00006
00007
00008
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> ¶ms) 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)