mirror of
https://github.com/anope/anope.git
synced 2026-07-01 09:46:40 +02:00
Move akick from the core to cs_akick.
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
class AccessGroup;
|
||||
class AutoKick;
|
||||
namespace ChanServ { class AutoKick; }
|
||||
class BotInfo;
|
||||
class CallBack;
|
||||
class ChanAccess;
|
||||
|
||||
+4
-4
@@ -672,14 +672,14 @@ public:
|
||||
* @param ci The channel
|
||||
* @param ak The akick
|
||||
*/
|
||||
virtual void OnAkickAdd(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
|
||||
virtual void OnAKickAdd(CommandSource &source, ChannelInfo *ci, const ChanServ::AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
|
||||
|
||||
/** Called before removing an akick from a channel
|
||||
* @param source The source of the command
|
||||
* @param ci The channel
|
||||
* @param ak The akick
|
||||
*/
|
||||
virtual void OnAkickDel(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
|
||||
virtual void OnAKickDel(CommandSource &source, ChannelInfo *ci, const ChanServ::AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
|
||||
|
||||
/** Called after a user join a channel when we decide whether to kick them or not
|
||||
* @param u The user
|
||||
@@ -1087,8 +1087,8 @@ enum Implementation
|
||||
I_OnAccessClear,
|
||||
I_OnAccessDel,
|
||||
I_OnAddXLine,
|
||||
I_OnAkickAdd,
|
||||
I_OnAkickDel,
|
||||
I_OnAKickAdd,
|
||||
I_OnAKickDel,
|
||||
I_OnBadWordAdd,
|
||||
I_OnBadWordDel,
|
||||
I_OnBotAssign,
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// Anope IRC Services <https://www.anope.org/>
|
||||
//
|
||||
// Copyright (C) 2003-2025 Anope Contributors
|
||||
//
|
||||
// Anope is free software. You can use, modify, and/or distribute it under the
|
||||
// terms of version 2 of the GNU General Public License. See docs/LICENSE.txt
|
||||
// for the complete terms of this license and docs/AUTHORS.txt for a list of
|
||||
// contributors.
|
||||
//
|
||||
// Based on the original code of Epona by Lara
|
||||
// Based on the original code of Services by Andy Church
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#define AUTOKICK_TYPE "AutoKick"
|
||||
#define AUTOKICK_SERVICE "ChanServ::AutoKickService"
|
||||
|
||||
namespace ChanServ
|
||||
{
|
||||
class AutoKick;
|
||||
class AutoKickService;
|
||||
|
||||
ServiceReference<AutoKickService> akick_service(AUTOKICK_SERVICE, AUTOKICK_TYPE);
|
||||
}
|
||||
|
||||
class ChanServ::AutoKickService
|
||||
: public Service
|
||||
{
|
||||
public:
|
||||
AutoKickService(Module *m)
|
||||
: Service(m, AUTOKICK_SERVICE, AUTOKICK_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
/** Add an akick entry to the channel by NickCore
|
||||
* @param user The user who added the akick
|
||||
* @param akicknc The nickcore being akicked
|
||||
* @param reason The reason for the akick
|
||||
* @param t The time the akick was added, defaults to now
|
||||
* @param lu The time the akick was last used, defaults to never
|
||||
*/
|
||||
virtual AutoKick *AddAKick(ChannelInfo *ci, const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) = 0;
|
||||
|
||||
/** Add an akick entry to the channel by reason
|
||||
* @param user The user who added the akick
|
||||
* @param mask The mask of the akick
|
||||
* @param reason The reason for the akick
|
||||
* @param t The time the akick was added, defaults to now
|
||||
* @param lu The time the akick was last used, defaults to never
|
||||
*/
|
||||
virtual AutoKick *AddAKick(ChannelInfo *ci, const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) = 0;
|
||||
|
||||
/** Get an entry from the channel akick list
|
||||
* @param index The index in the akick vector
|
||||
* @return The akick structure, or NULL if not found
|
||||
*/
|
||||
virtual AutoKick *GetAKick(ChannelInfo *ci, unsigned index) = 0;
|
||||
|
||||
/** Get the size of the akick vector for this channel
|
||||
* @return The akick vector size
|
||||
*/
|
||||
virtual unsigned GetAKickCount(ChannelInfo *ci) = 0;
|
||||
|
||||
/** Erase an entry from the channel akick list
|
||||
* @param index The index of the akick
|
||||
*/
|
||||
virtual void EraseAKick(ChannelInfo *ci, unsigned index) = 0;
|
||||
virtual void EraseAKick(ChannelInfo *ci, AutoKick *akick) = 0;
|
||||
|
||||
/** Clear the whole akick list
|
||||
*/
|
||||
virtual void ClearAKick(ChannelInfo *ci) = 0;
|
||||
};
|
||||
|
||||
class ChanServ::AutoKick final
|
||||
: public Serializable
|
||||
{
|
||||
public:
|
||||
/* Channel this autokick is on */
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
|
||||
Anope::string mask;
|
||||
Serialize::Reference<NickCore> nc;
|
||||
|
||||
Anope::string reason;
|
||||
Anope::string creator;
|
||||
time_t addtime;
|
||||
time_t last_used;
|
||||
|
||||
AutoKick()
|
||||
: Serializable(AUTOKICK_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoKick()
|
||||
{
|
||||
if (!this->ci)
|
||||
return;
|
||||
|
||||
if (ChanServ::akick_service)
|
||||
ChanServ::akick_service->EraseAKick(this->ci, this);
|
||||
|
||||
if (this->nc)
|
||||
this->nc->RemoveChannelReference(this->ci);
|
||||
}
|
||||
};
|
||||
@@ -26,34 +26,6 @@ typedef Anope::unordered_map<ChannelInfo *> registered_channel_map;
|
||||
|
||||
extern CoreExport Serialize::Checker<registered_channel_map> RegisteredChannelList;
|
||||
|
||||
/* AutoKick data. */
|
||||
class CoreExport AutoKick final
|
||||
: public Serializable
|
||||
{
|
||||
public:
|
||||
struct Type final
|
||||
: public Serialize::Type
|
||||
{
|
||||
Type();
|
||||
void Serialize(Serializable *obj, Serialize::Data &data) const override;
|
||||
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override;
|
||||
};
|
||||
|
||||
/* Channel this autokick is on */
|
||||
Serialize::Reference<ChannelInfo> ci;
|
||||
|
||||
Anope::string mask;
|
||||
Serialize::Reference<NickCore> nc;
|
||||
|
||||
Anope::string reason;
|
||||
Anope::string creator;
|
||||
time_t addtime;
|
||||
time_t last_used;
|
||||
|
||||
AutoKick();
|
||||
~AutoKick();
|
||||
};
|
||||
|
||||
/* It matters that Base is here before Extensible (it is inherited by Serializable)
|
||||
*/
|
||||
class CoreExport ChannelInfo final
|
||||
@@ -75,7 +47,6 @@ private:
|
||||
Serialize::Reference<NickCore> founder; /* Channel founder */
|
||||
Serialize::Reference<NickCore> successor; /* Who gets the channel if the founder nick is dropped or expires */
|
||||
Serialize::Checker<std::vector<ChanAccess *> > access; /* List of authorized users */
|
||||
Serialize::Checker<std::vector<AutoKick *> > akick; /* List of users to kickban */
|
||||
Anope::map<int16_t> levels;
|
||||
|
||||
public:
|
||||
@@ -180,44 +151,6 @@ public:
|
||||
*/
|
||||
void ClearAccess();
|
||||
|
||||
/** Add an akick entry to the channel by NickCore
|
||||
* @param user The user who added the akick
|
||||
* @param akicknc The nickcore being akicked
|
||||
* @param reason The reason for the akick
|
||||
* @param t The time the akick was added, defaults to now
|
||||
* @param lu The time the akick was last used, defaults to never
|
||||
*/
|
||||
AutoKick *AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0);
|
||||
|
||||
/** Add an akick entry to the channel by reason
|
||||
* @param user The user who added the akick
|
||||
* @param mask The mask of the akick
|
||||
* @param reason The reason for the akick
|
||||
* @param t The time the akick was added, defaults to now
|
||||
* @param lu The time the akick was last used, defaults to never
|
||||
*/
|
||||
AutoKick *AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0);
|
||||
|
||||
/** Get an entry from the channel akick list
|
||||
* @param index The index in the akick vector
|
||||
* @return The akick structure, or NULL if not found
|
||||
*/
|
||||
AutoKick *GetAkick(unsigned index) const;
|
||||
|
||||
/** Get the size of the akick vector for this channel
|
||||
* @return The akick vector size
|
||||
*/
|
||||
unsigned GetAkickCount() const;
|
||||
|
||||
/** Erase an entry from the channel akick list
|
||||
* @param index The index of the akick
|
||||
*/
|
||||
void EraseAkick(unsigned index);
|
||||
|
||||
/** Clear the whole akick list
|
||||
*/
|
||||
void ClearAkick();
|
||||
|
||||
/** Get the level entries for the channel.
|
||||
* @return The levels for the channel.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "base.h"
|
||||
|
||||
/** Names of serialization types implemented in the core. */
|
||||
#define AUTOKICK_TYPE "AutoKick"
|
||||
#define BOTINFO_TYPE "BotInfo"
|
||||
#define CHANACCESS_TYPE "ChanAccess"
|
||||
#define CHANNELINFO_TYPE "ChannelInfo"
|
||||
|
||||
@@ -211,16 +211,6 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
|
||||
{
|
||||
const AutoKick *akick = ci->GetAkick(j);
|
||||
if (akick->nc == nc)
|
||||
{
|
||||
ci->EraseAkick(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+237
-28
@@ -13,6 +13,180 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/chanserv/akick.h"
|
||||
|
||||
#define AKICK_EXT "akicks"
|
||||
|
||||
class AKickService final
|
||||
: public ChanServ::AutoKickService
|
||||
{
|
||||
private:
|
||||
struct AKickList final
|
||||
: Serialize::Checker<std::vector<ChanServ::AutoKick *>>
|
||||
{
|
||||
AKickList(Extensible *)
|
||||
: Serialize::Checker<std::vector<ChanServ::AutoKick *>>(AKICK_EXT)
|
||||
{
|
||||
}
|
||||
};
|
||||
ExtensibleItem<AKickList> akickext;
|
||||
|
||||
public:
|
||||
AKickService(Module *m)
|
||||
: ChanServ::AutoKickService(m)
|
||||
, akickext(m, AKICK_EXT)
|
||||
{
|
||||
}
|
||||
|
||||
ChanServ::AutoKick *AddAKick(ChannelInfo *ci, const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) override
|
||||
{
|
||||
auto *akick = new ChanServ::AutoKick();
|
||||
akick->ci = ci;
|
||||
akick->nc = akicknc;
|
||||
akick->reason = reason;
|
||||
akick->creator = user;
|
||||
akick->addtime = t;
|
||||
akick->last_used = lu;
|
||||
|
||||
auto *akicks = akickext.Require(ci);
|
||||
(*akicks)->push_back(akick);
|
||||
|
||||
akicknc->AddChannelReference(ci);
|
||||
|
||||
return akick;
|
||||
}
|
||||
|
||||
ChanServ::AutoKick *AddAKick(ChannelInfo *ci, const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t = Anope::CurTime, time_t lu = 0) override
|
||||
{
|
||||
auto *akick = new ChanServ::AutoKick();
|
||||
akick->ci = ci;
|
||||
akick->mask = mask;
|
||||
akick->nc = nullptr;
|
||||
akick->reason = reason;
|
||||
akick->creator = user;
|
||||
akick->addtime = t;
|
||||
akick->last_used = lu;
|
||||
|
||||
auto *akicks = akickext.Require(ci);
|
||||
(*akicks)->push_back(akick);
|
||||
|
||||
return akick;
|
||||
}
|
||||
|
||||
ChanServ::AutoKick *GetAKick(ChannelInfo *ci, unsigned index) override
|
||||
{
|
||||
auto *akicks = akickext.Get(ci);
|
||||
if (!akicks || index >= (*akicks)->size())
|
||||
return nullptr;
|
||||
|
||||
auto *akick = (*akicks)->at(index);
|
||||
akick->QueueUpdate();
|
||||
return akick;
|
||||
}
|
||||
|
||||
unsigned GetAKickCount(ChannelInfo *ci) override
|
||||
{
|
||||
auto *akicks = akickext.Get(ci);
|
||||
return akicks ? (*akicks)->size() : 0;
|
||||
}
|
||||
|
||||
void EraseAKick(ChannelInfo *ci, unsigned index) override
|
||||
{
|
||||
auto *akicks = akickext.Get(ci);
|
||||
if (akicks && index < (*akicks)->size())
|
||||
delete (*akicks)->at(index);
|
||||
}
|
||||
|
||||
void EraseAKick(ChannelInfo *ci, ChanServ::AutoKick *akick) override
|
||||
{
|
||||
auto *akicks = akickext.Get(ci);
|
||||
if (!akicks)
|
||||
return;
|
||||
|
||||
auto it = std::find((*akicks)->begin(), (*akicks)->end(), akick);
|
||||
if (it != (*akicks)->end())
|
||||
(*akicks)->erase(it);
|
||||
}
|
||||
|
||||
void ClearAKick(ChannelInfo *ci) override
|
||||
{
|
||||
auto *akicks = akickext.Get(ci);
|
||||
if (!akicks)
|
||||
return; // No akick list.
|
||||
|
||||
while (!(*akicks)->empty())
|
||||
delete (*akicks)->back();
|
||||
}
|
||||
};
|
||||
|
||||
struct AutoKickType final
|
||||
: public Serialize::Type
|
||||
{
|
||||
AutoKickType()
|
||||
: Serialize::Type(AUTOKICK_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(Serializable *obj, Serialize::Data &data) const override
|
||||
{
|
||||
const auto *ak = static_cast<const ChanServ::AutoKick *>(obj);
|
||||
data.Store("ci", ak->ci->name);
|
||||
if (ak->nc)
|
||||
data.Store("ncid", ak->nc->GetId());
|
||||
else
|
||||
data.Store("mask", ak->mask);
|
||||
data.Store("reason", ak->reason);
|
||||
data.Store("creator", ak->creator);
|
||||
data.Store("addtime", ak->addtime);
|
||||
data.Store("last_used", ak->last_used);
|
||||
}
|
||||
|
||||
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
|
||||
{
|
||||
Anope::string sci, snc;
|
||||
uint64_t sncid = 0;
|
||||
|
||||
data["ci"] >> sci;
|
||||
data["nc"] >> snc; // Deprecated 2.0 field
|
||||
data["ncid"] >> sncid;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
ChanServ::AutoKick *ak;
|
||||
auto *nc = sncid ? NickCore::FindId(sncid) : NickCore::Find(snc);
|
||||
if (obj)
|
||||
{
|
||||
ak = anope_dynamic_static_cast<ChanServ::AutoKick *>(obj);
|
||||
data["creator"] >> ak->creator;
|
||||
data["reason"] >> ak->reason;
|
||||
ak->nc = nc;
|
||||
data["mask"] >> ak->mask;
|
||||
data["addtime"] >> ak->addtime;
|
||||
data["last_used"] >> ak->last_used;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t addtime, lastused;
|
||||
data["addtime"] >> addtime;
|
||||
data["last_used"] >> lastused;
|
||||
|
||||
Anope::string screator, sreason, smask;
|
||||
|
||||
data["creator"] >> screator;
|
||||
data["reason"] >> sreason;
|
||||
data["mask"] >> smask;
|
||||
|
||||
if (nc)
|
||||
ak = ChanServ::akick_service->AddAKick(ci, screator, nc, sreason, addtime, lastused);
|
||||
else
|
||||
ak = ChanServ::akick_service->AddAKick(ci, screator, smask, sreason, addtime, lastused);
|
||||
}
|
||||
|
||||
return ak;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSAKick final
|
||||
: public Command
|
||||
@@ -48,7 +222,7 @@ class CommandCSAKick final
|
||||
Anope::string reason = params.size() > 3 ? params[3] : "";
|
||||
const NickAlias *na = NickAlias::Find(mask);
|
||||
NickCore *nc = NULL;
|
||||
const AutoKick *akick;
|
||||
const ChanServ::AutoKick *akick;
|
||||
unsigned reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
|
||||
|
||||
if (reason.length() > reasonmax)
|
||||
@@ -163,9 +337,9 @@ class CommandCSAKick final
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
|
||||
for (unsigned j = 0, end = ChanServ::akick_service->GetAKickCount(ci); j < end; ++j)
|
||||
{
|
||||
akick = ci->GetAkick(j);
|
||||
akick = ChanServ::akick_service->GetAKick(ci, j);
|
||||
if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
|
||||
{
|
||||
source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->nc ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
|
||||
@@ -173,20 +347,20 @@ class CommandCSAKick final
|
||||
}
|
||||
}
|
||||
|
||||
if (ci->GetAkickCount() >= Config->GetModule(this->owner).Get<unsigned>("autokickmax"))
|
||||
if (ChanServ::akick_service->GetAKickCount(ci) >= Config->GetModule(this->owner).Get<unsigned>("autokickmax"))
|
||||
{
|
||||
source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner).Get<unsigned>("autokickmax"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (nc)
|
||||
akick = ci->AddAkick(source.GetNick(), nc, reason);
|
||||
akick = ChanServ::akick_service->AddAKick(ci, source.GetNick(), nc, reason);
|
||||
else
|
||||
akick = ci->AddAkick(source.GetNick(), mask, reason);
|
||||
akick = ChanServ::akick_service->AddAKick(ci, source.GetNick(), mask, reason);
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
|
||||
|
||||
FOREACH_MOD(OnAkickAdd, (source, ci, akick));
|
||||
FOREACH_MOD(OnAKickAdd, (source, ci, akick));
|
||||
|
||||
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
|
||||
@@ -198,7 +372,7 @@ class CommandCSAKick final
|
||||
const Anope::string &mask = params[2];
|
||||
unsigned i, end;
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
if (!ChanServ::akick_service->GetAKickCount(ci))
|
||||
{
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
@@ -241,19 +415,19 @@ class CommandCSAKick final
|
||||
|
||||
void HandleNumber(unsigned number) override
|
||||
{
|
||||
if (!number || number > ci->GetAkickCount())
|
||||
if (!number || number > ChanServ::akick_service->GetAKickCount(ci))
|
||||
return;
|
||||
|
||||
const AutoKick *akick = ci->GetAkick(number - 1);
|
||||
const auto *akick = ChanServ::akick_service->GetAKick(ci, number - 1);
|
||||
|
||||
FOREACH_MOD(OnAkickDel, (source, ci, akick));
|
||||
FOREACH_MOD(OnAKickDel, (source, ci, akick));
|
||||
|
||||
bool override = !ag.HasPriv("AKICK");
|
||||
lastdeleted = (akick->nc ? akick->nc->display : akick->mask);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << lastdeleted;
|
||||
|
||||
++deleted;
|
||||
ci->EraseAkick(number - 1);
|
||||
ChanServ::akick_service->EraseAKick(ci, number - 1);
|
||||
}
|
||||
}
|
||||
delcallback(source, ci, this, mask);
|
||||
@@ -264,15 +438,15 @@ class CommandCSAKick final
|
||||
const NickAlias *na = NickAlias::Find(mask);
|
||||
const NickCore *nc = na ? *na->nc : NULL;
|
||||
|
||||
for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
|
||||
for (i = 0, end = ChanServ::akick_service->GetAKickCount(ci); i < end; ++i)
|
||||
{
|
||||
const AutoKick *akick = ci->GetAkick(i);
|
||||
const auto *akick = ChanServ::akick_service->GetAKick(ci, i);
|
||||
|
||||
if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ci->GetAkickCount())
|
||||
if (i == ChanServ::akick_service->GetAKickCount(ci))
|
||||
{
|
||||
source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
@@ -281,9 +455,9 @@ class CommandCSAKick final
|
||||
bool override = !source.AccessFor(ci).HasPriv("AKICK");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
|
||||
|
||||
FOREACH_MOD(OnAkickDel, (source, ci, ci->GetAkick(i)));
|
||||
FOREACH_MOD(OnAKickDel, (source, ci, ChanServ::akick_service->GetAKick(ci, i)));
|
||||
|
||||
ci->EraseAkick(i);
|
||||
ChanServ::akick_service->EraseAKick(ci, i);
|
||||
|
||||
source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
}
|
||||
@@ -308,10 +482,10 @@ class CommandCSAKick final
|
||||
|
||||
void HandleNumber(unsigned number) override
|
||||
{
|
||||
if (!number || number > ci->GetAkickCount())
|
||||
if (!number || number > ChanServ::akick_service->GetAKickCount(ci))
|
||||
return;
|
||||
|
||||
const AutoKick *akick = ci->GetAkick(number - 1);
|
||||
const auto *akick = ChanServ::akick_service->GetAKick(ci, number - 1);
|
||||
|
||||
Anope::string timebuf, lastused;
|
||||
if (akick->addtime)
|
||||
@@ -341,9 +515,9 @@ class CommandCSAKick final
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
|
||||
for (unsigned i = 0, end = ChanServ::akick_service->GetAKickCount(ci); i < end; ++i)
|
||||
{
|
||||
const AutoKick *akick = ci->GetAkick(i);
|
||||
const auto *akick = ChanServ::akick_service->GetAKick(ci, i);
|
||||
|
||||
if (!mask.empty())
|
||||
{
|
||||
@@ -389,7 +563,7 @@ class CommandCSAKick final
|
||||
|
||||
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
if (!ci->GetAkickCount())
|
||||
if (!ChanServ::akick_service->GetAKickCount(ci))
|
||||
{
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
@@ -409,7 +583,7 @@ class CommandCSAKick final
|
||||
|
||||
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
if (!ci->GetAkickCount())
|
||||
if (!ChanServ::akick_service->GetAKickCount(ci))
|
||||
{
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
@@ -445,7 +619,7 @@ class CommandCSAKick final
|
||||
bool override = !source.AccessFor(ci).HasPriv("AKICK");
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the akick list";
|
||||
|
||||
ci->ClearAkick();
|
||||
ChanServ::akick_service->ClearAKick(ci);
|
||||
source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
|
||||
}
|
||||
|
||||
@@ -561,22 +735,57 @@ public:
|
||||
class CSAKick final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
AKickService akick_service;
|
||||
AutoKickType autokick_type;
|
||||
CommandCSAKick commandcsakick;
|
||||
|
||||
public:
|
||||
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
|
||||
commandcsakick(this)
|
||||
CSAKick(const Anope::string &modname, const Anope::string &creator)
|
||||
: Module(modname, creator, VENDOR)
|
||||
, akick_service(this)
|
||||
, commandcsakick(this)
|
||||
{
|
||||
}
|
||||
|
||||
void OnCreateChan(ChannelInfo *ci) override
|
||||
{
|
||||
OnDelChan(ci); // copy ctor might have been called
|
||||
}
|
||||
|
||||
void OnDelChan(ChannelInfo *ci) override
|
||||
{
|
||||
akick_service.ClearAKick(ci);
|
||||
}
|
||||
|
||||
void OnDelCore(NickCore *nc) override
|
||||
{
|
||||
std::deque<ChannelInfo *> chans;
|
||||
nc->GetChannelReferences(chans);
|
||||
|
||||
for (auto *ci : chans)
|
||||
{
|
||||
for (unsigned j = 0; j < akick_service.GetAKickCount(ci); ++j)
|
||||
{
|
||||
const auto *akick = akick_service.GetAKick(ci, j);
|
||||
if (akick->nc == nc)
|
||||
{
|
||||
akick_service.EraseAKick(ci, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
|
||||
{
|
||||
if (!c->ci || c->MatchesList(u, "EXCEPT"))
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
for (unsigned j = 0, end = c->ci->GetAkickCount(); j < end; ++j)
|
||||
|
||||
for (unsigned j = 0, end = ChanServ::akick_service->GetAKickCount(c->ci); j < end; ++j)
|
||||
{
|
||||
AutoKick *autokick = c->ci->GetAkick(j);
|
||||
auto *autokick = ChanServ::akick_service->GetAKick(c->ci, j);
|
||||
bool kick = false;
|
||||
|
||||
if (autokick->nc)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/botserv/badwords.h"
|
||||
#include "modules/chanserv/akick.h"
|
||||
|
||||
class CommandCSClone final
|
||||
: public Command
|
||||
@@ -63,14 +64,17 @@ class CommandCSClone final
|
||||
|
||||
static void CopyAkick(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
|
||||
{
|
||||
target_ci->ClearAkick();
|
||||
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
|
||||
if (!ChanServ::akick_service)
|
||||
return;
|
||||
|
||||
ChanServ::akick_service->ClearAKick(target_ci);
|
||||
for (unsigned i = 0; i < ChanServ::akick_service->GetAKickCount(ci); ++i)
|
||||
{
|
||||
const AutoKick *akick = ci->GetAkick(i);
|
||||
const auto *akick = ChanServ::akick_service->GetAKick(ci, i);
|
||||
if (akick->nc)
|
||||
target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
|
||||
ChanServ::akick_service->AddAKick(ci, akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
|
||||
else
|
||||
target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
|
||||
ChanServ::akick_service->AddAKick(ci, akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
|
||||
}
|
||||
|
||||
source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/chanserv/akick.h"
|
||||
|
||||
class CommandCSStatus final
|
||||
: public Command
|
||||
@@ -82,20 +83,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
|
||||
if (ChanServ::akick_service)
|
||||
{
|
||||
AutoKick *autokick = ci->GetAkick(j);
|
||||
for (unsigned j = 0, end = ChanServ::akick_service->GetAKickCount(ci); j < end; ++j)
|
||||
{
|
||||
const auto *autokick = ChanServ::akick_service->GetAKick(ci, j);
|
||||
|
||||
if (autokick->nc)
|
||||
{
|
||||
if (na && *autokick->nc == na->nc)
|
||||
source.Reply(_("\002%s\002 is on the auto kick list of \002%s\002 (%s)."), na->nc->display.c_str(), ci->name.c_str(), autokick->reason.c_str());
|
||||
}
|
||||
else if (u != NULL)
|
||||
{
|
||||
Entry akick_mask("", autokick->mask);
|
||||
if (akick_mask.Matches(u))
|
||||
source.Reply(_("\002%s\002 matches auto kick entry %s on \002%s\002 (%s)."), u->nick.c_str(), autokick->mask.c_str(), ci->name.c_str(), autokick->reason.c_str());
|
||||
if (autokick->nc)
|
||||
{
|
||||
if (na && *autokick->nc == na->nc)
|
||||
source.Reply(_("\002%s\002 is on the auto kick list of \002%s\002 (%s)."), na->nc->display.c_str(), ci->name.c_str(), autokick->reason.c_str());
|
||||
}
|
||||
else if (u != NULL)
|
||||
{
|
||||
Entry akick_mask("", autokick->mask);
|
||||
if (akick_mask.Matches(u))
|
||||
source.Reply(_("\002%s\002 matches auto kick entry %s on \002%s\002 (%s)."), u->nick.c_str(), autokick->mask.c_str(), ci->name.c_str(), autokick->reason.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "module.h"
|
||||
#include "modules/botserv/badwords.h"
|
||||
#include "modules/botserv/kick.h"
|
||||
#include "modules/chanserv/akick.h"
|
||||
#include "modules/chanserv/entrymsg.h"
|
||||
#include "modules/chanserv/mode.h"
|
||||
#include "modules/hostserv/request.h"
|
||||
@@ -121,7 +122,7 @@ struct ModeLockData final
|
||||
|
||||
struct ChannelData final
|
||||
{
|
||||
Anope::unordered_map<AutoKick *> akicks;
|
||||
Anope::unordered_map<ChanServ::AutoKick *> akicks;
|
||||
Anope::string bot;
|
||||
Anope::string info_adder;
|
||||
Anope::string info_message;
|
||||
@@ -609,11 +610,17 @@ private:
|
||||
auto *nc = NickCore::Find(mask);
|
||||
if (flags.find('b') != Anope::string::npos)
|
||||
{
|
||||
if (ChanServ::akick_service)
|
||||
{
|
||||
Log(this) << "Unable to import channel akick for " << ci->name << " as cs_akick is not loaded";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *data = chandata.Require(ci);
|
||||
if (nc)
|
||||
data->akicks[mask] = ci->AddAkick(setter, nc, "", modifiedtime, modifiedtime);
|
||||
data->akicks[mask] = ChanServ::akick_service->AddAKick(ci, setter, nc, "", modifiedtime, modifiedtime);
|
||||
else
|
||||
data->akicks[mask] = ci->AddAkick(setter, mask, "", modifiedtime, modifiedtime);
|
||||
data->akicks[mask] = ChanServ::akick_service->AddAKick(ci, setter, mask, "", modifiedtime, modifiedtime);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include "../../webcpanel.h"
|
||||
#include "modules/chanserv/akick.h"
|
||||
|
||||
WebCPanel::ChanServ::Akick::Akick(const Anope::string &cat, const Anope::string &u) : WebPanelProtectedPage(cat, u)
|
||||
{
|
||||
@@ -75,16 +76,19 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTP::Provider *server, const Anope::
|
||||
|
||||
replacements["ESCAPED_CHANNEL"] = HTTP::URLEncode(chname);
|
||||
|
||||
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
|
||||
if (::ChanServ::akick_service)
|
||||
{
|
||||
AutoKick *akick = ci->GetAkick(i);
|
||||
for (unsigned i = 0; i < ::ChanServ::akick_service->GetAKickCount(ci); ++i)
|
||||
{
|
||||
const auto *akick = ::ChanServ::akick_service->GetAKick(ci, i);
|
||||
|
||||
if (akick->nc)
|
||||
replacements["MASKS"] = akick->nc->display;
|
||||
else
|
||||
replacements["MASKS"] = akick->mask;
|
||||
replacements["CREATORS"] = akick->creator;
|
||||
replacements["REASONS"] = akick->reason;
|
||||
if (akick->nc)
|
||||
replacements["MASKS"] = akick->nc->display;
|
||||
else
|
||||
replacements["MASKS"] = akick->mask;
|
||||
replacements["CREATORS"] = akick->creator;
|
||||
replacements["REASONS"] = akick->reason;
|
||||
}
|
||||
}
|
||||
|
||||
Page.Serve(server, page_name, client, message, reply, replacements);
|
||||
|
||||
@@ -24,93 +24,9 @@
|
||||
|
||||
Serialize::Checker<registered_channel_map> RegisteredChannelList(CHANNELINFO_TYPE);
|
||||
|
||||
AutoKick::AutoKick()
|
||||
: Serializable(AUTOKICK_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
AutoKick::~AutoKick()
|
||||
{
|
||||
if (this->ci)
|
||||
{
|
||||
std::vector<AutoKick *>::iterator it = std::find(this->ci->akick->begin(), this->ci->akick->end(), this);
|
||||
if (it != this->ci->akick->end())
|
||||
this->ci->akick->erase(it);
|
||||
|
||||
if (nc)
|
||||
nc->RemoveChannelReference(this->ci);
|
||||
}
|
||||
}
|
||||
|
||||
AutoKick::Type::Type()
|
||||
: Serialize::Type(AUTOKICK_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
void AutoKick::Type::Serialize(Serializable *obj, Serialize::Data &data) const
|
||||
{
|
||||
const auto *ak = static_cast<const AutoKick *>(obj);
|
||||
data.Store("ci", ak->ci->name);
|
||||
if (ak->nc)
|
||||
data.Store("ncid", ak->nc->GetId());
|
||||
else
|
||||
data.Store("mask", ak->mask);
|
||||
data.Store("reason", ak->reason);
|
||||
data.Store("creator", ak->creator);
|
||||
data.Store("addtime", ak->addtime);
|
||||
data.Store("last_used", ak->last_used);
|
||||
}
|
||||
|
||||
Serializable *AutoKick::Type::Unserialize(Serializable *obj, Serialize::Data &data) const
|
||||
{
|
||||
Anope::string sci, snc;
|
||||
uint64_t sncid = 0;
|
||||
|
||||
data["ci"] >> sci;
|
||||
data["nc"] >> snc; // Deprecated 2.0 field
|
||||
data["ncid"] >> sncid;
|
||||
|
||||
ChannelInfo *ci = ChannelInfo::Find(sci);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
AutoKick *ak;
|
||||
auto *nc = sncid ? NickCore::FindId(sncid) : NickCore::Find(snc);
|
||||
if (obj)
|
||||
{
|
||||
ak = anope_dynamic_static_cast<AutoKick *>(obj);
|
||||
data["creator"] >> ak->creator;
|
||||
data["reason"] >> ak->reason;
|
||||
ak->nc = nc;
|
||||
data["mask"] >> ak->mask;
|
||||
data["addtime"] >> ak->addtime;
|
||||
data["last_used"] >> ak->last_used;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t addtime, lastused;
|
||||
data["addtime"] >> addtime;
|
||||
data["last_used"] >> lastused;
|
||||
|
||||
Anope::string screator, sreason, smask;
|
||||
|
||||
data["creator"] >> screator;
|
||||
data["reason"] >> sreason;
|
||||
data["mask"] >> smask;
|
||||
|
||||
if (nc)
|
||||
ak = ci->AddAkick(screator, nc, sreason, addtime, lastused);
|
||||
else
|
||||
ak = ci->AddAkick(screator, smask, sreason, addtime, lastused);
|
||||
}
|
||||
|
||||
return ak;
|
||||
}
|
||||
|
||||
ChannelInfo::ChannelInfo(const Anope::string &chname)
|
||||
: Serializable(CHANNELINFO_TYPE)
|
||||
, access(CHANACCESS_TYPE)
|
||||
, akick(AUTOKICK_TYPE)
|
||||
, name(chname)
|
||||
, registered(Anope::CurTime)
|
||||
, last_used(Anope::CurTime)
|
||||
@@ -131,7 +47,6 @@ ChannelInfo::ChannelInfo(const Anope::string &chname)
|
||||
ChannelInfo::ChannelInfo(const ChannelInfo &ci)
|
||||
: Serializable(CHANNELINFO_TYPE)
|
||||
, access(CHANACCESS_TYPE)
|
||||
, akick(AUTOKICK_TYPE)
|
||||
{
|
||||
*this = ci;
|
||||
|
||||
@@ -139,7 +54,6 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci)
|
||||
++this->founder->channelcount;
|
||||
|
||||
this->access->clear();
|
||||
this->akick->clear();
|
||||
|
||||
FOREACH_MOD(OnCreateChan, (this));
|
||||
}
|
||||
@@ -174,7 +88,6 @@ ChannelInfo::~ChannelInfo()
|
||||
this->SetSuccessor(NULL);
|
||||
|
||||
this->ClearAccess();
|
||||
this->ClearAkick();
|
||||
|
||||
if (!this->memos.memos->empty())
|
||||
{
|
||||
@@ -540,68 +453,6 @@ void ChannelInfo::ClearAccess()
|
||||
delete this->GetAccess(i - 1);
|
||||
}
|
||||
|
||||
AutoKick *ChannelInfo::AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t, time_t lu)
|
||||
{
|
||||
auto *autokick = new AutoKick();
|
||||
autokick->ci = this;
|
||||
autokick->nc = akicknc;
|
||||
autokick->reason = reason;
|
||||
autokick->creator = user;
|
||||
autokick->addtime = t;
|
||||
autokick->last_used = lu;
|
||||
|
||||
this->akick->push_back(autokick);
|
||||
|
||||
akicknc->AddChannelReference(this);
|
||||
|
||||
return autokick;
|
||||
}
|
||||
|
||||
AutoKick *ChannelInfo::AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t, time_t lu)
|
||||
{
|
||||
auto *autokick = new AutoKick();
|
||||
autokick->ci = this;
|
||||
autokick->mask = mask;
|
||||
autokick->nc = NULL;
|
||||
autokick->reason = reason;
|
||||
autokick->creator = user;
|
||||
autokick->addtime = t;
|
||||
autokick->last_used = lu;
|
||||
|
||||
this->akick->push_back(autokick);
|
||||
|
||||
return autokick;
|
||||
}
|
||||
|
||||
AutoKick *ChannelInfo::GetAkick(unsigned index) const
|
||||
{
|
||||
if (this->akick->empty() || index >= this->akick->size())
|
||||
return NULL;
|
||||
|
||||
AutoKick *ak = (*this->akick)[index];
|
||||
ak->QueueUpdate();
|
||||
return ak;
|
||||
}
|
||||
|
||||
unsigned ChannelInfo::GetAkickCount() const
|
||||
{
|
||||
return this->akick->size();
|
||||
}
|
||||
|
||||
void ChannelInfo::EraseAkick(unsigned index)
|
||||
{
|
||||
if (this->akick->empty() || index >= this->akick->size())
|
||||
return;
|
||||
|
||||
delete this->GetAkick(index);
|
||||
}
|
||||
|
||||
void ChannelInfo::ClearAkick()
|
||||
{
|
||||
while (!this->akick->empty())
|
||||
delete this->akick->back();
|
||||
}
|
||||
|
||||
const Anope::map<int16_t> &ChannelInfo::GetLevelEntries()
|
||||
{
|
||||
return this->levels;
|
||||
|
||||
@@ -35,7 +35,6 @@ void Serialize::RegisterTypes()
|
||||
static BotInfo::Type bi;
|
||||
static ChannelInfo::Type ci;
|
||||
static ChanAccess::Type access;
|
||||
static AutoKick::Type akick;
|
||||
static Memo::Type memo;
|
||||
static XLine::Type xline;
|
||||
CreateTypes();
|
||||
|
||||
Reference in New Issue
Block a user