1
0
mirror of https://github.com/anope/anope.git synced 2026-06-12 17:04:47 +02:00

Store modes as their object form in ModeStatus.

This has the side effect of preventing users from putting nonsense
modes in {botserv}:botmodes and other related fields.
This commit is contained in:
Sadie Powell
2026-02-16 23:17:40 +00:00
parent 2f1f04f7cb
commit d43acc2381
14 changed files with 60 additions and 48 deletions
+8 -4
View File
@@ -263,16 +263,20 @@ public:
/* The status a user has on a channel (+v, +h, +o) etc */
class CoreExport ChannelStatus final
{
Anope::string modes;
private:
std::set<ChannelMode *> modes;
static bool IsValidMode(ChannelMode *cm);
public:
ChannelStatus() = default;
ChannelStatus(const Anope::string &modes);
void AddMode(char c);
void DelMode(char c);
bool HasMode(char c) const;
void AddMode(ChannelMode *cm);
void DelMode(ChannelMode *cm);
bool HasMode(ChannelMode *cm) const;
bool Empty() const;
void Clear();
const Anope::string &Modes() const;
const auto &Modes() const { return modes; }
Anope::string BuildModePrefixList() const;
};
+1 -1
View File
@@ -464,7 +464,7 @@ public:
{
auto *memb = c->FindUser(setter.GetUser());
ChannelMode *cm = ModeManager::FindChannelModeByName("OP");
if (memb && cm && !memb->status.HasMode(cm->mchar))
if (memb && cm && !memb->status.HasMode(cm))
{
/* Our -o and their mode change crossing, bounce their mode */
c->RemoveMode(c->ci->WhoSends(), mode, data.value);
+2 -2
View File
@@ -143,8 +143,8 @@ class CommandCSDown final
auto *memb = c->FindUser(u);
if (memb != NULL)
{
for (size_t i = memb->status.Modes().length(); i > 0;)
c->RemoveMode(NULL, ModeManager::FindChannelModeByChar(memb->status.Modes()[--i]), u->GetUID());
for (auto *mode : memb->status.Modes())
c->RemoveMode(NULL, mode, u->GetUID());
}
}
+1 -1
View File
@@ -292,7 +292,7 @@ public:
if (it != ei->end())
{
for (auto mode : it->second.Modes())
c->SetMode(c->WhoSends(), ModeManager::FindChannelModeByChar(mode), u->GetUID());
c->SetMode(c->WhoSends(), mode, u->GetUID());
ei->erase(it);
if (ei->empty())
+2 -2
View File
@@ -55,8 +55,8 @@ public:
if (uc->user->HasMode("OPER"))
continue;
for (size_t i = uc->status.Modes().length(); i > 0; --i)
c->RemoveMode(c->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i - 1]), uc->user->GetUID(), false);
for (auto *mode : uc->status.Modes())
c->RemoveMode(c->WhoSends(), mode, uc->user->GetUID(), false);
}
source.Reply(_("All modes cleared on %s."), c->name.c_str());
+2 -2
View File
@@ -122,8 +122,8 @@ public:
memb->status.Clear();
BotInfo *setter = BotInfo::Find(u->GetUID());
for (auto mode : cs.Modes())
c->SetMode(setter, ModeManager::FindChannelModeByChar(mode), u->GetUID(), false);
for (auto *mode : cs.Modes())
c->SetMode(setter, mode, u->GetUID(), false);
if (memb)
memb->status = cs;
+3 -3
View File
@@ -516,8 +516,8 @@ public:
memb->status.Clear();
BotInfo *setter = BotInfo::Find(user->GetUID());
for (auto mode : cs.Modes())
c->SetMode(setter, ModeManager::FindChannelModeByChar(mode), user->GetUID(), false);
for (auto *mode : cs.Modes())
c->SetMode(setter, mode, user->GetUID(), false);
if (memb != NULL)
memb->status = cs;
@@ -845,7 +845,7 @@ namespace InspIRCdExtBan
{
auto *memb = c->FindUser(u);
if (memb != NULL)
if (cm == NULL || memb->status.HasMode(cm->mchar))
if (cm == NULL || memb->status.HasMode(cm))
return true;
}
+2 -2
View File
@@ -105,8 +105,8 @@ public:
memb->status.Clear();
BotInfo *setter = BotInfo::Find(user->GetUID());
for (auto mode : cs.Modes())
c->SetMode(setter, ModeManager::FindChannelModeByChar(mode), user->GetUID(), false);
for (auto *mode : cs.Modes())
c->SetMode(setter, mode, user->GetUID(), false);
if (memb != NULL)
memb->status = cs;
+2 -2
View File
@@ -77,8 +77,8 @@ public:
memb->status.Clear();
BotInfo *setter = BotInfo::Find(user->GetUID());
for (auto mode : cs.Modes())
c->SetMode(setter, ModeManager::FindChannelModeByChar(mode), user->GetUID(), false);
for (auto *mode : cs.Modes())
c->SetMode(setter, mode, user->GetUID(), false);
if (memb != NULL)
memb->status = cs;
+1 -1
View File
@@ -134,7 +134,7 @@ public:
{
ChannelStatus status;
status.AddMode('o');
status.AddMode(ModeManager::FindChannelModeByName("OP"));
bi->Join(c, &status);
}
+3 -3
View File
@@ -200,8 +200,8 @@ private:
memb->status.Clear();
BotInfo *setter = BotInfo::Find(user->GetUID());
for (auto mode : cs.Modes())
c->SetMode(setter, ModeManager::FindChannelModeByChar(mode), user->GetUID(), false);
for (auto *mode : cs.Modes())
c->SetMode(setter, mode, user->GetUID(), false);
if (memb != NULL)
memb->status = cs;
@@ -554,7 +554,7 @@ namespace UnrealExtBan
{
auto *memb = c->FindUser(u);
if (memb != NULL)
if (cm == NULL || memb->status.HasMode(cm->mchar))
if (cm == NULL || memb->status.HasMode(cm))
return true;
}
+5 -5
View File
@@ -77,8 +77,8 @@ void Channel::Reset()
/* reset modes for my clients */
if (uc->user->server == Me)
{
for (auto mode : f.Modes())
this->SetMode(NULL, ModeManager::FindChannelModeByChar(mode), uc->user->GetUID(), false);
for (auto *mode : f.Modes())
this->SetMode(NULL, mode, uc->user->GetUID(), false);
/* Modes might not exist yet, so be sure the status is really reset */
uc->status = f;
}
@@ -182,7 +182,7 @@ bool Channel::HasUserStatus(User *u, ChannelModeStatus *cms)
if (memb)
{
if (cms)
return memb->status.HasMode(cms->mchar);
return memb->status.HasMode(cms);
else
return memb->status.Empty();
}
@@ -283,7 +283,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Mod
/* Set the status on the user */
auto *memb = u->FindChannel(this);
if (memb)
memb->status.AddMode(cm->mchar);
memb->status.AddMode(cm);
FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, data));
@@ -354,7 +354,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const
/* Remove the status on the user */
auto *memb = u->FindChannel(this);
if (memb)
memb->status.DelMode(cm->mchar);
memb->status.DelMode(cm);
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
+1 -1
View File
@@ -386,7 +386,7 @@ Conf::Conf() : Block("")
if (memb != NULL)
{
for (auto mode : memb->status.Modes())
c->RemoveMode(bi, ModeManager::FindChannelModeByChar(mode), bi->GetUID());
c->RemoveMode(bi, mode, bi->GetUID());
}
/* Set the new modes */
for (char want_mode : want_modes)
+27 -19
View File
@@ -64,24 +64,41 @@ struct StackerInfo final
void AddMode(Mode *mode, bool set, const ModeData &data);
};
ChannelStatus::ChannelStatus(const Anope::string &m) : modes(m)
ChannelStatus::ChannelStatus(const Anope::string &m)
{
for (const auto mc : m)
{
auto *cm = ModeManager::FindChannelModeByChar(mc);
if (IsValidMode(cm))
AddMode(cm);
}
}
bool ChannelStatus::IsValidMode(ChannelMode *cm)
{
return cm && cm->type == MODE_STATUS;
}
void ChannelStatus::AddMode(char c)
{
if (modes.find(c) == Anope::string::npos)
modes.append(c);
AddMode(ModeManager::FindChannelModeByChar(c));
}
void ChannelStatus::DelMode(char c)
void ChannelStatus::AddMode(ChannelMode *cm)
{
modes = modes.replace_all_cs(c, "");
if (IsValidMode(cm))
modes.insert(cm);
}
bool ChannelStatus::HasMode(char c) const
void ChannelStatus::DelMode(ChannelMode *cm)
{
return modes.find(c) != Anope::string::npos;
if (IsValidMode(cm))
modes.erase(cm);
}
bool ChannelStatus::HasMode(ChannelMode *cm) const
{
return IsValidMode(cm) && modes.find(cm) != modes.end();
}
bool ChannelStatus::Empty() const
@@ -94,23 +111,14 @@ void ChannelStatus::Clear()
modes.clear();
}
const Anope::string &ChannelStatus::Modes() const
{
return modes;
}
Anope::string ChannelStatus::BuildModePrefixList() const
{
Anope::string ret;
for (auto mode : modes)
for (const auto *cm : modes)
{
ChannelMode *cm = ModeManager::FindChannelModeByChar(mode);
if (cm != NULL && cm->type == MODE_STATUS)
{
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
ret += cms->symbol;
}
const auto *cms = anope_dynamic_static_cast<const ChannelModeStatus *>(cm);
ret += cms->symbol;
}
return ret;