.warn command, needs testing

This commit is contained in:
Kwoth 2017-03-30 03:51:54 +02:00
parent ca05b14f3e
commit 2d73f4bdfd
18 changed files with 2293 additions and 108 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class warningcommands : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "WarningsInitialized",
table: "GuildConfigs",
nullable: false,
defaultValue: false);
migrationBuilder.CreateTable(
name: "Warnings",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(nullable: true),
Forgiven = table.Column<bool>(nullable: false),
ForgivenBy = table.Column<string>(nullable: true),
GuildId = table.Column<ulong>(nullable: false),
Moderator = table.Column<string>(nullable: true),
Reason = table.Column<string>(nullable: true),
UserId = table.Column<ulong>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Warnings", x => x.Id);
});
migrationBuilder.CreateTable(
name: "WarningPunishment",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Count = table.Column<int>(nullable: false),
DateAdded = table.Column<DateTime>(nullable: true),
GuildConfigId = table.Column<int>(nullable: true),
Punishment = table.Column<int>(nullable: false),
Time = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_WarningPunishment", x => x.Id);
table.ForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_WarningPunishment_GuildConfigId",
table: "WarningPunishment",
column: "GuildConfigId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Warnings");
migrationBuilder.DropTable(
name: "WarningPunishment");
migrationBuilder.DropColumn(
name: "WarningsInitialized",
table: "GuildConfigs");
}
}
}

View File

@ -559,6 +559,8 @@ namespace NadekoBot.Migrations
b.Property<bool>("VoicePlusTextEnabled"); b.Property<bool>("VoicePlusTextEnabled");
b.Property<bool>("WarningsInitialized");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("GuildId") b.HasIndex("GuildId")
@ -1060,6 +1062,52 @@ namespace NadekoBot.Migrations
b.ToTable("WaifuUpdates"); b.ToTable("WaifuUpdates");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime?>("DateAdded");
b.Property<bool>("Forgiven");
b.Property<string>("ForgivenBy");
b.Property<ulong>("GuildId");
b.Property<string>("Moderator");
b.Property<string>("Reason");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.ToTable("Warnings");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Count");
b.Property<DateTime?>("DateAdded");
b.Property<int?>("GuildConfigId");
b.Property<int>("Punishment");
b.Property<int>("Time");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("WarningPunishment");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
{ {
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
@ -1285,6 +1333,13 @@ namespace NadekoBot.Migrations
.HasForeignKey("UserId") .HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId");
});
} }
} }
} }

View File

