anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

cs_updown.cpp (6536B)

      1 /* ChanServ 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  * 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 CommandCSUp : public Command
     15 {
     16 	void SetModes(User *u, Channel *c)
     17 	{
     18 		if (!c->ci)
     19 			return;
     20 
     21 		/* whether or not we are giving modes */
     22 		bool giving = true;
     23 		/* whether or not we have given a mode */
     24 		bool given = false;
     25 		AccessGroup u_access = c->ci->AccessFor(u);
     26 
     27 		for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
     28 		{
     29 			ChannelModeStatus *cm = ModeManager::GetStatusChannelModesByRank()[i];
     30 			bool has_priv = u_access.HasPriv("AUTO" + cm->name) || u_access.HasPriv(cm->name);
     31 
     32 			if (has_priv)
     33 			{
     34 				/* Always give op. If we have already given one mode, don't give more until it has a symbol */
     35 				if (cm->name == "OP" || !given || (giving && cm->symbol))
     36 				{
     37 					c->SetMode(NULL, cm, u->GetUID(), false);
     38 					/* Now if this contains a symbol don't give any more modes, to prevent setting +qaohv etc on users */
     39 					giving = !cm->symbol;
     40 					given = true;
     41 				}
     42 			}
     43 		}
     44 	}
     45  public:
     46 	CommandCSUp(Module *creator) : Command(creator, "chanserv/up", 0, 2)
     47 	{
     48 		this->SetDesc(_("Updates a selected nicks status on a channel"));
     49 		this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
     50 	}
     51 
     52 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
     53 	{
     54 		if (params.empty())
     55 		{
     56 			if (!source.GetUser())
     57 				return;
     58 			for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
     59 			{
     60 				Channel *c = it->second->chan;
     61 				SetModes(source.GetUser(), c);
     62 			}
     63 			Log(LOG_COMMAND, source, this, NULL) << "on all channels to update their status modes";
     64 		}
     65 		else
     66 		{
     67 			const Anope::string &channel = params[0];
     68 			const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
     69 
     70 			Channel *c = Channel::Find(channel);
     71 
     72 			if (c == NULL)
     73 			{
     74 				source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
     75 				return;
     76 			}
     77 			else if (!c->ci)
     78 			{
     79 				source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
     80 				return;
     81 			}
     82 
     83 			User *u = User::Find(nick, true);
     84 			User *srcu = source.GetUser();
     85 			bool override = false;
     86 
     87 			if (u == NULL)
     88 			{
     89 				source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
     90 				return;
     91 			}
     92 			else if (srcu && !srcu->FindChannel(c))
     93 			{
     94 				source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
     95 				return;
     96 			}
     97 			else if (!u->FindChannel(c))
     98 			{
     99 				source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
    100 				return;
    101 			}
    102 			else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
    103 			{
    104 				if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
    105 				{
    106 					if (source.HasPriv("chanserv/administration"))
    107 						override = true;
    108 					else
    109 					{
    110 						source.Reply(ACCESS_DENIED);
    111 						return;
    112 					}
    113 				}
    114 			}
    115 
    116 			Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci) << "to update the status modes of " << u->nick;
    117 			SetModes(u, c);
    118 		}
    119 
    120 	}
    121 
    122 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    123 	{
    124 		this->SendSyntax(source);
    125 		source.Reply(" ");
    126 		source.Reply(_("Updates a selected nicks status modes on a channel. If \037nick\037 is\n"
    127 				"omitted then your status is updated. If \037channel\037 is omitted then\n"
    128 				"your channel status is updated on every channel you are in."));
    129 		return true;
    130 	}
    131 };
    132 
    133 class CommandCSDown : public Command
    134 {
    135 	void RemoveAll(User *u, Channel *c)
    136 	{
    137 		ChanUserContainer *cu = c->FindUser(u);
    138 		if (cu != NULL)
    139 			for (size_t i = cu->status.Modes().length(); i > 0;)
    140 				c->RemoveMode(NULL, ModeManager::FindChannelModeByChar(cu->status.Modes()[--i]), u->GetUID());
    141 	}
    142 
    143  public:
    144 	CommandCSDown(Module *creator) : Command(creator, "chanserv/down", 0, 2)
    145 	{
    146 		this->SetDesc(_("Removes a selected nicks status from a channel"));
    147 		this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
    148 	}
    149 
    150 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
    151 	{
    152 		if (params.empty())
    153 		{
    154 			if (!source.GetUser())
    155 				return;
    156 			for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
    157 			{
    158 				Channel *c = it->second->chan;
    159 				RemoveAll(source.GetUser(), c);
    160 			}
    161 			Log(LOG_COMMAND, source, this, NULL) << "on all channels to remove their status modes";
    162 		}
    163 		else
    164 		{
    165 			const Anope::string &channel = params[0];
    166 			const Anope::string &nick = params.size() > 1 ? params[1] : source.GetNick();
    167 
    168 			Channel *c = Channel::Find(channel);
    169 
    170 			if (c == NULL)
    171 			{
    172 				source.Reply(CHAN_X_NOT_IN_USE, channel.c_str());
    173 				return;
    174 			}
    175 			else if (!c->ci)
    176 			{
    177 				source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
    178 				return;
    179 			}
    180 
    181 			User *u = User::Find(nick, true);
    182 			User *srcu = source.GetUser();
    183 			bool override = false;
    184 
    185 			if (u == NULL)
    186 			{
    187 				source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
    188 				return;
    189 			}
    190 			else if (srcu && !srcu->FindChannel(c))
    191 			{
    192 				source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str());
    193 				return;
    194 			}
    195 			else if (!u->FindChannel(c))
    196 			{
    197 				source.Reply(NICK_X_NOT_ON_CHAN, nick.c_str(), channel.c_str());
    198 				return;
    199 			}
    200 			else if (source.GetUser() && u != source.GetUser() && c->ci->HasExt("PEACE"))
    201 			{
    202 				if (c->ci->AccessFor(u) >= c->ci->AccessFor(source.GetUser()))
    203 				{
    204 					if (source.HasPriv("chanserv/administration"))
    205 						override = true;
    206 					else
    207 					{
    208 						source.Reply(ACCESS_DENIED);
    209 						return;
    210 					}
    211 				}
    212 			}
    213 
    214 			Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci) << "to remove the status modes from " << u->nick;
    215 			RemoveAll(u, c);
    216 		}
    217 	}
    218 
    219 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    220 	{
    221 		this->SendSyntax(source);
    222 		source.Reply(" ");
    223 		source.Reply(_("Removes a selected nicks status modes on a channel. If \037nick\037 is\n"
    224 				"omitted then your status is removed. If \037channel\037 is omitted then\n"
    225 				"your channel status is removed on every channel you are in."));
    226 		return true;
    227 	}
    228 };
    229 
    230 class CSUpDown : public Module
    231 {
    232 	CommandCSUp commandcsup;
    233 	CommandCSDown commandcsdown;
    234 
    235  public:
    236 	CSUpDown(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
    237 		commandcsup(this), commandcsdown(this)
    238 	{
    239 
    240 	}
    241 };
    242 
    243 MODULE_INIT(CSUpDown)