anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
os_info.cpp (6661B)
1 /* OperServ core functions 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 */ 8 9 #include "module.h" 10 11 struct OperInfo : Serializable 12 { 13 Anope::string target; 14 Anope::string info; 15 Anope::string adder; 16 time_t created; 17 18 OperInfo() : Serializable("OperInfo"), created(0) { } 19 OperInfo(const Anope::string &t, const Anope::string &i, const Anope::string &a, time_t c) : 20 Serializable("OperInfo"), target(t), info(i), adder(a), created(c) { } 21 22 ~OperInfo(); 23 24 void Serialize(Serialize::Data &data) const anope_override 25 { 26 data["target"] << target; 27 data["info"] << info; 28 data["adder"] << adder; 29 data["created"] << created; 30 } 31 32 static Serializable *Unserialize(Serializable *obj, Serialize::Data &data); 33 }; 34 35 struct OperInfos : Serialize::Checker<std::vector<OperInfo *> > 36 { 37 OperInfos(Extensible *) : Serialize::Checker<std::vector<OperInfo *> >("OperInfo") { } 38 39 ~OperInfos() 40 { 41 for (unsigned i = (*this)->size(); i > 0; --i) 42 delete (*this)->at(i - 1); 43 } 44 45 static Extensible *Find(const Anope::string &target) 46 { 47 NickAlias *na = NickAlias::Find(target); 48 if (na) 49 return na->nc; 50 return ChannelInfo::Find(target); 51 } 52 }; 53 54 OperInfo::~OperInfo() 55 { 56 Extensible *e = OperInfos::Find(target); 57 if (e) 58 { 59 OperInfos *op = e->GetExt<OperInfos>("operinfo"); 60 if (op) 61 { 62 std::vector<OperInfo *>::iterator it = std::find((*op)->begin(), (*op)->end(), this); 63 if (it != (*op)->end()) 64 (*op)->erase(it); 65 } 66 } 67 } 68 69 Serializable *OperInfo::Unserialize(Serializable *obj, Serialize::Data &data) 70 { 71 Anope::string starget; 72 data["target"] >> starget; 73 74 Extensible *e = OperInfos::Find(starget); 75 if (!e) 76 return NULL; 77 78 OperInfos *oi = e->Require<OperInfos>("operinfo"); 79 OperInfo *o; 80 if (obj) 81 o = anope_dynamic_static_cast<OperInfo *>(obj); 82 else 83 { 84 o = new OperInfo(); 85 o->target = starget; 86 } 87 data["info"] >> o->info; 88 data["adder"] >> o->adder; 89 data["created"] >> o->created; 90 91 if (!obj) 92 (*oi)->push_back(o); 93 return o; 94 } 95 96 class CommandOSInfo : public Command 97 { 98 public: 99 CommandOSInfo(Module *creator) : Command(creator, "operserv/info", 2, 3) 100 { 101 this->SetDesc(_("Associate oper info with a nick or channel")); 102 this->SetSyntax(_("ADD \037target\037 \037info\037")); 103 this->SetSyntax(_("DEL \037target\037 \037info\037")); 104 this->SetSyntax(_("CLEAR \037target\037")); 105 } 106 107 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 108 { 109 const Anope::string &cmd = params[0], target = params[1], info = params.size() > 2 ? params[2] : ""; 110 111 Extensible *e; 112 if (IRCD->IsChannelValid(target)) 113 { 114 ChannelInfo *ci = ChannelInfo::Find(target); 115 if (!ci) 116 { 117 source.Reply(CHAN_X_NOT_REGISTERED, target.c_str()); 118 return; 119 } 120 121 e = ci; 122 } 123 else 124 { 125 NickAlias *na = NickAlias::Find(target); 126 if (!na) 127 { 128 source.Reply(NICK_X_NOT_REGISTERED, target.c_str()); 129 return; 130 } 131 132 e = na->nc; 133 } 134 135 if (cmd.equals_ci("ADD")) 136 { 137 if (info.empty()) 138 { 139 this->OnSyntaxError(source, cmd); 140 return; 141 } 142 143 OperInfos *oi = e->Require<OperInfos>("operinfo"); 144 145 if ((*oi)->size() >= Config->GetModule(this->module)->Get<unsigned>("max", "10")) 146 { 147 source.Reply(_("The oper info list for \002%s\002 is full."), target.c_str()); 148 return; 149 } 150 151 for (unsigned i = 0; i < (*oi)->size(); ++i) 152 { 153 OperInfo *o = (*oi)->at(i); 154 155 if (o->info.equals_ci(info)) 156 { 157 source.Reply(_("The oper info already exists on \002%s\002."), target.c_str()); 158 return; 159 } 160 } 161 162 (*oi)->push_back(new OperInfo(target, info, source.GetNick(), Anope::CurTime)); 163 164 source.Reply(_("Added info to \002%s\002."), target.c_str()); 165 Log(LOG_ADMIN, source, this) << "to add information to " << target; 166 167 if (Anope::ReadOnly) 168 source.Reply(READ_ONLY_MODE); 169 } 170 else if (cmd.equals_ci("DEL")) 171 { 172 if (info.empty()) 173 { 174 this->OnSyntaxError(source, cmd); 175 return; 176 } 177 178 OperInfos *oi = e->GetExt<OperInfos>("operinfo"); 179 180 if (!oi) 181 { 182 source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str()); 183 return; 184 } 185 186 bool found = false; 187 for (unsigned i = (*oi)->size(); i > 0; --i) 188 { 189 OperInfo *o = (*oi)->at(i - 1); 190 191 if (o->info.equals_ci(info)) 192 { 193 delete o; 194 found = true; 195 break; 196 } 197 } 198 199 if (!found) 200 { 201 source.Reply(_("No such info \"%s\" on \002%s\002."), info.c_str(), target.c_str()); 202 } 203 else 204 { 205 if ((*oi)->empty()) 206 e->Shrink<OperInfos>("operinfo"); 207 208 source.Reply(_("Deleted info from \002%s\002."), target.c_str()); 209 Log(LOG_ADMIN, source, this) << "to remove information from " << target; 210 211 if (Anope::ReadOnly) 212 source.Reply(READ_ONLY_MODE); 213 } 214 } 215 else if (cmd.equals_ci("CLEAR")) 216 { 217 OperInfos *oi = e->GetExt<OperInfos>("operinfo"); 218 219 if (!oi) 220 { 221 source.Reply(_("Oper info list for \002%s\002 is empty."), target.c_str()); 222 return; 223 } 224 225 e->Shrink<OperInfos>("operinfo"); 226 227 source.Reply(_("Cleared info from \002%s\002."), target.c_str()); 228 Log(LOG_ADMIN, source, this) << "to clear information for " << target; 229 230 if (Anope::ReadOnly) 231 source.Reply(READ_ONLY_MODE); 232 } 233 else 234 { 235 this->OnSyntaxError(source, cmd); 236 } 237 } 238 239 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 240 { 241 this->SendSyntax(source); 242 source.Reply(" "); 243 source.Reply(_("Add or delete oper information for a given nick or channel.\n" 244 "This will show to opers in the respective info command for\n" 245 "the nick or channel.")); 246 return true; 247 } 248 }; 249 250 class OSInfo : public Module 251 { 252 CommandOSInfo commandosinfo; 253 ExtensibleItem<OperInfos> oinfo; 254 Serialize::Type oinfo_type; 255 256 void OnInfo(CommandSource &source, Extensible *e, InfoFormatter &info) 257 { 258 if (!source.IsOper()) 259 return; 260 261 OperInfos *oi = oinfo.Get(e); 262 if (!oi) 263 return; 264 265 for (unsigned i = 0; i < (*oi)->size(); ++i) 266 { 267 OperInfo *o = (*oi)->at(i); 268 info[_("Oper Info")] = Anope::printf(_("(by %s on %s) %s"), o->adder.c_str(), Anope::strftime(o->created, source.GetAccount(), true).c_str(), o->info.c_str()); 269 } 270 } 271 272 public: 273 OSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), 274 commandosinfo(this), oinfo(this, "operinfo"), oinfo_type("OperInfo", OperInfo::Unserialize) 275 { 276 277 } 278 279 void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override 280 { 281 OnInfo(source, na->nc, info); 282 } 283 284 void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override 285 { 286 OnInfo(source, ci, info); 287 } 288 }; 289 290 MODULE_INIT(OSInfo)