@ -218,101 +218,6 @@ namespace NadekoBot.Modules.Administration
} }
} }
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
[RequireBotPermission(GuildPermission.BanMembers)]
public async Task Ban(IGuildUser user, [Remainder] string msg = null)
{
if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()))
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg));
}
catch
{
// ignored
}
}
await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle("⛔️ " + GetText("banned_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.KickMembers)]
[RequireUserPermission(GuildPermission.ManageMessages)]
[RequireBotPermission(GuildPermission.BanMembers)]
public async Task Softban(IGuildUser user, [Remainder] string msg = null)
{
if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg));
}
catch
{
// ignored
}
}
await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false);
try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle("☣ " + GetText("sb_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.KickMembers)]
[RequireBotPermission(GuildPermission.KickMembers)]
public async Task Kick(IGuildUser user, [Remainder] string msg = null)
{
if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg));
}
catch { }
}
await user.KickAsync().ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("kicked_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.DeafenMembers)] [RequireUserPermission(GuildPermission.DeafenMembers)]

View File

@ -16,25 +16,26 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class LocalizationCommands : NadekoSubmodule public class LocalizationCommands : NadekoSubmodule
{ {
//Română, România
private ImmutableDictionary<string, string> supportedLocales { get; } = new Dictionary<string, string>() private ImmutableDictionary<string, string> supportedLocales { get; } = new Dictionary<string, string>()
{ {
{"zh-TW", "Chinese (Traditional), China" }, {"zh-TW", "繁體中文, 台灣" },
{"zh-CN", "Chinese (Simplified), China"}, {"zh-CN", "简体中文, 中华人民共和国"},
{"nl-NL", "Dutch, Netherlands"}, {"nl-NL", "Dutch, Netherlands"},
{"en-US", "English, United States"}, {"en-US", "English, United States"},
{"fr-FR", "French, France"}, {"fr-FR", "Français, France"},
{"de-DE", "German, Germany"}, {"de-DE", "German, Germany"},
{"he-IL", "Hebrew, Israel" }, {"he-IL", "Hebrew, Israel" },
{"it-IT", "Italian, Italy" }, {"it-IT", "Italiano, Italia" },
//{"ja-JP", "Japanese, Japan"}, //{"ja-JP", "Japanese, Japan"},
{"ko-KR", "Korean, Korea" }, {"ko-KR", "Korean, South Korea" },
{"nb-NO", "Norwegian (bokmål), Norway"}, {"nb-NO", "Norwegian (bokmål), Norway"},
{"pl-PL", "Polish, Poland" }, {"pl-PL", "Polski, Polska" },
{"pt-BR", "Portuguese, Brazil"}, {"pt-BR", "Português Brasileiro, Brasil"},
{"ru-RU", "Russian, Russia"}, {"ru-RU", "Russian, Russia"},
{"sr-Cyrl-RS", "Serbian, Serbia - Cyrillic"}, {"sr-Cyrl-RS", "Српски, Србија"},
{"es-ES", "Spanish, Spain"}, {"es-ES", "Español, España"},
{"sv-SE", "Swedish, Sweden"}, {"sv-SE", "Svenska, Sverige"},
{"tr-TR", "Turkish, Turkey" } {"tr-TR", "Turkish, Turkey" }
}.ToImmutableDictionary(); }.ToImmutableDictionary();

View File

@ -0,0 +1,358 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration
{
public partial class Administration
{
[Group]
public class UserPunishCommands : NadekoSubmodule
{
private async Task InternalWarn(IGuild guild, ulong userId, string modName, string reason)
{
if (string.IsNullOrWhiteSpace(reason))
reason = "-";
var guildId = guild.Id;
var warn = new Warning()
{
UserId = userId,
GuildId = guildId,
Forgiven = false,
Reason = reason,
Moderator = modName,
};
int warnings;
List<WarningPunishment> ps;
using (var uow = DbHandler.UnitOfWork())
{
ps = uow.GuildConfigs.For(guildId, set => set.Include(x => x.WarnPunishments))
.WarnPunishments;
uow.Warnings.Add(warn);
warnings = uow.Warnings
.For(guildId, userId)
.Where(w => !w.Forgiven && w.UserId == userId)
.Count();
uow.Complete();
}
var p = ps.FirstOrDefault(x => x.Count == warnings);
if (p != null)
{
var user = await guild.GetUserAsync(userId);
if (user == null)
return;
switch (p.Punishment)
{
case PunishmentAction.Mute:
await MuteCommands.TimedMute(user, TimeSpan.FromMinutes(p.Time));
break;
case PunishmentAction.Kick:
await user.KickAsync().ConfigureAwait(false);
break;
case PunishmentAction.Ban:
await guild.AddBanAsync(user).ConfigureAwait(false);
break;
default:
break;
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public async Task Warn(IGuildUser user, [Remainder] string reason = null)
{
try
{
await (await user.CreateDMChannelAsync()).EmbedAsync(new EmbedBuilder().WithErrorColor()
.WithDescription(GetText("warned_on", Context.Guild.ToString()))
.AddField(efb => efb.WithName(GetText("moderator")).WithValue(Context.User.ToString()))
.AddField(efb => efb.WithName(GetText("reason")).WithValue(reason ?? "-")))
.ConfigureAwait(false);
}
catch { }
await InternalWarn(Context.Guild, user.Id, Context.User.ToString(), reason).ConfigureAwait(false);
await ReplyConfirmLocalized("user_warned", Format.Bold(user.ToString())).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public Task Warnlog(int page, IGuildUser user)
=> Warnlog(page, user.Id);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public Task Warnlog(IGuildUser user)
=> Warnlog(user.Id);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public Task Warnlog(int page, ulong userId)
=> InternalWarnlog(userId, page - 1);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public Task Warnlog(ulong userId)
=> InternalWarnlog(userId, 0);
private async Task InternalWarnlog(ulong userId, int page)
{
if (page < 0)
return;
Warning[] warnings;
using (var uow = DbHandler.UnitOfWork())
{
warnings = uow.Warnings.For(Context.Guild.Id, userId);
}
warnings = warnings.Skip(page * 9)
.Take(9)
.ToArray();
var embed = new EmbedBuilder().WithOkColor()
.WithTitle(GetText("warnlog_for", (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString()))
.WithFooter(efb => efb.WithText(GetText("page", page + 1)));
if (!warnings.Any())
{
embed.WithDescription(GetText("warnings_none"));
}
else
{
foreach (var w in warnings)
{
var name = GetText("warned_on_by", w.DateAdded.Value.ToString("dd.MM.yyy"), w.DateAdded.Value.ToString("HH:mm"), w.Moderator);
if (w.Forgiven)
name = Format.Strikethrough(name) + GetText("warn_cleared_by", w.ForgivenBy);
embed.AddField(x => x
.WithName(name)
.WithValue(w.Reason));
}
}
await Context.Channel.EmbedAsync(embed);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public Task Warnclear(IGuildUser user)
=> Warnclear(user.Id);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public async Task Warnclear(ulong userId)
{
using (var uow = DbHandler.UnitOfWork())
{
await uow.Warnings.ForgiveAll(Context.Guild.Id, userId, Context.User.ToString()).ConfigureAwait(false);
uow.Complete();
}
await ReplyConfirmLocalized("warnings_cleared",
(Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString()).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public async Task WarnPunish(int number, PunishmentAction punish, int time = 0)
{
if (punish != PunishmentAction.Mute && time != 0)
return;
if (number <= 0)
return;
using (var uow = DbHandler.UnitOfWork())
{
var ps = uow.GuildConfigs.For(Context.Guild.Id).WarnPunishments;
var p = ps.FirstOrDefault(x => x.Count == number);
if (p == null)
{
ps.Add(new WarningPunishment()
{
Count = number,
Punishment = punish,
Time = time,
});
}
else
{
p.Count = number;
p.Punishment = punish;
p.Time = time;
uow._context.Update(p);
}
uow.Complete();
}
await ReplyConfirmLocalized("warn_punish_set",
Format.Bold(punish.ToString()),
Format.Bold(number.ToString())).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
public async Task WarnPunish(int number)
{
if (number <= 0)
return;
using (var uow = DbHandler.UnitOfWork())
{
var ps = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
var p = ps.FirstOrDefault(x => x.Count == number);
if (p != null)
{
uow._context.Remove(p);
uow.Complete();
}
}
await ReplyConfirmLocalized("warn_punish_rem",
Format.Bold(number.ToString())).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task WarnPunishList()
{
WarningPunishment[] ps;
using (var uow = DbHandler.UnitOfWork())
{
ps = uow.GuildConfigs.For(Context.Guild.Id, gc => gc.Include(x => x.WarnPunishments))
.WarnPunishments
.OrderBy(x => x.Count)
.ToArray();
}
await Context.Channel.SendConfirmAsync(
GetText("warn_punish_list"),
string.Join("\n", ps.Select(x => $"{x.Count} -> {x.Punishment}"))).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.BanMembers)]
[RequireBotPermission(GuildPermission.BanMembers)]
public async Task Ban(IGuildUser user, [Remainder] string msg = null)
{
if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()))
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg));
}
catch
{
// ignored
}
}
await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle("⛔️ " + GetText("banned_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.KickMembers)]
[RequireUserPermission(GuildPermission.ManageMessages)]
[RequireBotPermission(GuildPermission.BanMembers)]
public async Task Softban(IGuildUser user, [Remainder] string msg = null)
{
if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg));
}
catch
{
// ignored
}
}
await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false);
try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); }
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle("☣ " + GetText("sb_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.KickMembers)]
[RequireBotPermission(GuildPermission.KickMembers)]
public async Task Kick(IGuildUser user, [Remainder] string msg = null)
{
if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())
{
await ReplyErrorLocalized("hierarchy").ConfigureAwait(false);
return;
}
if (!string.IsNullOrWhiteSpace(msg))
{
try
{
await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg));
}
catch { }
}
await user.KickAsync().ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("kicked_user"))
.AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
}
}
}
}

View File

@ -9104,6 +9104,141 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to warn.
/// </summary>
public static string warn_cmd {
get {
return ResourceManager.GetString("warn_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warns a user..
/// </summary>
public static string warn_desc {
get {
return ResourceManager.GetString("warn_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}warn @b1nzy`.
/// </summary>
public static string warn_usage {
get {
return ResourceManager.GetString("warn_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to warnclear warnc.
/// </summary>
public static string warnclear_cmd {
get {
return ResourceManager.GetString("warnclear_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clears all warnings from a certain user..
/// </summary>
public static string warnclear_desc {
get {
return ResourceManager.GetString("warnclear_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}warnclear @PoorDude`.
/// </summary>
public static string warnclear_usage {
get {
return ResourceManager.GetString("warnclear_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to warnlog.
/// </summary>
public static string warnlog_cmd {
get {
return ResourceManager.GetString("warnlog_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to See a list of warnings of a certain user..
/// </summary>
public static string warnlog_desc {
get {
return ResourceManager.GetString("warnlog_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}warnlog @b1nzy`.
/// </summary>
public static string warnlog_usage {
get {
return ResourceManager.GetString("warnlog_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to warnpunish warnp.
/// </summary>
public static string warnpunish_cmd {
get {
return ResourceManager.GetString("warnpunish_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sets a punishment for a certain number of warnings. Provide no punishment to remove..
/// </summary>
public static string warnpunish_desc {
get {
return ResourceManager.GetString("warnpunish_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}warnpunish 5 Ban` or `{0}warnpunish 3`.
/// </summary>
public static string warnpunish_usage {
get {
return ResourceManager.GetString("warnpunish_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to warnpunishlist warnpl.
/// </summary>
public static string warnpunishlist_cmd {
get {
return ResourceManager.GetString("warnpunishlist_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lists punishments for warnings..
/// </summary>
public static string warnpunishlist_desc {
get {
return ResourceManager.GetString("warnpunishlist_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}warnpunishlist`.
/// </summary>
public static string warnpunishlist_usage {
get {
return ResourceManager.GetString("warnpunishlist_usage", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to weather we. /// Looks up a localized string similar to weather we.
/// </summary> /// </summary>

View File

@ -3222,4 +3222,49 @@
<data name="alias_usage" xml:space="preserve"> <data name="alias_usage" xml:space="preserve">
<value>`{0}alias allin $bf 100 h` or `{0}alias "linux thingy" &gt;loonix Spyware Windows`</value> <value>`{0}alias allin $bf 100 h` or `{0}alias "linux thingy" &gt;loonix Spyware Windows`</value>
</data> </data>
<data name="warnlog_cmd" xml:space="preserve">
<value>warnlog</value>
</data>
<data name="warnlog_desc" xml:space="preserve">
<value>See a list of warnings of a certain user.</value>
</data>
<data name="warnlog_usage" xml:space="preserve">
<value>`{0}warnlog @b1nzy`</value>
</data>
<data name="warn_cmd" xml:space="preserve">
<value>warn</value>
</data>
<data name="warn_desc" xml:space="preserve">
<value>Warns a user.</value>
</data>
<data name="warn_usage" xml:space="preserve">
<value>`{0}warn @b1nzy`</value>
</data>
<data name="warnclear_cmd" xml:space="preserve">
<value>warnclear warnc</value>
</data>
<data name="warnclear_desc" xml:space="preserve">
<value>Clears all warnings from a certain user.</value>
</data>
<data name="warnclear_usage" xml:space="preserve">
<value>`{0}warnclear @PoorDude`</value>
</data>
<data name="warnpunishlist_cmd" xml:space="preserve">
<value>warnpunishlist warnpl</value>
</data>
<data name="warnpunishlist_desc" xml:space="preserve">
<value>Lists punishments for warnings.</value>
</data>
<data name="warnpunishlist_usage" xml:space="preserve">
<value>`{0}warnpunishlist`</value>
</data>
<data name="warnpunish_cmd" xml:space="preserve">
<value>warnpunish warnp</value>
</data>
<data name="warnpunish_desc" xml:space="preserve">
<value>Sets a punishment for a certain number of warnings. Provide no punishment to remove.</value>
</data>
<data name="warnpunish_usage" xml:space="preserve">
<value>`{0}warnpunish 5 Ban` or `{0}warnpunish 3`</value>
</data>
</root> </root>

View File

@ -736,6 +736,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Moderator.
/// </summary>
public static string administration_moderator {
get {
return ResourceManager.GetString("administration_moderator", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to {0} moved from {1} to {2}. /// Looks up a localized string similar to {0} moved from {1} to {2}.
/// </summary> /// </summary>
@ -907,6 +916,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to page {0}.
/// </summary>
public static string administration_page {
get {
return ResourceManager.GetString("administration_page", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Error. Most likely I don&apos;t have sufficient permissions.. /// Looks up a localized string similar to Error. Most likely I don&apos;t have sufficient permissions..
/// </summary> /// </summary>
@ -1060,6 +1078,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Reason.
/// </summary>
public static string administration_reason {
get {
return ResourceManager.GetString("administration_reason", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Successfully removed role {0} from user {1}. /// Looks up a localized string similar to Successfully removed role {0} from user {1}.
/// </summary> /// </summary>
@ -1648,6 +1675,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to User {0} has been warned..
/// </summary>
public static string administration_user_warned {
get {
return ResourceManager.GetString("administration_user_warned", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Username. /// Looks up a localized string similar to Username.
/// </summary> /// </summary>
@ -1765,6 +1801,87 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to cleared by {0}.
/// </summary>
public static string administration_warn_cleared_by {
get {
return ResourceManager.GetString("administration_warn_cleared_by", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warning punishment list.
/// </summary>
public static string administration_warn_punish_list {
get {
return ResourceManager.GetString("administration_warn_punish_list", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Having {0} warnings will no longer trigger a punishment..
/// </summary>
public static string administration_warn_punish_rem {
get {
return ResourceManager.GetString("administration_warn_punish_rem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to I will apply {0} punishment to users with {1} warnings..
/// </summary>
public static string administration_warn_punish_set {
get {
return ResourceManager.GetString("administration_warn_punish_set", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warned on {0} server.
/// </summary>
public static string administration_warned_on {
get {
return ResourceManager.GetString("administration_warned_on", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On {0} at {1} by {2}.
/// </summary>
public static string administration_warned_on_by {
get {
return ResourceManager.GetString("administration_warned_on_by", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to All warnings have been cleared for {0}..
/// </summary>
public static string administration_warnings_cleared {
get {
return ResourceManager.GetString("administration_warnings_cleared", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No warning on this page..
/// </summary>
public static string administration_warnings_none {
get {
return ResourceManager.GetString("administration_warnings_none", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warnlog for {0}.
/// </summary>
public static string administration_warnlog_for {
get {
return ResourceManager.GetString("administration_warnlog_for", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to User {0} from text chat. /// Looks up a localized string similar to User {0} from text chat.
/// </summary> /// </summary>

View File

@ -2278,4 +2278,43 @@ Owner ID: {2}</value>
<data name="searches_compet_playtime" xml:space="preserve"> <data name="searches_compet_playtime" xml:space="preserve">
<value>Competitive playtime</value> <value>Competitive playtime</value>
</data> </data>
<data name="administration_moderator" xml:space="preserve">
<value>Moderator</value>
</data>
<data name="administration_page" xml:space="preserve">
<value>page {0}</value>
</data>
<data name="administration_reason" xml:space="preserve">
<value>Reason</value>
</data>
<data name="administration_user_warned" xml:space="preserve">
<value>User {0} has been warned.</value>
</data>
<data name="administration_warned_on" xml:space="preserve">
<value>Warned on {0} server</value>
</data>
<data name="administration_warned_on_by" xml:space="preserve">
<value>On {0} at {1} by {2}</value>
</data>
<data name="administration_warnings_cleared" xml:space="preserve">
<value>All warnings have been cleared for {0}.</value>
</data>
<data name="administration_warnings_none" xml:space="preserve">
<value>No warning on this page.</value>
</data>
<data name="administration_warnlog_for" xml:space="preserve">
<value>Warnlog for {0}</value>
</data>
<data name="administration_warn_cleared_by" xml:space="preserve">
<value>cleared by {0}</value>
</data>
<data name="administration_warn_punish_list" xml:space="preserve">
<value>Warning punishment list</value>
</data>
<data name="administration_warn_punish_rem" xml:space="preserve">
<value>Having {0} warnings will no longer trigger a punishment.</value>
</data>
<data name="administration_warn_punish_set" xml:space="preserve">
<value>I will apply {0} punishment to users with {1} warnings.</value>
</data>
</root> </root>

View File

@ -23,6 +23,7 @@ namespace NadekoBot.Services.Database
IPokeGameRepository PokeGame { get; } IPokeGameRepository PokeGame { get; }
IWaifuRepository Waifus { get; } IWaifuRepository Waifus { get; }
IDiscordUserRepository DiscordUsers { get; } IDiscordUserRepository DiscordUsers { get; }
IWarningsRepository Warnings { get; }
int Complete(); int Complete();
Task<int> CompleteAsync(); Task<int> CompleteAsync();

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static NadekoBot.Modules.Administration.Administration;
namespace NadekoBot.Services.Database.Models namespace NadekoBot.Services.Database.Models
{ {
@ -72,10 +71,19 @@ namespace NadekoBot.Services.Database.Models
public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new HashSet<UnmuteTimer>(); public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new HashSet<UnmuteTimer>();
public HashSet<VcRoleInfo> VcRoleInfos { get; set; } public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
public HashSet<CommandAlias> CommandAliases { get; set; } = new HashSet<CommandAlias>(); public HashSet<CommandAlias> CommandAliases { get; set; } = new HashSet<CommandAlias>();
public List<WarningPunishment> WarnPunishments { get; set; } = new List<WarningPunishment>();
public bool WarningsInitialized { get; set; }
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
} }
public class WarningPunishment : DbEntity
{
public int Count { get; set; }
public PunishmentAction Punishment { get; set; }
public int Time { get; set; }
}
public class CommandAlias : DbEntity public class CommandAlias : DbEntity
{ {
public string Trigger { get; set; } public string Trigger { get; set; }

View File

@ -0,0 +1,12 @@
namespace NadekoBot.Services.Database.Models
{
public class Warning : DbEntity
{
public ulong GuildId { get; set; }
public ulong UserId { get; set; }
public string Reason { get; set; }
public bool Forgiven { get; set; }
public string ForgivenBy { get; set; }
public string Moderator { get; set; }
}
}

View File

@ -40,6 +40,7 @@ namespace NadekoBot.Services.Database
public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; } public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
public DbSet<UserPokeTypes> PokeGame { get; set; } public DbSet<UserPokeTypes> PokeGame { get; set; }
public DbSet<WaifuUpdate> WaifuUpdates { get; set; } public DbSet<WaifuUpdate> WaifuUpdates { get; set; }
public DbSet<Warning> Warnings { get; set; }
//logging //logging
public DbSet<LogSetting> LogSettings { get; set; } public DbSet<LogSetting> LogSettings { get; set; }
@ -272,6 +273,10 @@ namespace NadekoBot.Services.Database
du.HasAlternateKey(w => w.UserId); du.HasAlternateKey(w => w.UserId);
#endregion #endregion
#region Warnings
var warn = modelBuilder.Entity<Warning>();
#endregion
} }
} }
} }

View File

@ -0,0 +1,11 @@
using NadekoBot.Services.Database.Models;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Repositories
{
public interface IWarningsRepository : IRepository<Warning>
{
Warning[] For(ulong guildId, ulong userId);
Task ForgiveAll(ulong guildId, ulong userId, string mod);
}
}

View File

@ -12,6 +12,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl
{ {
} }
private List<WarningPunishment> DefaultWarnPunishments =>
new List<WarningPunishment>() {
new WarningPunishment() {
Count = 3,
Punishment = PunishmentAction.Kick
},
new WarningPunishment() {
Count = 5,
Punishment = PunishmentAction.Ban
}
};
public IEnumerable<GuildConfig> GetAllGuildConfigs() => public IEnumerable<GuildConfig> GetAllGuildConfigs() =>
_set.Include(gc => gc.LogSetting) _set.Include(gc => gc.LogSetting)
.ThenInclude(ls => ls.IgnoredChannels) .ThenInclude(ls => ls.IgnoredChannels)
@ -64,10 +76,19 @@ namespace NadekoBot.Services.Database.Repositories.Impl
_set.Add((config = new GuildConfig _set.Add((config = new GuildConfig
{ {
GuildId = guildId, GuildId = guildId,
Permissions = Permissionv2.GetDefaultPermlist Permissions = Permissionv2.GetDefaultPermlist,
WarningsInitialized = true,
WarnPunishments = DefaultWarnPunishments,
})); }));
_context.SaveChanges(); _context.SaveChanges();
} }
if (!config.WarningsInitialized)
{
config.WarningsInitialized = true;
config.WarnPunishments = DefaultWarnPunishments;
}
return config; return config;
} }
@ -82,10 +103,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl
_set.Add((config = new GuildConfig _set.Add((config = new GuildConfig
{ {
GuildId = guildId, GuildId = guildId,
Permissions = Permissionv2.GetDefaultPermlist Permissions = Permissionv2.GetDefaultPermlist,
WarningsInitialized = true,
WarnPunishments = DefaultWarnPunishments,
})); }));
_context.SaveChanges(); _context.SaveChanges();
} }
if (!config.WarningsInitialized)
{
config.WarningsInitialized = true;
config.WarnPunishments = DefaultWarnPunishments;
}
return config; return config;
} }

View File

@ -0,0 +1,37 @@
using NadekoBot.Services.Database.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Repositories.Impl
{
public class WarningsRepository : Repository<Warning>, IWarningsRepository
{
public WarningsRepository(DbContext context) : base(context)
{
}
public Warning[] For(ulong guildId, ulong userId)
{
var query = _set.Where(x => x.GuildId == guildId && x.UserId == userId)
.OrderByDescending(x => x.DateAdded);
return query.ToArray();
}
public async Task ForgiveAll(ulong guildId, ulong userId, string mod)
{
await _set.Where(x => x.GuildId == guildId && x.UserId == userId)
.ForEachAsync(x =>
{
if (x.Forgiven != true)
{
x.Forgiven = true;
x.ForgivenBy = mod;
}
})
.ConfigureAwait(false);
}
}
}

View File

@ -54,6 +54,9 @@ namespace NadekoBot.Services.Database
private IDiscordUserRepository _discordUsers; private IDiscordUserRepository _discordUsers;
public IDiscordUserRepository DiscordUsers => _discordUsers ?? (_discordUsers = new DiscordUserRepository(_context)); public IDiscordUserRepository DiscordUsers => _discordUsers ?? (_discordUsers = new DiscordUserRepository(_context));
private IWarningsRepository _warnings;
public IWarningsRepository Warnings => _warnings ?? (_warnings = new WarningsRepository(_context));
public UnitOfWork(NadekoContext context) public UnitOfWork(NadekoContext context)
{ {
_context = context; _context = context;