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:
+7
-2
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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> ¶ms)
|
||||
@@ -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
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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--));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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--));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user