00001 #include "inspircd.h"
00002 #include "xline.h"
00003
00004
00005
00006 class Shun : public XLine
00007 {
00008 public:
00009 std::string matchtext;
00010
00011 Shun(InspIRCd* Instance, time_t s_time, long d, const char* src, const char* re, const char *shunmask) : XLine(Instance, s_time, d, src, re, "SHUN")
00012 {
00013 this->matchtext = shunmask;
00014 }
00015
00016 ~Shun()
00017 {
00018 }
00019
00020 bool Matches(User *u)
00021 {
00022 if (InspIRCd::Match(u->GetFullHost(), matchtext) || InspIRCd::Match(u->GetFullRealHost(), matchtext))
00023 return true;
00024
00025 return false;
00026 }
00027
00028 bool Matches(const std::string &s)
00029 {
00030 if (matchtext == s)
00031 return true;
00032 return false;
00033 }
00034
00035 void Apply(User *u)
00036 {
00037 if (!u->GetExt("shunned"))
00038 u->Extend("shunned");
00039 }
00040
00041
00042 void DisplayExpiry()
00043 {
00044 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed shun %s (set by %s %ld seconds ago)", this->matchtext.c_str(), this->source, this->duration);
00045 }
00046
00047 const char* Displayable()
00048 {
00049 return matchtext.c_str();
00050 }
00051 };
00052
00055 class ShunFactory : public XLineFactory
00056 {
00057 public:
00058 ShunFactory(InspIRCd* Instance) : XLineFactory(Instance, "SHUN") { }
00059
00062 XLine* Generate(time_t set_time, long duration, const char* source, const char* reason, const char* xline_specific_mask)
00063 {
00064 return new Shun(ServerInstance, set_time, duration, source, reason, xline_specific_mask);
00065 }
00066 };
00067
00068
00069
00070 class cmd_shun : public Command
00071 {
00072 private:
00073 InspIRCd *Srv;
00074
00075 public:
00076 cmd_shun(InspIRCd* Me) : Command(Me, "SHUN", "o", 1, 3), Srv(Me)
00077 {
00078 this->source = "m_shun.so";
00079 this->syntax = "<nick!user@hostmask> [<shun-duration>] :<reason>";
00080 }
00081
00082 CmdResult Handle(const std::vector<std::string>& parameters, User *user)
00083 {
00084
00085
00086
00087 if (parameters.size() == 1)
00088 {
00089 if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "SHUN", user))
00090 {
00091 ServerInstance->SNO->WriteToSnoMask('x',"%s Removed shun on %s.",user->nick.c_str(),parameters[0].c_str());
00092 }
00093 else
00094 {
00095
00096 user->WriteServ("NOTICE %s :*** Shun %s not found in list, try /stats s.",user->nick.c_str(),parameters[0].c_str());
00097 }
00098
00099 return CMD_SUCCESS;
00100 }
00101 else if (parameters.size() >= 2)
00102 {
00103
00104 long duration = ServerInstance->Duration(parameters[1]);
00105 Shun *r = NULL;
00106
00107 try
00108 {
00109 r = new Shun(ServerInstance, ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
00110 }
00111 catch (...)
00112 {
00113 ;
00114 }
00115
00116 if (r)
00117 {
00118 if (ServerInstance->XLines->AddLine(r, user))
00119 {
00120 if (!duration)
00121 {
00122 ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent shun for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
00123 }
00124 else
00125 {
00126 time_t c_requires_crap = duration + ServerInstance->Time();
00127 ServerInstance->SNO->WriteToSnoMask('x', "%s added timed shun for %s, expires on %s: %s", user->nick.c_str(), parameters[0].c_str(), ServerInstance->TimeString(c_requires_crap).c_str(), parameters[2].c_str());
00128 }
00129
00130 ServerInstance->XLines->ApplyLines();
00131 }
00132 else
00133 {
00134 delete r;
00135 user->WriteServ("NOTICE %s :*** Shun for %s already exists", user->nick.c_str(), parameters[0].c_str());
00136 }
00137 }
00138 }
00139
00140 return CMD_FAILURE;
00141 }
00142 };
00143
00144 class ModuleShun : public Module
00145 {
00146 cmd_shun* mycommand;
00147 ShunFactory *f;
00148 std::map<std::string, bool> ShunEnabledCommands;
00149 bool NotifyOfShun;
00150
00151 public:
00152 ModuleShun(InspIRCd* Me) : Module(Me)
00153 {
00154 f = new ShunFactory(ServerInstance);
00155 ServerInstance->XLines->RegisterFactory(f);
00156
00157 mycommand = new cmd_shun(ServerInstance);
00158 ServerInstance->AddCommand(mycommand);
00159
00160 Implementation eventlist[] = { I_OnStats, I_OnPreCommand, I_OnUserConnect, I_OnRehash };
00161 ServerInstance->Modules->Attach(eventlist, this, 4);
00162 OnRehash(NULL, "");
00163 }
00164
00165 virtual ~ModuleShun()
00166 {
00167 ServerInstance->XLines->DelAll("SHUN");
00168 ServerInstance->XLines->UnregisterFactory(f);
00169 }
00170
00171 virtual int OnStats(char symbol, User* user, string_list& out)
00172 {
00173 if (symbol != 'S')
00174 return 0;
00175
00176 ServerInstance->XLines->InvokeStats("SHUN", 223, user, out);
00177 return 1;
00178 }
00179
00180 virtual void OnRehash(User* user, const std::string ¶meter)
00181 {
00182 ConfigReader MyConf(ServerInstance);
00183 std::string cmds = MyConf.ReadValue("shun", "enabledcommands", 0);
00184
00185 if (cmds.empty())
00186 cmds = "PING PONG QUIT";
00187
00188 ShunEnabledCommands.clear();
00189 NotifyOfShun = true;
00190
00191 std::stringstream dcmds(cmds);
00192 std::string thiscmd;
00193
00194 while (dcmds >> thiscmd)
00195 {
00196 ShunEnabledCommands[thiscmd] = true;
00197 }
00198
00199 NotifyOfShun = MyConf.ReadFlag("shun", "notifyuser", "yes", 0);
00200 }
00201
00202 virtual void OnUserConnect(User* user)
00203 {
00204 if (!IS_LOCAL(user))
00205 return;
00206
00207
00208 XLine *rl = ServerInstance->XLines->MatchesLine("SHUN", user);
00209
00210 if (rl)
00211 {
00212
00213 rl->Apply(user);
00214 }
00215 }
00216
00217 virtual int OnPreCommand(std::string &command, std::vector<std::string>& parameters, User* user, bool validated, const std::string &original_line)
00218 {
00219 if (validated || !user->GetExt("shunned"))
00220 return 0;
00221
00222 if (!ServerInstance->XLines->MatchesLine("SHUN", user))
00223 {
00224
00225 user->Shrink("shunned");
00226 return 0;
00227 }
00228
00229 std::map<std::string, bool>::iterator i = ShunEnabledCommands.find(command);
00230
00231 if (i == ShunEnabledCommands.end())
00232 {
00233 user->WriteServ("NOTICE %s :*** Command %s not processed, as you have been blocked from issuing commands (SHUN)", user->nick.c_str(), command.c_str());
00234 return 1;
00235 }
00236
00237 if (command == "QUIT")
00238 {
00239
00240 parameters.clear();
00241 }
00242 else if (command == "PART")
00243 {
00244
00245 parameters.clear();
00246 }
00247
00248 return 1;
00249 }
00250
00251 virtual Version GetVersion()
00252 {
00253 return Version("$Id: m_shun.cpp 10741 2008-10-28 16:11:20Z w00t $",VF_VENDOR|VF_COMMON,API_VERSION);
00254 }
00255 };
00256
00257 MODULE_INIT(ModuleShun)
00258