split warn punishments into a separate table
Added warn endpoints Reminders should now be able to ping everyone if the user who created the reminder has that permission
This commit is contained in:
parent
aca7ace527
commit
17d4d2a925
27 changed files with 7434 additions and 214 deletions
|
@ -35,7 +35,7 @@ enum GrpcGreetType {
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateGreetReply {
|
message UpdateGreetReply {
|
||||||
GrpcGreetSettings settings = 1;
|
bool Success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TestGreetRequest {
|
message TestGreetRequest {
|
||||||
|
|
|
@ -11,6 +11,7 @@ service GrpcOther {
|
||||||
rpc BotOnGuild(BotOnGuildRequest) returns (BotOnGuildReply);
|
rpc BotOnGuild(BotOnGuildRequest) returns (BotOnGuildReply);
|
||||||
rpc GetGuilds(google.protobuf.Empty) returns (GetGuildsReply);
|
rpc GetGuilds(google.protobuf.Empty) returns (GetGuildsReply);
|
||||||
rpc GetTextChannels(GetTextChannelsRequest) returns (GetTextChannelsReply);
|
rpc GetTextChannels(GetTextChannelsRequest) returns (GetTextChannelsReply);
|
||||||
|
rpc GetRoles(GetRolesRequest) returns (GetRolesReply);
|
||||||
|
|
||||||
rpc GetCurrencyLb(GetLbRequest) returns (CurrencyLbReply);
|
rpc GetCurrencyLb(GetLbRequest) returns (CurrencyLbReply);
|
||||||
rpc GetXpLb(GetLbRequest) returns (XpLbReply);
|
rpc GetXpLb(GetLbRequest) returns (XpLbReply);
|
||||||
|
@ -20,6 +21,14 @@ service GrpcOther {
|
||||||
rpc GetServerInfo(ServerInfoRequest) returns (GetServerInfoReply);
|
rpc GetServerInfo(ServerInfoRequest) returns (GetServerInfoReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetRolesRequest {
|
||||||
|
uint64 guildId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRolesReply {
|
||||||
|
repeated RoleReply roles = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message BotOnGuildRequest {
|
message BotOnGuildRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,17 @@ package warn;
|
||||||
|
|
||||||
service GrpcWarn {
|
service GrpcWarn {
|
||||||
rpc GetWarnSettings (WarnSettingsRequest) returns (WarnSettingsReply);
|
rpc GetWarnSettings (WarnSettingsRequest) returns (WarnSettingsReply);
|
||||||
|
|
||||||
|
rpc SetWarnExpiry(SetWarnExpiryRequest) returns (SetWarnExpiryReply);
|
||||||
rpc AddWarnp (AddWarnpRequest) returns (AddWarnpReply);
|
rpc AddWarnp (AddWarnpRequest) returns (AddWarnpReply);
|
||||||
rpc DeleteWarnp (DeleteWarnpRequest) returns (DeleteWarnpReply);
|
rpc DeleteWarnp (DeleteWarnpRequest) returns (DeleteWarnpReply);
|
||||||
|
|
||||||
|
rpc GetLatestWarnings(GetLatestWarningsRequest) returns (GetLatestWarningsReply);
|
||||||
rpc GetUserWarnings(GetUserWarningsRequest) returns (GetUserWarningsReply);
|
rpc GetUserWarnings(GetUserWarningsRequest) returns (GetUserWarningsReply);
|
||||||
rpc ClearWarning(ClearWarningRequest) returns (ClearWarningReply);
|
|
||||||
rpc SetWarnExpiry(SetWarnExpiryRequest) returns (SetWarnExpiryReply);
|
rpc ForgiveWarning(ForgiveWarningRequest) returns (ForgiveWarningReply);
|
||||||
|
rpc DeleteWarning(ForgiveWarningRequest) returns (ForgiveWarningReply);
|
||||||
|
|
||||||
}
|
}
|
||||||
message WarnSettingsRequest {
|
message WarnSettingsRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
|
@ -19,12 +25,14 @@ message WarnSettingsRequest {
|
||||||
message WarnPunishment {
|
message WarnPunishment {
|
||||||
int32 threshold = 1;
|
int32 threshold = 1;
|
||||||
string action = 2;
|
string action = 2;
|
||||||
int64 duration = 3;
|
int32 duration = 3;
|
||||||
|
string role = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message WarnSettingsReply {
|
message WarnSettingsReply {
|
||||||
repeated WarnPunishment punishments = 1;
|
repeated WarnPunishment punishments = 1;
|
||||||
int32 expiryDays = 2;
|
int32 expiryDays = 2;
|
||||||
|
bool deleteOnExpire = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddWarnpRequest {
|
message AddWarnpRequest {
|
||||||
|
@ -38,7 +46,7 @@ message AddWarnpReply {
|
||||||
|
|
||||||
message DeleteWarnpRequest {
|
message DeleteWarnpRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
int32 warnpIndex = 2;
|
int32 threshold = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteWarnpReply {
|
message DeleteWarnpReply {
|
||||||
|
@ -47,37 +55,53 @@ message DeleteWarnpReply {
|
||||||
|
|
||||||
message GetUserWarningsRequest {
|
message GetUserWarningsRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
uint64 user_id = 2;
|
string user = 2;
|
||||||
|
int32 page = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetUserWarningsReply {
|
message GetUserWarningsReply {
|
||||||
repeated Warning warnings = 1;
|
repeated Warning warnings = 1;
|
||||||
|
int32 totalCount = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Warning {
|
message Warning {
|
||||||
int32 id = 1;
|
string id = 1;
|
||||||
string reason = 2;
|
string reason = 2;
|
||||||
int64 timestamp = 3;
|
int64 timestamp = 3;
|
||||||
int64 expiry_timestamp = 4;
|
int64 weight = 4;
|
||||||
bool cleared = 5;
|
bool forgiven = 5;
|
||||||
string clearedBy = 6;
|
string forgivenBy = 6;
|
||||||
|
string user = 7;
|
||||||
|
uint64 userId = 8;
|
||||||
|
string moderator = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ClearWarningRequest {
|
message ForgiveWarningRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
uint64 userId = 2;
|
string warnId = 2;
|
||||||
optional int32 warnId = 3;
|
string modName = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ClearWarningReply {
|
message ForgiveWarningReply {
|
||||||
bool success = 1;
|
bool success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetWarnExpiryRequest {
|
message SetWarnExpiryRequest {
|
||||||
uint64 guildId = 1;
|
uint64 guildId = 1;
|
||||||
int32 expiryDays = 2;
|
int32 expiryDays = 2;
|
||||||
|
bool deleteOnExpire = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetWarnExpiryReply {
|
message SetWarnExpiryReply {
|
||||||
bool success = 1;
|
bool success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetLatestWarningsRequest {
|
||||||
|
uint64 guildId = 1;
|
||||||
|
int32 page = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetLatestWarningsReply {
|
||||||
|
repeated Warning warnings = 1;
|
||||||
|
int32 totalCount = 2;
|
||||||
|
}
|
|
@ -194,11 +194,6 @@ public abstract class EllieContext : DbContext
|
||||||
.WithOne()
|
.WithOne()
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<GuildConfig>()
|
|
||||||
.HasMany(x => x.WarnPunishments)
|
|
||||||
.WithOne()
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<GuildConfig>()
|
modelBuilder.Entity<GuildConfig>()
|
||||||
.HasMany(x => x.SlowmodeIgnoredRoles)
|
.HasMany(x => x.SlowmodeIgnoredRoles)
|
||||||
.WithOne()
|
.WithOne()
|
||||||
|
@ -276,6 +271,18 @@ public abstract class EllieContext : DbContext
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region WarningPunishments
|
||||||
|
|
||||||
|
var warnpunishmentEntity = modelBuilder.Entity<WarningPunishment>(b =>
|
||||||
|
{
|
||||||
|
b.HasAlternateKey(x => new
|
||||||
|
{
|
||||||
|
x.GuildId,
|
||||||
|
x.Count
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Self Assignable Roles
|
#region Self Assignable Roles
|
||||||
|
|
||||||
|
@ -338,6 +345,7 @@ public abstract class EllieContext : DbContext
|
||||||
du.HasIndex(x => x.TotalXp);
|
du.HasIndex(x => x.TotalXp);
|
||||||
du.HasIndex(x => x.CurrencyAmount);
|
du.HasIndex(x => x.CurrencyAmount);
|
||||||
du.HasIndex(x => x.UserId);
|
du.HasIndex(x => x.UserId);
|
||||||
|
du.HasIndex(x => x.Username);
|
||||||
});
|
});
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -96,7 +96,6 @@ public static class GuildConfigExtensions
|
||||||
GuildId = guildId,
|
GuildId = guildId,
|
||||||
Permissions = Permissionv2.GetDefaultPermlist,
|
Permissions = Permissionv2.GetDefaultPermlist,
|
||||||
WarningsInitialized = true,
|
WarningsInitialized = true,
|
||||||
WarnPunishments = DefaultWarnPunishments
|
|
||||||
});
|
});
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
}
|
}
|
||||||
|
@ -104,7 +103,6 @@ public static class GuildConfigExtensions
|
||||||
if (!config.WarningsInitialized)
|
if (!config.WarningsInitialized)
|
||||||
{
|
{
|
||||||
config.WarningsInitialized = true;
|
config.WarningsInitialized = true;
|
||||||
config.WarnPunishments = DefaultWarnPunishments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
|
|
@ -77,7 +77,6 @@ public class GuildConfig : DbEntity
|
||||||
public HashSet<UnroleTimer> UnroleTimer { get; set; } = new();
|
public HashSet<UnroleTimer> UnroleTimer { get; set; } = new();
|
||||||
public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
|
public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
|
||||||
public HashSet<CommandAlias> CommandAliases { get; set; } = new();
|
public HashSet<CommandAlias> CommandAliases { get; set; } = new();
|
||||||
public List<WarningPunishment> WarnPunishments { get; set; } = new();
|
|
||||||
public bool WarningsInitialized { get; set; }
|
public bool WarningsInitialized { get; set; }
|
||||||
public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
|
public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
|
||||||
public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
|
public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace EllieBot.Db.Models;
|
||||||
|
|
||||||
public class WarningPunishment : DbEntity
|
public class WarningPunishment : DbEntity
|
||||||
{
|
{
|
||||||
|
public ulong GuildId { get; set; }
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
public PunishmentAction Punishment { get; set; }
|
public PunishmentAction Punishment { get; set; }
|
||||||
public int Time { get; set; }
|
public int Time { get; set; }
|
||||||
|
|
|
@ -66,4 +66,19 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
|
||||||
WHERE SendBoostMessage = TRUE;
|
WHERE SendBoostMessage = TRUE;
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddGuildIdsToWarningPunishment(MigrationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Sql("""
|
||||||
|
UPDATE WarningPunishment
|
||||||
|
SET GuildId = (SELECT GuildId FROM guildconfigs WHERE Id = GuildConfigId);
|
||||||
|
|
||||||
|
DELETE FROM WarningPunishment as wp
|
||||||
|
WHERE (wp.Count, wp.GuildConfigId) in (
|
||||||
|
SELECT wp2.Count, wp2.GuildConfigId FROM WarningPunishment as wp2
|
||||||
|
GROUP BY wp2.Count, wp2.GuildConfigId
|
||||||
|
HAVING COUNT(id) > 1
|
||||||
|
);
|
||||||
|
""");
|
||||||
|
}
|
||||||
}
|
}
|
3778
src/EllieBot/Migrations/PostgreSql/20241018004623_warn-split.Designer.cs
generated
Normal file
3778
src/EllieBot/Migrations/PostgreSql/20241018004623_warn-split.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,71 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.PostgreSql
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class warnsplit : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<decimal>(
|
||||||
|
name: "guildid",
|
||||||
|
table: "warningpunishment",
|
||||||
|
type: "numeric(20,0)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0m);
|
||||||
|
|
||||||
|
MigrationQueries.AddGuildIdsToWarningPunishment(migrationBuilder);
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_warningpunishment_guildconfigs_guildconfigid",
|
||||||
|
table: "warningpunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_warningpunishment_guildconfigid",
|
||||||
|
table: "warningpunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "guildconfigid",
|
||||||
|
table: "warningpunishment");
|
||||||
|
|
||||||
|
migrationBuilder.AddUniqueConstraint(
|
||||||
|
name: "ak_warningpunishment_guildid_count",
|
||||||
|
table: "warningpunishment",
|
||||||
|
columns: new[] { "guildid", "count" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropUniqueConstraint(
|
||||||
|
name: "ak_warningpunishment_guildid_count",
|
||||||
|
table: "warningpunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "guildid",
|
||||||
|
table: "warningpunishment");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "guildconfigid",
|
||||||
|
table: "warningpunishment",
|
||||||
|
type: "integer",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_warningpunishment_guildconfigid",
|
||||||
|
table: "warningpunishment",
|
||||||
|
column: "guildconfigid");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_warningpunishment_guildconfigs_guildconfigid",
|
||||||
|
table: "warningpunishment",
|
||||||
|
column: "guildconfigid",
|
||||||
|
principalTable: "guildconfigs",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2938,9 +2938,9 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("timestamp without time zone")
|
.HasColumnType("timestamp without time zone")
|
||||||
.HasColumnName("dateadded");
|
.HasColumnName("dateadded");
|
||||||
|
|
||||||
b.Property<int?>("GuildConfigId")
|
b.Property<decimal>("GuildId")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("numeric(20,0)")
|
||||||
.HasColumnName("guildconfigid");
|
.HasColumnName("guildid");
|
||||||
|
|
||||||
b.Property<int>("Punishment")
|
b.Property<int>("Punishment")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
|
@ -2957,8 +2957,8 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_warningpunishment");
|
.HasName("pk_warningpunishment");
|
||||||
|
|
||||||
b.HasIndex("GuildConfigId")
|
b.HasAlternateKey("GuildId", "Count")
|
||||||
.HasDatabaseName("ix_warningpunishment_guildconfigid");
|
.HasName("ak_warningpunishment_guildid_count");
|
||||||
|
|
||||||
b.ToTable("warningpunishment", (string)null);
|
b.ToTable("warningpunishment", (string)null);
|
||||||
});
|
});
|
||||||
|
@ -3616,15 +3616,6 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.WarningPunishment", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
|
||||||
.WithMany("WarnPunishments")
|
|
||||||
.HasForeignKey("GuildConfigId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.XpCurrencyReward", b =>
|
modelBuilder.Entity("EllieBot.Db.Models.XpCurrencyReward", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
||||||
|
@ -3740,8 +3731,6 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
|
|
||||||
b.Navigation("VcRoleInfos");
|
b.Navigation("VcRoleInfos");
|
||||||
|
|
||||||
b.Navigation("WarnPunishments");
|
|
||||||
|
|
||||||
b.Navigation("XpSettings");
|
b.Navigation("XpSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
2919
src/EllieBot/Migrations/Sqlite/20241018004612_warn-split.Designer.cs
generated
Normal file
2919
src/EllieBot/Migrations/Sqlite/20241018004612_warn-split.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
72
src/EllieBot/Migrations/Sqlite/20241018004612_warn-split.cs
Normal file
72
src/EllieBot/Migrations/Sqlite/20241018004612_warn-split.cs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class warnsplit : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<ulong>(
|
||||||
|
name: "GuildId",
|
||||||
|
table: "WarningPunishment",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0ul);
|
||||||
|
|
||||||
|
MigrationQueries.AddGuildIdsToWarningPunishment(migrationBuilder);
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
|
||||||
|
table: "WarningPunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_WarningPunishment_GuildConfigId",
|
||||||
|
table: "WarningPunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "GuildConfigId",
|
||||||
|
table: "WarningPunishment");
|
||||||
|
|
||||||
|
migrationBuilder.AddUniqueConstraint(
|
||||||
|
name: "AK_WarningPunishment_GuildId_Count",
|
||||||
|
table: "WarningPunishment",
|
||||||
|
columns: new[] { "GuildId", "Count" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropUniqueConstraint(
|
||||||
|
name: "AK_WarningPunishment_GuildId_Count",
|
||||||
|
table: "WarningPunishment");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "GuildId",
|
||||||
|
table: "WarningPunishment");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "GuildConfigId",
|
||||||
|
table: "WarningPunishment",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_WarningPunishment_GuildConfigId",
|
||||||
|
table: "WarningPunishment",
|
||||||
|
column: "GuildConfigId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
|
||||||
|
table: "WarningPunishment",
|
||||||
|
column: "GuildConfigId",
|
||||||
|
principalTable: "GuildConfigs",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2183,7 +2183,7 @@ namespace EllieBot.Migrations
|
||||||
b.Property<DateTime?>("DateAdded")
|
b.Property<DateTime?>("DateAdded")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int?>("GuildConfigId")
|
b.Property<ulong>("GuildId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int>("Punishment")
|
b.Property<int>("Punishment")
|
||||||
|
@ -2197,7 +2197,7 @@ namespace EllieBot.Migrations
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("GuildConfigId");
|
b.HasAlternateKey("GuildId", "Count");
|
||||||
|
|
||||||
b.ToTable("WarningPunishment");
|
b.ToTable("WarningPunishment");
|
||||||
});
|
});
|
||||||
|
@ -2760,14 +2760,6 @@ namespace EllieBot.Migrations
|
||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.WarningPunishment", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
|
||||||
.WithMany("WarnPunishments")
|
|
||||||
.HasForeignKey("GuildConfigId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.XpCurrencyReward", b =>
|
modelBuilder.Entity("EllieBot.Db.Models.XpCurrencyReward", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
||||||
|
@ -2880,8 +2872,6 @@ namespace EllieBot.Migrations
|
||||||
|
|
||||||
b.Navigation("VcRoleInfos");
|
b.Navigation("VcRoleInfos");
|
||||||
|
|
||||||
b.Navigation("WarnPunishments");
|
|
||||||
|
|
||||||
b.Navigation("XpSettings");
|
b.Navigation("XpSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,6 @@ public partial class Administration
|
||||||
public Task DeleteXp()
|
public Task DeleteXp()
|
||||||
=> ConfirmActionInternalAsync("Delete Xp", () => _xcs.DeleteXp());
|
=> ConfirmActionInternalAsync("Delete Xp", () => _xcs.DeleteXp());
|
||||||
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public Task DeleteWaifus()
|
public Task DeleteWaifus()
|
||||||
|
|
|
@ -85,7 +85,8 @@ public partial class Administration
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Exception occured while warning a user");
|
Log.Warning(ex, "Exception occured while warning a user");
|
||||||
var errorEmbed = _sender.CreateEmbed().WithErrorColor()
|
var errorEmbed = _sender.CreateEmbed()
|
||||||
|
.WithErrorColor()
|
||||||
.WithDescription(GetText(strs.cant_apply_punishment));
|
.WithDescription(GetText(strs.cant_apply_punishment));
|
||||||
|
|
||||||
if (dmFailed)
|
if (dmFailed)
|
||||||
|
@ -287,7 +288,7 @@ public partial class Administration
|
||||||
if (--index < 0)
|
if (--index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var warn = await _service.WarnDelete(userId, index);
|
var warn = await _service.WarnDelete(ctx.Guild.Id, userId, index);
|
||||||
|
|
||||||
if (warn is null)
|
if (warn is null)
|
||||||
{
|
{
|
||||||
|
@ -344,7 +345,7 @@ public partial class Administration
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var success = _service.WarnPunish(ctx.Guild.Id, number, punish, time, role);
|
var success = await _service.WarnPunish(ctx.Guild.Id, number, punish, time, role);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return;
|
return;
|
||||||
|
@ -380,7 +381,7 @@ public partial class Administration
|
||||||
if (punish is PunishmentAction.TimeOut && time is null)
|
if (punish is PunishmentAction.TimeOut && time is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var success = _service.WarnPunish(ctx.Guild.Id, number, punish, time);
|
var success = await _service.WarnPunish(ctx.Guild.Id, number, punish, time);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return;
|
return;
|
||||||
|
@ -407,7 +408,7 @@ public partial class Administration
|
||||||
[UserPerm(GuildPerm.BanMembers)]
|
[UserPerm(GuildPerm.BanMembers)]
|
||||||
public async Task WarnPunish(int number)
|
public async Task WarnPunish(int number)
|
||||||
{
|
{
|
||||||
if (!_service.WarnPunishRemove(ctx.Guild.Id, number))
|
if (!await _service.WarnPunishRemove(ctx.Guild.Id, number))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await Response().Confirm(strs.warn_punish_rem(Format.Bold(number.ToString()))).SendAsync();
|
await Response().Confirm(strs.warn_punish_rem(Format.Bold(number.ToString()))).SendAsync();
|
||||||
|
@ -417,7 +418,7 @@ public partial class Administration
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task WarnPunishList()
|
public async Task WarnPunishList()
|
||||||
{
|
{
|
||||||
var ps = _service.WarnPunishList(ctx.Guild.Id);
|
var ps = await _service.WarnPunishList(ctx.Guild.Id);
|
||||||
|
|
||||||
string list;
|
string list;
|
||||||
if (ps.Any())
|
if (ps.Any())
|
||||||
|
@ -505,7 +506,8 @@ public partial class Administration
|
||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
||||||
|
|
||||||
await Response().Embed(_sender.CreateEmbed()
|
await Response()
|
||||||
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||||
.AddField("ID", userId.ToString(), true))
|
.AddField("ID", userId.ToString(), true))
|
||||||
|
@ -734,7 +736,8 @@ public partial class Administration
|
||||||
|
|
||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
await ctx.Guild.AddBanAsync(user, banPrune, ("Softban | " + ctx.User + " | " + msg).TrimTo(512));
|
await ctx.Guild.AddBanAsync(user, banPrune, ("Softban | " + ctx.User + " | " + msg).TrimTo(512));
|
||||||
try { await ctx.Guild.RemoveBanAsync(user); }
|
try
|
||||||
|
{ await ctx.Guild.RemoveBanAsync(user); }
|
||||||
catch { await ctx.Guild.RemoveBanAsync(user); }
|
catch { await ctx.Guild.RemoveBanAsync(user); }
|
||||||
|
|
||||||
var toSend = _sender.CreateEmbed()
|
var toSend = _sender.CreateEmbed()
|
||||||
|
@ -920,8 +923,10 @@ public partial class Administration
|
||||||
|
|
||||||
await banningMessage.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
await banningMessage.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
GetText(strs.mass_ban_completed(banning.Count())))
|
GetText(strs.mass_ban_completed(
|
||||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
banning.Count())))
|
||||||
|
.AddField(GetText(strs.invalid(missing.Count)),
|
||||||
|
missStr)
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.Build());
|
.Build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.EntityFrameworkCore;
|
using LinqToDB.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using EllieBot.Common.ModuleBehaviors;
|
using EllieBot.Common.ModuleBehaviors;
|
||||||
using EllieBot.Common.TypeReaders.Models;
|
using EllieBot.Common.TypeReaders.Models;
|
||||||
using EllieBot.Modules.Permissions.Services;
|
using EllieBot.Modules.Permissions.Services;
|
||||||
|
@ -83,17 +82,24 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
};
|
};
|
||||||
|
|
||||||
long previousCount;
|
long previousCount;
|
||||||
List<WarningPunishment> ps;
|
var ps = await WarnPunishList(guildId);
|
||||||
await using (var uow = _db.GetDbContext())
|
await using (var uow = _db.GetDbContext())
|
||||||
{
|
{
|
||||||
ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
|
previousCount = uow.GetTable<Warning>()
|
||||||
|
.Where(w => w.GuildId == guildId && w.UserId == userId && !w.Forgiven)
|
||||||
previousCount = uow.Set<Warning>()
|
|
||||||
.ForId(guildId, userId)
|
|
||||||
.Where(w => !w.Forgiven && w.UserId == userId)
|
|
||||||
.Sum(x => x.Weight);
|
.Sum(x => x.Weight);
|
||||||
|
|
||||||
uow.Set<Warning>().Add(warn);
|
await uow.GetTable<Warning>()
|
||||||
|
.InsertAsync(() => new()
|
||||||
|
{
|
||||||
|
UserId = userId,
|
||||||
|
GuildId = guildId,
|
||||||
|
Forgiven = false,
|
||||||
|
Reason = reason,
|
||||||
|
Moderator = modName,
|
||||||
|
Weight = weight,
|
||||||
|
DateAdded = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
|
||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
@ -377,18 +383,19 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool WarnPunish(
|
public async Task<bool> WarnPunish(
|
||||||
ulong guildId,
|
ulong guildId,
|
||||||
int number,
|
int number,
|
||||||
PunishmentAction punish,
|
PunishmentAction punish,
|
||||||
StoopidTime time,
|
TimeSpan? time,
|
||||||
IRole role = null)
|
IRole role = null)
|
||||||
{
|
{
|
||||||
// these 3 don't make sense with time
|
// these 3 don't make sense with time
|
||||||
if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles
|
if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles
|
||||||
&& time is not null)
|
&& time is not null)
|
||||||
return false;
|
return false;
|
||||||
if (number <= 0 || (time is not null && time.Time > TimeSpan.FromDays(49)))
|
|
||||||
|
if (number <= 0 || (time is not null && time > TimeSpan.FromDays(59)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (punish is PunishmentAction.AddRole && role is null)
|
if (punish is PunishmentAction.AddRole && role is null)
|
||||||
|
@ -397,47 +404,51 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
if (punish is PunishmentAction.TimeOut && time is null)
|
if (punish is PunishmentAction.TimeOut && time is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
using var uow = _db.GetDbContext();
|
var timeMinutes = (int?)time?.TotalMinutes ?? 0;
|
||||||
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
|
var roleId = punish == PunishmentAction.AddRole ? role!.Id : default(ulong?);
|
||||||
var toDelete = ps.Where(x => x.Count == number);
|
await using var uow = _db.GetDbContext();
|
||||||
|
await uow.GetTable<WarningPunishment>()
|
||||||
uow.RemoveRange(toDelete);
|
.InsertOrUpdateAsync(() => new()
|
||||||
|
|
||||||
ps.Add(new()
|
|
||||||
{
|
{
|
||||||
|
GuildId = guildId,
|
||||||
Count = number,
|
Count = number,
|
||||||
Punishment = punish,
|
Punishment = punish,
|
||||||
Time = (int?)time?.Time.TotalMinutes ?? 0,
|
Time = timeMinutes,
|
||||||
RoleId = punish == PunishmentAction.AddRole ? role!.Id : default(ulong?)
|
RoleId = roleId
|
||||||
|
},
|
||||||
|
_ => new()
|
||||||
|
{
|
||||||
|
Punishment = punish,
|
||||||
|
Time = timeMinutes,
|
||||||
|
RoleId = roleId
|
||||||
|
},
|
||||||
|
() => new()
|
||||||
|
{
|
||||||
|
GuildId = guildId,
|
||||||
|
Count = number
|
||||||
});
|
});
|
||||||
uow.SaveChanges();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool WarnPunishRemove(ulong guildId, int number)
|
public async Task<bool> WarnPunishRemove(ulong guildId, int count)
|
||||||
{
|
{
|
||||||
if (number <= 0)
|
await using var uow = _db.GetDbContext();
|
||||||
return false;
|
var numDeleted = await uow.GetTable<WarningPunishment>()
|
||||||
|
.DeleteAsync(x => x.GuildId == guildId && x.Count == count);
|
||||||
|
|
||||||
using var uow = _db.GetDbContext();
|
return numDeleted > 0;
|
||||||
var ps = uow.GuildConfigsForId(guildId, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
|
|
||||||
var p = ps.FirstOrDefault(x => x.Count == number);
|
|
||||||
|
|
||||||
if (p is not null)
|
|
||||||
{
|
|
||||||
uow.Remove(p);
|
|
||||||
uow.SaveChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WarningPunishment[] WarnPunishList(ulong guildId)
|
public async Task<WarningPunishment[]> WarnPunishList(ulong guildId)
|
||||||
{
|
{
|
||||||
using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
return uow.GuildConfigsForId(guildId, gc => gc.Include(x => x.WarnPunishments))
|
|
||||||
.WarnPunishments.OrderBy(x => x.Count)
|
var wps = uow.GetTable<WarningPunishment>()
|
||||||
|
.Where(x => x.GuildId == guildId)
|
||||||
|
.OrderBy(x => x.Count)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
return wps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (IReadOnlyCollection<(string Original, ulong? Id, string Reason)> Bans, int Missing) MassKill(
|
public (IReadOnlyCollection<(string Original, ulong? Id, string Reason)> Bans, int Missing) MassKill(
|
||||||
|
@ -607,12 +618,12 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
return await _repSvc.ReplaceAsync(output, repCtx);
|
return await _repSvc.ReplaceAsync(output, repCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Warning> WarnDelete(ulong userId, int index)
|
public async Task<Warning> WarnDelete(ulong guildId, ulong userId, int index)
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
|
|
||||||
var warn = await uow.GetTable<Warning>()
|
var warn = await uow.GetTable<Warning>()
|
||||||
.Where(x => x.UserId == userId)
|
.Where(x => x.GuildId == guildId && x.UserId == userId)
|
||||||
.OrderByDescending(x => x.DateAdded)
|
.OrderByDescending(x => x.DateAdded)
|
||||||
.Skip(index)
|
.Skip(index)
|
||||||
.FirstOrDefaultAsyncLinqToDB();
|
.FirstOrDefaultAsyncLinqToDB();
|
||||||
|
@ -626,4 +637,73 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
|
|
||||||
return warn;
|
return warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> WarnDelete(ulong guildId, int id)
|
||||||
|
{
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
|
||||||
|
var numDeleted = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == guildId && x.Id == id)
|
||||||
|
.DeleteAsync();
|
||||||
|
|
||||||
|
return numDeleted > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(IReadOnlyCollection<Warning> latest, int totalCount)> GetLatestWarnings(
|
||||||
|
ulong guildId,
|
||||||
|
int page = 1)
|
||||||
|
{
|
||||||
|
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(page);
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var latest = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == guildId)
|
||||||
|
.OrderByDescending(x => x.DateAdded)
|
||||||
|
.Skip(10 * (page - 1))
|
||||||
|
.Take(10)
|
||||||
|
.ToListAsyncLinqToDB();
|
||||||
|
|
||||||
|
var totalCount = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == guildId)
|
||||||
|
.CountAsyncLinqToDB();
|
||||||
|
|
||||||
|
return (latest, totalCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ForgiveWarning(ulong requestGuildId, int warnId, string modName)
|
||||||
|
{
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var success = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == requestGuildId && x.Id == warnId)
|
||||||
|
.UpdateAsync(_ => new()
|
||||||
|
{
|
||||||
|
Forgiven = true,
|
||||||
|
ForgivenBy = modName,
|
||||||
|
})
|
||||||
|
== 1;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(IReadOnlyCollection<Warning> latest, int totalCount)> GetUserWarnings(
|
||||||
|
ulong guildId,
|
||||||
|
ulong userId,
|
||||||
|
int page)
|
||||||
|
{
|
||||||
|
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(page);
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var latest = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == guildId && x.UserId == userId)
|
||||||
|
.OrderByDescending(x => x.DateAdded)
|
||||||
|
.Skip(10 * (page - 1))
|
||||||
|
.Take(10)
|
||||||
|
.ToListAsyncLinqToDB();
|
||||||
|
|
||||||
|
var totalCount = await uow.GetTable<Warning>()
|
||||||
|
.Where(x => x.GuildId == guildId && x.UserId == userId)
|
||||||
|
.CountAsyncLinqToDB();
|
||||||
|
|
||||||
|
return (latest, totalCount);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -197,17 +197,20 @@ public class RemindService : IEService, IReadyExecutor, IRemindService
|
||||||
|
|
||||||
var st = SmartText.CreateFrom(r.Message);
|
var st = SmartText.CreateFrom(r.Message);
|
||||||
|
|
||||||
|
var res = _sender.Response(ch)
|
||||||
|
.UserBasedMentions(_client.GetGuild(r.ServerId)?.GetUser(r.UserId));
|
||||||
|
|
||||||
if (st is SmartEmbedText set)
|
if (st is SmartEmbedText set)
|
||||||
{
|
{
|
||||||
await _sender.Response(ch).Embed(set.GetEmbed()).SendAsync();
|
await res.Embed(set.GetEmbed()).SendAsync();
|
||||||
}
|
}
|
||||||
else if (st is SmartEmbedTextArray seta)
|
else if (st is SmartEmbedTextArray seta)
|
||||||
{
|
{
|
||||||
await _sender.Response(ch).Embeds(seta.GetEmbedBuilders()).SendAsync();
|
await res.Embeds(seta.GetEmbedBuilders()).SendAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _sender.Response(ch)
|
await res
|
||||||
.Embed(_sender.CreateEmbed()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("Reminder")
|
.WithTitle("Reminder")
|
||||||
|
|
|
@ -6,7 +6,7 @@ using EllieBot.Modules.Utility;
|
||||||
|
|
||||||
namespace EllieBot.GrpcApi;
|
namespace EllieBot.GrpcApi;
|
||||||
|
|
||||||
public class ExprsSvc : GrpcExprs.GrpcExprsBase, IEService
|
public class ExprsSvc : GrpcExprs.GrpcExprsBase, IGrpcSvc, IEService
|
||||||
{
|
{
|
||||||
private readonly EllieExpressionsService _svc;
|
private readonly EllieExpressionsService _svc;
|
||||||
private readonly IQuoteService _qs;
|
private readonly IQuoteService _qs;
|
||||||
|
@ -19,6 +19,9 @@ public class ExprsSvc : GrpcExprs.GrpcExprsBase, IEService
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerServiceDefinition Bind()
|
||||||
|
=> GrpcExprs.BindService(this);
|
||||||
|
|
||||||
private ulong GetUserId(Metadata meta)
|
private ulong GetUserId(Metadata meta)
|
||||||
=> ulong.Parse(meta.FirstOrDefault(x => x.Key == "userid")!.Value);
|
=> ulong.Parse(meta.FirstOrDefault(x => x.Key == "userid")!.Value);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ using GreetType = EllieBot.Services.GreetType;
|
||||||
|
|
||||||
namespace EllieBot.GrpcApi;
|
namespace EllieBot.GrpcApi;
|
||||||
|
|
||||||
public sealed class GreetByeSvc : GrpcGreet.GrpcGreetBase, IEService
|
public sealed class GreetByeSvc : GrpcGreet.GrpcGreetBase, IGrpcSvc, IEService
|
||||||
{
|
{
|
||||||
private readonly GreetService _gs;
|
private readonly GreetService _gs;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
@ -14,6 +14,9 @@ public sealed class GreetByeSvc : GrpcGreet.GrpcGreetBase, IEService
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerServiceDefinition Bind()
|
||||||
|
=> GrpcGreet.BindService(this);
|
||||||
|
|
||||||
private static GrpcGreetSettings ToConf(GreetSettings? conf)
|
private static GrpcGreetSettings ToConf(GreetSettings? conf)
|
||||||
{
|
{
|
||||||
if (conf is null)
|
if (conf is null)
|
||||||
|
@ -50,11 +53,14 @@ public sealed class GreetByeSvc : GrpcGreet.GrpcGreetBase, IEService
|
||||||
var settings = await _gs.GetGreetSettingsAsync(gid, type);
|
var settings = await _gs.GetGreetSettingsAsync(gid, type);
|
||||||
|
|
||||||
if (settings is null)
|
if (settings is null)
|
||||||
return new();
|
return new()
|
||||||
|
{
|
||||||
|
Success = false
|
||||||
|
};
|
||||||
|
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
Settings = ToConf(settings)
|
Success = true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ public static class GrpcApiExtensions
|
||||||
=> ulong.Parse(context.RequestHeaders.FirstOrDefault(x => x.Key == "userid")!.Value);
|
=> ulong.Parse(context.RequestHeaders.FirstOrDefault(x => x.Key == "userid")!.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class OtherSvc : GrpcOther.GrpcOtherBase, IEService
|
public sealed class OtherSvc : GrpcOther.GrpcOtherBase, IGrpcSvc, IEService
|
||||||
{
|
{
|
||||||
private readonly IDiscordClient _client;
|
private readonly IDiscordClient _client;
|
||||||
private readonly XpService _xp;
|
private readonly XpService _xp;
|
||||||
|
@ -39,6 +39,9 @@ public sealed class OtherSvc : GrpcOther.GrpcOtherBase, IEService
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerServiceDefinition Bind()
|
||||||
|
=> GrpcOther.BindService(this);
|
||||||
|
|
||||||
[GrpcNoAuthRequired]
|
[GrpcNoAuthRequired]
|
||||||
public override async Task<BotOnGuildReply> BotOnGuild(BotOnGuildRequest request, ServerCallContext context)
|
public override async Task<BotOnGuildReply> BotOnGuild(BotOnGuildRequest request, ServerCallContext context)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +55,22 @@ public sealed class OtherSvc : GrpcOther.GrpcOtherBase, IEService
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task<GetRolesReply> GetRoles(GetRolesRequest request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
var g = await _client.GetGuildAsync(request.GuildId);
|
||||||
|
var roles = g?.Roles;
|
||||||
|
var reply = new GetRolesReply();
|
||||||
|
reply.Roles.AddRange(roles?.Select(x => new RoleReply()
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
Name = x.Name,
|
||||||
|
Color = x.Color.ToString(),
|
||||||
|
IconUrl = x.GetIconUrl() ?? string.Empty,
|
||||||
|
}) ?? new List<RoleReply>());
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task<GetTextChannelsReply> GetTextChannels(
|
public override async Task<GetTextChannelsReply> GetTextChannels(
|
||||||
GetTextChannelsRequest request,
|
GetTextChannelsRequest request,
|
||||||
ServerCallContext context)
|
ServerCallContext context)
|
||||||
|
|
222
src/EllieBot/Services/GrpcApi/WarnSvc.cs
Normal file
222
src/EllieBot/Services/GrpcApi/WarnSvc.cs
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
using Grpc.Core;
|
||||||
|
using EllieBot.Db.Models;
|
||||||
|
using EllieBot.Modules.Administration.Services;
|
||||||
|
using Enum = System.Enum;
|
||||||
|
|
||||||
|
namespace EllieBot.GrpcApi;
|
||||||
|
|
||||||
|
public sealed class WarnSvc : GrpcWarn.GrpcWarnBase, IGrpcSvc, IEService
|
||||||
|
{
|
||||||
|
private readonly UserPunishService _ups;
|
||||||
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
|
public WarnSvc(UserPunishService ups, DiscordSocketClient client)
|
||||||
|
{
|
||||||
|
_ups = ups;
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerServiceDefinition Bind()
|
||||||
|
=> GrpcWarn.BindService(this);
|
||||||
|
|
||||||
|
public override async Task<WarnSettingsReply> GetWarnSettings(
|
||||||
|
WarnSettingsRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
var list = await _ups.WarnPunishList(request.GuildId);
|
||||||
|
|
||||||
|
var wsr = new WarnSettingsReply();
|
||||||
|
|
||||||
|
wsr.Punishments.AddRange(list.Select(x => new WarnPunishment()
|
||||||
|
{
|
||||||
|
Action = x.Punishment.ToString(),
|
||||||
|
Duration = x.Time,
|
||||||
|
Threshold = x.Count,
|
||||||
|
Role = x.RoleId is ulong rid
|
||||||
|
? _client.GetGuild(request.GuildId)?.GetRole(rid)?.Name ?? x.RoleId?.ToString() ?? string.Empty
|
||||||
|
: string.Empty
|
||||||
|
}));
|
||||||
|
|
||||||
|
return wsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<SetWarnExpiryReply> SetWarnExpiry(
|
||||||
|
SetWarnExpiryRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
if (request.ExpiryDays > 366)
|
||||||
|
{
|
||||||
|
return new SetWarnExpiryReply()
|
||||||
|
{
|
||||||
|
Success = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await _ups.WarnExpireAsync(request.GuildId, request.ExpiryDays, request.DeleteOnExpire);
|
||||||
|
|
||||||
|
return new SetWarnExpiryReply()
|
||||||
|
{
|
||||||
|
Success = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<DeleteWarnpReply> DeleteWarnp(DeleteWarnpRequest request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
var succ = await _ups.WarnPunishRemove(request.GuildId, request.Threshold);
|
||||||
|
|
||||||
|
return new DeleteWarnpReply
|
||||||
|
{
|
||||||
|
Success = succ
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<AddWarnpReply> AddWarnp(AddWarnpRequest request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
if (request.Punishment.Threshold <= 0)
|
||||||
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "Threshold must be greater than 0"));
|
||||||
|
|
||||||
|
var g = _client.GetGuild(request.GuildId);
|
||||||
|
|
||||||
|
if (g is null)
|
||||||
|
throw new RpcException(new Status(StatusCode.NotFound, "Guild not found"));
|
||||||
|
|
||||||
|
if (!Enum.TryParse<PunishmentAction>(request.Punishment.Action, out var action))
|
||||||
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid action"));
|
||||||
|
|
||||||
|
IRole? role = null;
|
||||||
|
if (action == PunishmentAction.AddRole && ulong.TryParse(request.Punishment.Role, out var roleId))
|
||||||
|
{
|
||||||
|
role = g.GetRole(roleId);
|
||||||
|
|
||||||
|
if (role is null)
|
||||||
|
return new AddWarnpReply()
|
||||||
|
{
|
||||||
|
Success = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!ulong.TryParse(context.RequestHeaders.GetValue("userid"), out var userId))
|
||||||
|
return new AddWarnpReply()
|
||||||
|
{
|
||||||
|
Success = false
|
||||||
|
};
|
||||||
|
|
||||||
|
var user = await ((IGuild)g).GetUserAsync(userId);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
throw new RpcException(new Status(StatusCode.NotFound, "User not found"));
|
||||||
|
|
||||||
|
var userMaxRole = user.GetRoles().MaxBy(x => x.Position)?.Position ?? 0;
|
||||||
|
if (g.OwnerId != user.Id && userMaxRole <= role.Position)
|
||||||
|
{
|
||||||
|
return new AddWarnpReply()
|
||||||
|
{
|
||||||
|
Success = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var duration = TimeSpan.FromMinutes(request.Punishment.Duration);
|
||||||
|
|
||||||
|
var succ = await _ups.WarnPunish(request.GuildId,
|
||||||
|
request.Punishment.Threshold,
|
||||||
|
action,
|
||||||
|
duration,
|
||||||
|
role
|
||||||
|
);
|
||||||
|
|
||||||
|
return new AddWarnpReply()
|
||||||
|
{
|
||||||
|
Success = succ
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<GetLatestWarningsReply> GetLatestWarnings(
|
||||||
|
GetLatestWarningsRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
var (latest, count) = await _ups.GetLatestWarnings(request.GuildId, request.Page);
|
||||||
|
|
||||||
|
var reply = new GetLatestWarningsReply()
|
||||||
|
{
|
||||||
|
TotalCount = count
|
||||||
|
};
|
||||||
|
|
||||||
|
reply.Warnings.AddRange(latest.Select(MapWarningToGrpcWarning));
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<GetUserWarningsReply> GetUserWarnings(
|
||||||
|
GetUserWarningsRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
IReadOnlyCollection<Db.Models.Warning> latest = [];
|
||||||
|
var count = 0;
|
||||||
|
if (ulong.TryParse(request.User, out var userId))
|
||||||
|
{
|
||||||
|
(latest, count) = await _ups.GetUserWarnings(request.GuildId, userId, request.Page);
|
||||||
|
}
|
||||||
|
else if (_client.GetGuild(request.GuildId)?.Users.FirstOrDefault(x => x.Username == request.User) is { } user)
|
||||||
|
{
|
||||||
|
(latest, count) = await _ups.GetUserWarnings(request.GuildId, user.Id, request.Page);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
var reply = new GetUserWarningsReply
|
||||||
|
{
|
||||||
|
TotalCount = count
|
||||||
|
};
|
||||||
|
|
||||||
|
reply.Warnings.AddRange(latest.Select(MapWarningToGrpcWarning));
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Warning MapWarningToGrpcWarning(Db.Models.Warning x)
|
||||||
|
{
|
||||||
|
return new Warning
|
||||||
|
{
|
||||||
|
Id = new kwum(x.Id).ToString(),
|
||||||
|
Forgiven = x.Forgiven,
|
||||||
|
ForgivenBy = x.ForgivenBy ?? string.Empty,
|
||||||
|
Reason = x.Reason ?? string.Empty,
|
||||||
|
Timestamp = x.DateAdded is { } da ? Ellie.Common.Extensions.ToTimestamp(da) : 0,
|
||||||
|
Weight = x.Weight,
|
||||||
|
Moderator = x.Moderator ?? string.Empty,
|
||||||
|
User = _client.GetUser(x.UserId)?.Username ?? x.UserId.ToString(),
|
||||||
|
UserId = x.UserId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<ForgiveWarningReply> ForgiveWarning(
|
||||||
|
ForgiveWarningRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
if (!kwum.TryParse(request.WarnId, out var wid))
|
||||||
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid warning ID"));
|
||||||
|
|
||||||
|
var succ = await _ups.ForgiveWarning(request.GuildId, wid, request.ModName);
|
||||||
|
|
||||||
|
return new ForgiveWarningReply
|
||||||
|
{
|
||||||
|
Success = succ
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<ForgiveWarningReply> DeleteWarning(
|
||||||
|
ForgiveWarningRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
if (!kwum.TryParse(request.WarnId, out var wid))
|
||||||
|
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid warning ID"));
|
||||||
|
|
||||||
|
var succ = await _ups.WarnDelete(request.GuildId, wid);
|
||||||
|
|
||||||
|
return new ForgiveWarningReply
|
||||||
|
{
|
||||||
|
Success = succ
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ public sealed partial class GrpcApiPermsInterceptor : Interceptor
|
||||||
return await continuation(request, context);
|
return await continuation(request, context);
|
||||||
|
|
||||||
// otherwise the method requires auth, and if it requires auth then the guildid has to be specified
|
// otherwise the method requires auth, and if it requires auth then the guildid has to be specified
|
||||||
if (!metadata.ContainsKey("guildid"))
|
if (string.IsNullOrWhiteSpace(gidString))
|
||||||
throw new RpcException(new(StatusCode.Unauthenticated, "guildid has to be specified."));
|
throw new RpcException(new(StatusCode.Unauthenticated, "guildid has to be specified."));
|
||||||
|
|
||||||
var userId = ulong.Parse(metadata["userid"]);
|
var userId = ulong.Parse(metadata["userid"]);
|
||||||
|
|
|
@ -9,22 +9,16 @@ public class GrpcApiService : IEService, IReadyExecutor
|
||||||
private Server? _app;
|
private Server? _app;
|
||||||
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly OtherSvc _other;
|
private readonly IEnumerable<IGrpcSvc> _svcs;
|
||||||
private readonly ExprsSvc _exprs;
|
|
||||||
private readonly GreetByeSvc _greet;
|
|
||||||
private readonly IBotCredsProvider _creds;
|
private readonly IBotCredsProvider _creds;
|
||||||
|
|
||||||
public GrpcApiService(
|
public GrpcApiService(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
OtherSvc other,
|
IEnumerable<IGrpcSvc> svcs,
|
||||||
ExprsSvc exprs,
|
|
||||||
GreetByeSvc greet,
|
|
||||||
IBotCredsProvider creds)
|
IBotCredsProvider creds)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_other = other;
|
_svcs = svcs;
|
||||||
_exprs = exprs;
|
|
||||||
_greet = greet;
|
|
||||||
_creds = creds;
|
_creds = creds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,21 +47,19 @@ public class GrpcApiService : IEService, IReadyExecutor
|
||||||
new[] { new KeyCertificatePair(cert.CertChain, cert.CertPrivateKey) });
|
new[] { new KeyCertificatePair(cert.CertChain, cert.CertPrivateKey) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_app = new()
|
||||||
_app = new Server()
|
|
||||||
{
|
{
|
||||||
Services =
|
|
||||||
{
|
|
||||||
GrpcOther.BindService(_other).Intercept(interceptor),
|
|
||||||
GrpcExprs.BindService(_exprs).Intercept(interceptor),
|
|
||||||
GrpcGreet.BindService(_greet).Intercept(interceptor),
|
|
||||||
},
|
|
||||||
Ports =
|
Ports =
|
||||||
{
|
{
|
||||||
new(host, port, serverCreds),
|
new(host, port, serverCreds),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foreach (var svc in _svcs)
|
||||||
|
{
|
||||||
|
_app.Services.Add(svc.Bind().Intercept(interceptor));
|
||||||
|
}
|
||||||
|
|
||||||
_app.Start();
|
_app.Start();
|
||||||
|
|
||||||
Log.Information("Grpc Api Server started on port {Host}:{Port}", host, port);
|
Log.Information("Grpc Api Server started on port {Host}:{Port}", host, port);
|
||||||
|
|
8
src/EllieBot/Services/IGrpcSvc.cs
Normal file
8
src/EllieBot/Services/IGrpcSvc.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
using Grpc.Core;
|
||||||
|
|
||||||
|
namespace EllieBot.GrpcApi;
|
||||||
|
|
||||||
|
public interface IGrpcSvc
|
||||||
|
{
|
||||||
|
ServerServiceDefinition Bind();
|
||||||
|
}
|
|
@ -287,9 +287,9 @@ public sealed partial class ResponseBuilder
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder UserBasedMentions()
|
public ResponseBuilder UserBasedMentions(IGuildUser? permUser = null)
|
||||||
{
|
{
|
||||||
sanitizeMentions = !((InternalResolveUser() as IGuildUser)?.GuildPermissions.MentionEveryone ?? false);
|
sanitizeMentions = !((InternalResolveUser() as IGuildUser ?? permUser)?.GuildPermissions.MentionEveryone ?? false);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,4 +52,14 @@ public class StoopidTime
|
||||||
Time = ts
|
Time = ts
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static implicit operator TimeSpan(StoopidTime st)
|
||||||
|
=> st.Time;
|
||||||
|
|
||||||
|
public static implicit operator StoopidTime(TimeSpan ts)
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Input = ts.ToString(),
|
||||||
|
Time = ts
|
||||||
|
};
|
||||||
}
|
}
|
Loading…
Reference in a new issue