Initial commit

This commit is contained in:
Mira 2025-01-27 18:37:03 +01:00
commit 4e795fddc7
Signed by untrusted user who does not match committer: Xorog
GPG key ID: 983798ED9C3E7C36
37 changed files with 3269 additions and 0 deletions

132
Events/AfkEvents.cs Normal file
View file

@ -0,0 +1,132 @@
// Project Makoto
// Copyright (C) 2023 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
using DisCatSharp.CommandsNext;
using ProjectMakoto.Entities.Users;
namespace ProjectMakoto.Events;
internal sealed class AfkEvents : RequiresParent<SocialPlugin>
{
internal AfkEvents(SocialPlugin plugin) : base(plugin.Bot, plugin)
{
}
internal async Task MessageCreated(DiscordClient sender, MessageCreateEventArgs e)
{
if (SocialPlugin.Plugin!.HasUserObjected(e.Author.Id) || SocialPlugin.Plugin!.IsUserBanned(e.Author.Id) || SocialPlugin.Plugin!.IsGuildBanned(e.Guild?.Id ?? 0))
return;
var prefix = e.Guild!.GetGuildPrefix(this.Parent.Bot);
if (e?.Message?.Content?.StartsWith(prefix) ?? false)
foreach (var command in sender.GetCommandsNext().RegisteredCommands)
if (e.Message.Content.StartsWith($"{prefix}{command.Key}"))
return;
if (e?.Guild is null || e.Channel.IsPrivate || e.Author.IsBot)
return;
var AfkKey = ((Plugins.Social.Entities.Translations)SocialPlugin.Plugin!.Translations).Commands.Afk;
if (this.Parent.Users![e.Author.Id].AfkStatus.TimeStamp != DateTime.MinValue && this.Parent.Users![e.Author.Id].AfkStatus.LastMentionTrigger.AddSeconds(10) < DateTime.UtcNow)
{
var cache = new DateTime().ToUniversalTime().AddTicks(this.Parent.Users![e.Author.Id].AfkStatus.TimeStamp.Ticks);
this.Parent.Users![e.Author.Id].AfkStatus.Reason = "";
this.Parent.Users![e.Author.Id].AfkStatus.TimeStamp = DateTime.MinValue;
var embed = new DiscordEmbedBuilder
{
Author = new DiscordEmbedBuilder.EmbedAuthor { IconUrl = e.Guild.IconUrl, Name = $"{AfkKey.Title.Get(this.Parent.Bot.Users![e.Author.Id])} • {e.Guild.Name}" },
Color = EmbedColors.Info,
Timestamp = DateTime.UtcNow,
Description = AfkKey.Events.NoLongerAfk.Get(this.Parent.Bot.Users![e.Author.Id]).Build(true,
new TVar("User", e.Author.Mention),
new TVar("Timestamp", cache.ToTimestamp()))
};
var ExtendDelay = false;
if (this.Parent.Users![e.Author.Id].AfkStatus.MessagesAmount > 0)
{
embed.Description += $"\n\n{AfkKey.Events.NoLongerAfk.Get(this.Parent.Bot.Users![e.Author.Id]).Build(true)}\n" +
$"{string.Join("\n", this.Parent.Users![e.Author.Id].AfkStatus.Messages
.Select(x => AfkKey.Events.MessageListing
.Get(this.Parent.Bot.Users![e.Author.Id])
.Build(true,
new TVar("User", $"<@!{x.AuthorId}>"),
new TVar("Message", new EmbeddedLink($"https://discord.com/channels/{x.GuildId}/{x.ChannelId}/{x.MessageId}", AfkKey.Events.Message.Get(this.Parent.Bot.Users![e.Author.Id]))))))}";
ExtendDelay = true;
if (this.Parent.Users![e.Author.Id].AfkStatus.MessagesAmount - 5 > 0)
{
embed.Description += $"\n{AfkKey.Events.AndMore.Get(this.Parent.Bot.Users![e.Author.Id])
.Build(true, new TVar("Count", this.Parent.Users![e.Author.Id].AfkStatus.MessagesAmount - 5))}";
}
this.Parent.Users![e.Author.Id].AfkStatus.MessagesAmount = 0;
this.Parent.Users![e.Author.Id].AfkStatus.Messages = Array.Empty<MessageDetails>();
}
var message = await e.Message.RespondAsync(embed);
if (ExtendDelay)
await Task.Delay(30000);
else
await Task.Delay(10000);
_ = message.DeleteAsync();
}
if (e.MentionedUsers != null && e.MentionedUsers.Count > 0)
{
foreach (var b in e.MentionedUsers)
{
if (b.Id == e.Author.Id)
continue;
if (this.Parent.Users![b.Id].AfkStatus.TimeStamp != DateTime.MinValue)
{
if (this.Parent.Users![e.Author.Id].AfkStatus.LastMentionTrigger.AddSeconds(30) > DateTime.UtcNow)
return;
if (this.Parent.Users![b.Id].AfkStatus.Messages.Length < 5)
{
this.Parent.Users![b.Id].AfkStatus.Messages = this.Parent.Users![b.Id].AfkStatus.Messages.Add(new()
{
AuthorId = e.Author.Id,
ChannelId = e.Channel.Id,
GuildId = e.Guild.Id,
MessageId = e.Message.Id,
});
}
this.Parent.Users![b.Id].AfkStatus.MessagesAmount++;
this.Parent.Users![e.Author.Id].AfkStatus.LastMentionTrigger = DateTime.UtcNow;
var message = await e.Message.RespondAsync(new DiscordEmbedBuilder
{
Author = new DiscordEmbedBuilder.EmbedAuthor { IconUrl = e.Guild.IconUrl, Name = $"{AfkKey.Title.Get(this.Parent.Bot.Users![e.Author.Id])} • {e.Guild.Name}" },
Color = EmbedColors.Info,
Timestamp = DateTime.UtcNow,
Description = AfkKey.Events.CurrentlyAfk.Get(this.Parent.Bot.Users![e.Author.Id]).Build(true,
new TVar("User", b.Mention),
new TVar("Timestamp", this.Parent.Users![b.Id].AfkStatus.TimeStamp.ToTimestamp()),
new TVar("Reason", this.Parent.Users![b.Id].AfkStatus.Reason.FullSanitize()))
});
await Task.Delay(10000);
_ = message.DeleteAsync();
return;
}
}
}
}
}

