anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
m_rewrite.cpp (4887B)
1 /* 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 Rewrite 12 { 13 Anope::string client, source_message, target_message, desc; 14 15 bool Matches(const std::vector<Anope::string> &message) 16 { 17 std::vector<Anope::string> sm; 18 spacesepstream(this->source_message).GetTokens(sm); 19 20 for (unsigned i = 0; i < sm.size(); ++i) 21 if (i >= message.size() || (sm[i] != "$" && !sm[i].equals_ci(message[i]))) 22 return false; 23 24 return true; 25 } 26 27 Anope::string Process(CommandSource &source, const std::vector<Anope::string> ¶ms) 28 { 29 spacesepstream sep(this->target_message); 30 Anope::string token, message; 31 32 while (sep.GetToken(token)) 33 { 34 if (token[0] != '$') 35 message += " " + token; 36 else if (token == "$me") 37 message += " " + source.GetNick(); 38 else 39 { 40 int num = -1, end = -1; 41 try 42 { 43 Anope::string num_str = token.substr(1); 44 size_t hy = num_str.find('-'); 45 if (hy == Anope::string::npos) 46 { 47 num = convertTo<int>(num_str); 48 end = num + 1; 49 } 50 else 51 { 52 num = convertTo<int>(num_str.substr(0, hy)); 53 if (hy == num_str.length() - 1) 54 end = params.size(); 55 else 56 end = convertTo<int>(num_str.substr(hy + 1)) + 1; 57 } 58 } 59 catch (const ConvertException &) 60 { 61 continue; 62 } 63 64 for (int i = num; i < end && static_cast<unsigned>(i) < params.size(); ++i) 65 message += " " + params[i]; 66 } 67 } 68 69 message.trim(); 70 return message; 71 } 72 73 static std::vector<Rewrite> rewrites; 74 75 static Rewrite *Find(const Anope::string &client, const Anope::string &cmd) 76 { 77 for (unsigned i = 0; i < rewrites.size(); ++i) 78 { 79 Rewrite &r = rewrites[i]; 80 81 if ((client.empty() || r.client.equals_ci(client)) && (r.source_message.equals_ci(cmd) || r.source_message.find_ci(cmd + " ") == 0)) 82 return &r; 83 } 84 85 return NULL; 86 } 87 88 static Rewrite *Match(const Anope::string &client, const std::vector<Anope::string> ¶ms) 89 { 90 for (unsigned i = 0; i < rewrites.size(); ++i) 91 { 92 Rewrite &r = rewrites[i]; 93 94 if ((client.empty() || r.client.equals_ci(client)) && r.Matches(params)) 95 return &r; 96 } 97 98 return NULL; 99 } 100 }; 101 102 std::vector<Rewrite> Rewrite::rewrites; 103 104 class RewriteCommand : public Command 105 { 106 public: 107 RewriteCommand(Module *creator) : Command(creator, "rewrite", 0, 0) { } 108 109 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 110 { 111 std::vector<Anope::string> full_params = params; 112 full_params.insert(full_params.begin(), source.command); 113 114 Rewrite *r = Rewrite::Match(!source.c ? source.service->nick : "", full_params); 115 if (r != NULL) 116 { 117 Anope::string new_message = r->Process(source, full_params); 118 Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'"; 119 source.service = BotInfo::Find(r->client, true); 120 if (!source.service) 121 return; 122 Command::Run(source, new_message); 123 } 124 else 125 Log() << "m_rewrite: Unable to rewrite '" << source.command << (!params.empty() ? " " + params[0] : "") << "'"; 126 } 127 128 void OnServHelp(CommandSource &source) anope_override 129 { 130 Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command); 131 if (r != NULL && !r->desc.empty()) 132 { 133 this->SetDesc(r->desc); 134 Command::OnServHelp(source); 135 } 136 } 137 138 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 139 { 140 Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command); 141 if (r != NULL && !r->desc.empty()) 142 { 143 source.Reply(r->desc); 144 size_t sz = r->target_message.find(' '); 145 source.Reply(_("This command is an alias to the command %s."), sz != Anope::string::npos ? r->target_message.substr(0, sz).c_str() : r->target_message.c_str()); 146 return true; 147 } 148 return false; 149 } 150 }; 151 152 class ModuleRewrite : public Module 153 { 154 RewriteCommand cmdrewrite; 155 156 public: 157 ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA), cmdrewrite(this) 158 { 159 } 160 161 void OnReload(Configuration::Conf *conf) anope_override 162 { 163 Rewrite::rewrites.clear(); 164 165 for (int i = 0; i < conf->CountBlock("command"); ++i) 166 { 167 Configuration::Block *block = conf->GetBlock("command", i); 168 169 if (!block->Get<bool>("rewrite")) 170 continue; 171 172 Rewrite rw; 173 174 rw.client = block->Get<const Anope::string>("service"); 175 rw.source_message = block->Get<const Anope::string>("rewrite_source"); 176 rw.target_message = block->Get<const Anope::string>("rewrite_target"); 177 rw.desc = block->Get<const Anope::string>("rewrite_description"); 178 179 if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty()) 180 continue; 181 182 Rewrite::rewrites.push_back(rw); 183 } 184 } 185 }; 186 187 MODULE_INIT(ModuleRewrite)