Add anti-raid and anti-nuke protection
Join Gate (account age, avatar, advertising and username filters, bot checks), raid detection with invite pausing, anti-nuke quarantine of admins who mass delete, manual and automatic lockdowns, a decaying heat score against spam, role and channel snapshots with restore, and alert DMs to the owner and trusted users. Everything that weakens protection is limited to the owner and the trusted list. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
d294b3463b
commit
3f87e68a2c
26 files changed
+6022
No files matched your search
@@ -10,6 +10,7 @@ import (
|
||||
"velox-bot/internal/events"
|
||||
"velox-bot/internal/music"
|
||||
"velox-bot/internal/tickets"
|
||||
"velox-bot/internal/security"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
@@ -84,6 +85,24 @@ func (b *Bot) Start() error {
|
||||
}()
|
||||
}
|
||||
|
||||
if eng := security.Start(b.Session, b.Session.State.User.ID); eng != nil {
|
||||
// Moderators are exempt from heat; their permissions come from the
|
||||
// gateway cache so a message never costs an API call.
|
||||
eng.ChannelPerms = b.Session.State.UserChannelPermissions
|
||||
eng.ResumeRaids(context.Background())
|
||||
go eng.WatchRaids(context.Background(), 30*time.Second)
|
||||
go eng.WatchSnapshots(context.Background())
|
||||
go func() {
|
||||
// Reconnect if the database connection drops, instead of
|
||||
// silently ignoring the dashboard from then on.
|
||||
for {
|
||||
err := eng.StartCommandListener(context.Background(), b.DBHost)
|
||||
log.Printf("security: command listener stopped: %v (retrying in 10s)", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
b.registeredCommands = make([]*discordgo.ApplicationCommand, len(b.Commands))
|
||||
for _, cmd := range b.Commands {
|
||||
created, err := b.Session.ApplicationCommandCreate(b.AppID, b.GuildID, cmd)
|
||||
@@ -97,12 +116,24 @@ func (b *Bot) Start() error {
|
||||
b.Session.AddHandler(commands.HandleInteraction)
|
||||
|
||||
b.Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
if eng := security.Default(); eng != nil {
|
||||
eng.OnMessage(context.Background(), m)
|
||||
}
|
||||
events.HandleMessageCreate(s, m, b.Services)
|
||||
})
|
||||
|
||||
b.Session.AddHandler(func(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
|
||||
events.HandleBotAddedOnGuild(s, m, b.Services)
|
||||
|
||||
// Security runs first: someone it removes (join lock, Join Gate,
|
||||
// raid) gets no welcome message or default role.
|
||||
if eng := security.Default(); eng != nil && m != nil && m.Member != nil {
|
||||
if eng.OnMemberJoin(context.Background(), m.GuildID, m.Member) {
|
||||
events.HandleGuildMemberAddLog(s, m, b.Services)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore bot members for welcome/log onboarding of normal users.
|
||||
if m != nil && m.Member != nil && m.User != nil && m.User.Bot {
|
||||
return
|
||||
@@ -112,6 +143,14 @@ func (b *Bot) Start() error {
|
||||
events.HandleGuildMemberAddLog(s, m, b.Services)
|
||||
})
|
||||
|
||||
// Anti-nuke and unauthorized bot additions read the audit log as it
|
||||
// happens (needs the Guild Moderation intent and View Audit Log).
|
||||
b.Session.AddHandler(func(s *discordgo.Session, ev *discordgo.GuildAuditLogEntryCreate) {
|
||||
if eng := security.Default(); eng != nil && ev.AuditLogEntry != nil {
|
||||
eng.OnAuditLogEntry(context.Background(), ev.GuildID, ev.AuditLogEntry)
|
||||
}
|
||||
})
|
||||
|
||||
b.Session.AddHandler(func(s *discordgo.Session, m *discordgo.GuildMemberRemove) {
|
||||
events.HandleGuildMemberRemoveLog(s, m, b.Services)
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user