95
Events/UserBlockEvents.cs Normal file
View file

@ -0,0 +1,95 @@
// Project Makoto
// Copyright (C) 2023 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
namespace ProjectMakoto.Events;
internal sealed class UserBlockEvents : RequiresParent<SocialPlugin>
{
internal UserBlockEvents(SocialPlugin plugin) : base(plugin.Bot, plugin)
{
}
internal readonly Permissions[] ModerationPermissions =
{
Permissions.Administrator,
Permissions.MuteMembers,
Permissions.DeafenMembers,
Permissions.ModerateMembers,
Permissions.KickMembers,
Permissions.BanMembers,
};
internal async Task VoiceStateUpdated(DiscordClient sender, VoiceStateUpdateEventArgs e)
{
if (e.After.Channel is not null && !e.Channel.IsPrivate)
{
if (e.User.IsBot)
return;
var TranslationKey = ((Plugins.Social.Entities.Translations)SocialPlugin.Plugin!.Translations).Commands;
var joiningMember = await e.User.ConvertToMember(e.Guild);
var membersWithBlocks = e.After.Channel.Users.Where(x => x.Id != joiningMember.Id).Where(x => this.Parent.Users![x.Id].BlockedUsers.Contains(e.User.Id));
var blockedMembers = e.After.Channel.Users.Where(x => x.Id != joiningMember.Id).Where(x => this.Parent.Users![x.Id].BlockedUsers.Contains(x.Id));
var memberWithBlocksHighestRole = membersWithBlocks?.MaxBy(x => GetModerationStatus(x));
var blockedMemberHighestRole = blockedMembers?.MaxBy(x => GetModerationStatus(x));
int GetModerationStatus(DiscordMember? member)
{
var i = -1;
if (member is not null && member.Permissions.HasAnyPermission(this.ModerationPermissions))
i = member.GetRoleHighestPosition();
return i;
}
if (membersWithBlocks?.IsNotNullAndNotEmpty() ?? false)
{
if (GetModerationStatus(joiningMember) > GetModerationStatus(memberWithBlocksHighestRole))
return;
_ = joiningMember.SendMessageAsync(new DiscordEmbedBuilder()
.WithDescription(TranslationKey.BlockedByVictim.Get(this.Parent.Bot.Users![joiningMember.Id])
.Build(true, new TVar("User", membersWithBlocks.First().Mention)))
.AsError(new SharedCommandContext()
{
Bot = this.Parent.Bot,
User = e.User,
Client = sender,
DbUser = this.Parent.Bot.Users![e.User.Id],
}).WithFooter());
if (e.Before?.Channel is not null)
await joiningMember.ModifyAsync(x => x.VoiceChannel = e.Before.Channel);
else
await joiningMember.DisconnectFromVoiceAsync();
}
else if (this.Parent.Users![e.User.Id].BlockedUsers.Any(blockedId => e.Channel.Users.Any(user => user.Id == blockedId)))
{
if (GetModerationStatus(joiningMember) > GetModerationStatus(blockedMemberHighestRole))
return;
_ = joiningMember.SendMessageAsync(new DiscordEmbedBuilder()
.WithDescription(TranslationKey.BlockedVictim.Get(joiningMember.GetDbEntry(this.Parent.Bot))
.Build(true, new TVar("User", $"<@{this.Parent.Users![e.User.Id].BlockedUsers.First(blockedId => e.Channel.Users.Any(user => user.Id == blockedId))}>")))
.AsError(new SharedCommandContext()
{
Bot = this.Parent.Bot,
User = e.User,
Client = sender,
DbUser = this.Parent.Bot.Users![e.User.Id],
}).WithFooter());
if (e.Before?.Channel is not null)
await joiningMember.ModifyAsync(x => x.VoiceChannel = e.Before.Channel);
else
await joiningMember.DisconnectFromVoiceAsync();
}
}
}
}