1
0
mirror of https://github.com/anope/anope.git synced 2026-07-04 14:53:12 +02:00

Track what "level" channel status modes are, which allows us to have chanserv/mode determine if a status mode can be set by users better

This commit is contained in:
Adam
2011-08-19 04:18:13 -04:00
parent 6401d93b8e
commit 4fcb371bc8
10 changed files with 91 additions and 52 deletions
+7 -2
View File
@@ -276,13 +276,18 @@ class CoreExport ChannelModeStatus : public ChannelMode
public:
/* The symbol, eg @ % + */
char Symbol;
/* The "level" of the mode, used to compare with other modes.
* Used so we know op > halfop > voice etc.
*/
unsigned short Level;
/** Default constructor
* @param mName The mode name
* @param modeChar The mode char
* @param mSymbol The symbol for the mode, eg @ % +
* @param mSymbol The symbol for the mode, eg @ %
* @param mLevel A level for the mode, which is usually determined by the PREFIX capab
*/
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol);
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol, unsigned short mLevel = 0);
/** Default destructor
*/
+33 -25
View File
@@ -15,25 +15,29 @@
class CommandCSMode : public Command
{
bool CanSet(User *u, ChannelInfo *ci, ChannelModeName mode)
bool CanSet(User *u, ChannelInfo *ci, ChannelMode *cm)
{
switch (mode)
{
case CMODE_OWNER:
return ci->AccessFor(u).HasPriv(CA_OWNER);
case CMODE_PROTECT:
return ci->AccessFor(u).HasPriv(CA_PROTECT);
case CMODE_OP:
return ci->AccessFor(u).HasPriv(CA_OPDEOP);
case CMODE_HALFOP:
return ci->AccessFor(u).HasPriv(CA_HALFOP);
case CMODE_VOICE:
return ci->AccessFor(u).HasPriv(CA_VOICE);
default:
break;
}
if (!u || !ci || !cm || cm->Type != MODE_STATUS)
return false;
return false;
const ChannelAccess accesses[] = { CA_VOICE, CA_HALFOP, CA_OPDEOP, CA_PROTECT, CA_OWNER, CA_SIZE };
const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER };
ChannelModeStatus *cms = debug_cast<ChannelModeStatus *>(cm);
AccessGroup access = ci->AccessFor(u);
unsigned short u_level = 0;
for (int i = 0; accesses[i] != CA_SIZE; ++i)
if (access.HasPriv(accesses[i]))
{
ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]);
if (cm2 == NULL || cm2->Type != MODE_STATUS)
continue;
ChannelModeStatus *cms2 = debug_cast<ChannelModeStatus *>(cm2);
if (cms2->Level > u_level)
u_level = cms2->Level;
}
return u_level >= cms->Level;
}
void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -222,7 +226,7 @@ class CommandCSMode : public Command
if (!sep.GetToken(param))
break;
if (!this->CanSet(u, ci, cm->Name))
if (!this->CanSet(u, ci, cm))
{
source.Reply(_("You do not have access to set mode %c."), cm->ModeChar);
break;
@@ -256,15 +260,19 @@ class CommandCSMode : public Command
else
{
User *target = finduser(param);
if (target != NULL)
if (target == NULL)
{
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
source.Reply(NICK_X_NOT_IN_USE, param.c_str());
break;
}
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
if (adding)
ci->c->SetMode(NULL, cm, param);
else
+2 -2
View File
@@ -537,8 +537,8 @@ class ProtoBahamut : public Module
ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
/* v/h/o/a/q */
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 1));
/* Add channel modes */
ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
+8 -5
View File
@@ -524,26 +524,29 @@ class InspircdIRCdMessage : public IRCdMessage
{
Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')'));
Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end());
unsigned short level = modes.length() - 1;
for (size_t t = 0, end = modes.length(); t < end; ++t)
{
switch (modes[t])
{
case 'q':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~', level--));
continue;
case 'a':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&', level--));
continue;
case 'o':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', level--));
continue;
case 'h':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', level--));
continue;
case 'v':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', level--));
continue;
default:
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_END, modes[t], chars[t], level--));
}
}
}
+8 -5
View File
@@ -656,26 +656,29 @@ class Inspircd12IRCdMessage : public InspircdIRCdMessage
{
Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')'));
Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end());
unsigned short level = modes.length() - 1;
for (size_t t = 0, end = modes.length(); t < end; ++t)
{
switch (modes[t])
{
case 'q':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t]));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t], level--));
continue;
case 'a':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t]));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t], level--));
continue;
case 'o':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t]));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t], level--));
continue;
case 'h':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t]));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t], level--));
continue;
case 'v':
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t]));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t], level--));
continue;
default:
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_END, modes[t], chars[t], level--));
}
}
}
+19
View File
@@ -688,6 +688,25 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
Anope::string maxmodes(capab.begin() + 9, capab.end());
ircd->maxmodes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3;
}
else if (capab.find("PREFIX=") != Anope::string::npos)
{
Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')'));
Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end());
unsigned short level = modes.length() - 1;
for (size_t t = 0, end = modes.length(); t < end; ++t)
{
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[t]);
if (cm == NULL || cm->Type != MODE_STATUS)
{
Log() << "CAPAB PREFIX gave unknown channel status mode " << modes[t];
continue;
}
ChannelModeStatus *cms = debug_cast<ChannelModeStatus *>(cm);
cms->Level = level--;
}
}
}
}
else if (params[0].equals_cs("END"))
+5 -5
View File
@@ -631,11 +631,11 @@ class ProtoPlexus : public Module
ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
/* v/h/o/a/q */
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', 1));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 2));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&', 3));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~', 4));
/* Add channel modes */
ModeManager::AddChannelMode(new ChannelMode(CMODE_BANDWIDTH, 'B'));
+2 -2
View File
@@ -565,8 +565,8 @@ class ProtoRatbox : public Module
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
/* v/h/o/a/q */
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 1));
/* Add channel modes */
ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+5 -5
View File
@@ -1065,12 +1065,12 @@ class ProtoUnreal : public Module
void AddModes()
{
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', 1));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 2));
/* Unreal sends +q as * and +a as ~ */
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '~'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '*'));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '~', 3));
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '*', 4));
/* Add user modes */
ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A'));
+2 -1
View File
@@ -222,8 +222,9 @@ ChannelModeParam::~ChannelModeParam()
* @param mName The mode name
* @param modeChar The mode char
* @param mSymbol The symbol for the mode, eg @ % +
* @param mLevel A level for the mode, which is usually determined by the PREFIX capab
*/
ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol) : ChannelMode(mName, modeChar), Symbol(mSymbol)
ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol, unsigned short mLevel) : ChannelMode(mName, modeChar), Symbol(mSymbol), Level(mLevel)
{
this->Type = MODE_STATUS;
}