anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
fantasy.cpp (6119B)
1 /* Fantasy functionality 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 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #include "module.h" 13 14 class CommandBSSetFantasy : public Command 15 { 16 public: 17 CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2) 18 { 19 this->SetDesc(_("Enable fantaisist commands")); 20 this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); 21 } 22 23 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 24 { 25 ChannelInfo *ci = ChannelInfo::Find(params[0]); 26 const Anope::string &value = params[1]; 27 28 if (ci == NULL) 29 { 30 source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); 31 return; 32 } 33 34 if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET")) 35 { 36 source.Reply(ACCESS_DENIED); 37 return; 38 } 39 40 if (Anope::ReadOnly) 41 { 42 source.Reply(_("Sorry, bot option setting is temporarily disabled.")); 43 return; 44 } 45 46 if (value.equals_ci("ON")) 47 { 48 bool override = !source.AccessFor(ci).HasPriv("SET"); 49 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy"; 50 51 ci->Extend<bool>("BS_FANTASY"); 52 source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str()); 53 } 54 else if (value.equals_ci("OFF")) 55 { 56 bool override = !source.AccessFor(ci).HasPriv("SET"); 57 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy"; 58 59 ci->Shrink<bool>("BS_FANTASY"); 60 source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str()); 61 } 62 else 63 this->OnSyntaxError(source, source.command); 64 } 65 66 bool OnHelp(CommandSource &source, const Anope::string &) anope_override 67 { 68 this->SendSyntax(source); 69 source.Reply(_(" \n" 70 "Enables or disables \002fantasy\002 mode on a channel.\n" 71 "When it is enabled, users will be able to use\n" 72 "fantasy commands on a channel when prefixed\n" 73 "with one of the following fantasy characters: \002%s\002\n" 74 " \n" 75 "Note that users wanting to use fantaisist\n" 76 "commands MUST have enough access for both\n" 77 "the FANTASIA and the command they are executing."), 78 Config->GetModule(this->owner)->Get<const Anope::string>("fantasycharacter", "!").c_str()); 79 return true; 80 } 81 }; 82 83 class Fantasy : public Module 84 { 85 SerializableExtensibleItem<bool> fantasy; 86 87 CommandBSSetFantasy commandbssetfantasy; 88 89 public: 90 Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), 91 fantasy(this, "BS_FANTASY"), commandbssetfantasy(this) 92 { 93 } 94 95 void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override 96 { 97 if (!u || !c || !c->ci || !c->ci->bi || msg.empty() || msg[0] == '\1') 98 return; 99 100 if (Config->GetClient("BotServ") && !fantasy.HasExt(c->ci)) 101 return; 102 103 std::vector<Anope::string> params; 104 spacesepstream(msg).GetTokens(params); 105 106 if (params.empty()) 107 return; 108 109 Anope::string normalized_param0 = Anope::NormalizeBuffer(params[0]); 110 Anope::string fantasy_chars = Config->GetModule(this)->Get<Anope::string>("fantasycharacter", "!"); 111 112 if (!normalized_param0.find(c->ci->bi->nick)) 113 { 114 params.erase(params.begin()); 115 } 116 else if (!normalized_param0.find_first_of(fantasy_chars)) 117 { 118 size_t sz = params[0].find_first_of(fantasy_chars); 119 if (sz == Anope::string::npos) 120 return; /* normalized_param0 is a subset of params[0] so this can't happen */ 121 122 params[0].erase(0, sz + 1); 123 } 124 else 125 { 126 return; 127 } 128 129 if (params.empty()) 130 return; 131 132 CommandInfo::map::const_iterator it = Config->Fantasy.end(); 133 unsigned count = 0; 134 for (unsigned max = params.size(); it == Config->Fantasy.end() && max > 0; --max) 135 { 136 Anope::string full_command; 137 for (unsigned i = 0; i < max; ++i) 138 full_command += " " + params[i]; 139 full_command.erase(full_command.begin()); 140 141 ++count; 142 it = Config->Fantasy.find(Anope::NormalizeBuffer(full_command)); 143 } 144 145 if (it == Config->Fantasy.end()) 146 return; 147 148 const CommandInfo &info = it->second; 149 ServiceReference<Command> cmd("Command", info.name); 150 if (!cmd) 151 { 152 Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for nonexistent service " << info.name << "!"; 153 return; 154 } 155 156 for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i) 157 params.erase(params.begin()); 158 159 /* Some commands take the channel as a first parameter */ 160 if (info.prepend_channel) 161 params.insert(params.begin(), c->name); 162 163 while (cmd->max_params > 0 && params.size() > cmd->max_params) 164 { 165 params[cmd->max_params - 1] += " " + params[cmd->max_params]; 166 params.erase(params.begin() + cmd->max_params); 167 } 168 169 // Command requires registered users only 170 if (!cmd->AllowUnregistered() && !u->Account()) 171 return; 172 173 if (params.size() < cmd->min_params) 174 return; 175 176 CommandSource source(u->nick, u, u->Account(), u, c->ci->bi); 177 source.c = c; 178 source.command = it->first; 179 source.permission = info.permission; 180 181 AccessGroup ag = c->ci->AccessFor(u); 182 bool has_fantasia = ag.HasPriv("FANTASIA") || source.HasPriv("botserv/fantasy"); 183 184 EventReturn MOD_RESULT; 185 if (has_fantasia) 186 { 187 FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params)); 188 } 189 else 190 { 191 FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params)); 192 } 193 194 if (MOD_RESULT == EVENT_STOP || !has_fantasia) 195 return; 196 197 if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission)) 198 return; 199 200 FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, cmd, params)); 201 if (MOD_RESULT == EVENT_STOP) 202 return; 203 204 Reference<NickCore> nc_reference(u->Account()); 205 cmd->Execute(source, params); 206 if (!nc_reference) 207 source.nc = NULL; 208 FOREACH_MOD(OnPostCommand, (source, cmd, params)); 209 } 210 211 void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) anope_override 212 { 213 if (fantasy.HasExt(ci)) 214 info.AddOption(_("Fantasy")); 215 } 216 }; 217 218 MODULE_INIT(Fantasy)