mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
dev: Removed discrim from the database
add: .translateflags command add: captcha to timely, configurable in .conf gambling change: change bonuses for patreon rewards fix: nunchi message color fix
This commit is contained in:
703
CHANGELOG.md
703
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@ public static class DiscordUserExtensions
|
|||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Username = username,
|
Username = username,
|
||||||
Discriminator = discrim,
|
|
||||||
AvatarId = avatarId,
|
AvatarId = avatarId,
|
||||||
TotalXp = 0,
|
TotalXp = 0,
|
||||||
CurrencyAmount = 0
|
CurrencyAmount = 0
|
||||||
@@ -33,7 +32,6 @@ public static class DiscordUserExtensions
|
|||||||
old => new()
|
old => new()
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
Discriminator = discrim,
|
|
||||||
AvatarId = avatarId
|
AvatarId = avatarId
|
||||||
},
|
},
|
||||||
() => new()
|
() => new()
|
||||||
@@ -49,8 +47,7 @@ public static class DiscordUserExtensions
|
|||||||
() => new()
|
() => new()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Username = "Unknown",
|
Username = "??Unknown",
|
||||||
Discriminator = "????",
|
|
||||||
AvatarId = string.Empty,
|
AvatarId = string.Empty,
|
||||||
TotalXp = 0,
|
TotalXp = 0,
|
||||||
CurrencyAmount = 0
|
CurrencyAmount = 0
|
||||||
|
@@ -7,7 +7,7 @@ public class DiscordUser : DbEntity
|
|||||||
{
|
{
|
||||||
public ulong UserId { get; set; }
|
public ulong UserId { get; set; }
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string Discriminator { get; set; }
|
// public string Discriminator { get; set; }
|
||||||
public string AvatarId { get; set; }
|
public string AvatarId { get; set; }
|
||||||
|
|
||||||
public int? ClubId { get; set; }
|
public int? ClubId { get; set; }
|
||||||
@@ -27,9 +27,6 @@ public class DiscordUser : DbEntity
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(Discriminator) || Discriminator == "0000")
|
return Username;
|
||||||
return Username;
|
|
||||||
|
|
||||||
return Username + "#" + Discriminator;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
8
src/NadekoBot/Db/Models/FlagTranslateChannel.cs
Normal file
8
src/NadekoBot/Db/Models/FlagTranslateChannel.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#nullable disable
|
||||||
|
namespace NadekoBot.Db.Models;
|
||||||
|
|
||||||
|
public class FlagTranslateChannel : DbEntity
|
||||||
|
{
|
||||||
|
public ulong GuildId { get; set; }
|
||||||
|
public ulong ChannelId { get; set; }
|
||||||
|
}
|
@@ -73,6 +73,14 @@ public abstract class NadekoContext : DbContext
|
|||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
#region Flag Translate
|
||||||
|
|
||||||
|
modelBuilder.Entity<FlagTranslateChannel>()
|
||||||
|
.HasIndex(x => new { x.GuildId, x.ChannelId })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region NCanvas
|
#region NCanvas
|
||||||
|
|
||||||
modelBuilder.Entity<NCPixel>()
|
modelBuilder.Entity<NCPixel>()
|
||||||
|
@@ -5,6 +5,11 @@ namespace NadekoBot.Migrations;
|
|||||||
|
|
||||||
public static class MigrationQueries
|
public static class MigrationQueries
|
||||||
{
|
{
|
||||||
|
public static void UpdateUsernames(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql("UPDATE DiscordUser SET Username = '??' + Username WHERE Discriminator = '????';");
|
||||||
|
}
|
||||||
|
|
||||||
public static void MigrateRero(MigrationBuilder migrationBuilder)
|
public static void MigrateRero(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
if (migrationBuilder.IsSqlite())
|
if (migrationBuilder.IsSqlite())
|
||||||
|
3851
src/NadekoBot/Migrations/PostgreSql/20241102022956_no-discrim-and-flag-translate.Designer.cs
generated
Normal file
3851
src/NadekoBot/Migrations/PostgreSql/20241102022956_no-discrim-and-flag-translate.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace NadekoBot.Migrations.PostgreSql
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class nodiscrimandflagtranslate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
MigrationQueries.UpdateUsernames(migrationBuilder);
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "discriminator",
|
||||||
|
table: "discorduser");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "flagtranslatechannel",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
guildid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
||||||
|
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_flagtranslatechannel", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_flagtranslatechannel_guildid_channelid",
|
||||||
|
table: "flagtranslatechannel",
|
||||||
|
columns: new[] { "guildid", "channelid" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "flagtranslatechannel");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "discriminator",
|
||||||
|
table: "discorduser",
|
||||||
|
type: "text",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -751,10 +751,6 @@ namespace NadekoBot.Migrations.PostgreSql
|
|||||||
.HasColumnType("timestamp without time zone")
|
.HasColumnType("timestamp without time zone")
|
||||||
.HasColumnName("dateadded");
|
.HasColumnName("dateadded");
|
||||||
|
|
||||||
b.Property<string>("Discriminator")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("discriminator");
|
|
||||||
|
|
||||||
b.Property<bool>("IsClubAdmin")
|
b.Property<bool>("IsClubAdmin")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
@@ -998,6 +994,37 @@ namespace NadekoBot.Migrations.PostgreSql
|
|||||||
b.ToTable("filteredword", (string)null);
|
b.ToTable("filteredword", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Db.Models.FlagTranslateChannel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<decimal>("ChannelId")
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("channelid");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DateAdded")
|
||||||
|
.HasColumnType("timestamp without time zone")
|
||||||
|
.HasColumnName("dateadded");
|
||||||
|
|
||||||
|
b.Property<decimal>("GuildId")
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("guildid");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_flagtranslatechannel");
|
||||||
|
|
||||||
|
b.HasIndex("GuildId", "ChannelId")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_flagtranslatechannel_guildid_channelid");
|
||||||
|
|
||||||
|
b.ToTable("flagtranslatechannel", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
|
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
2973
src/NadekoBot/Migrations/Sqlite/20241102022949_no-discrim-and-flag-translate.Designer.cs
generated
Normal file
2973
src/NadekoBot/Migrations/Sqlite/20241102022949_no-discrim-and-flag-translate.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace NadekoBot.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class nodiscrimandflagtranslate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
MigrationQueries.UpdateUsernames(migrationBuilder);
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Discriminator",
|
||||||
|
table: "DiscordUser");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "FlagTranslateChannel",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||||
|
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||||
|
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_FlagTranslateChannel", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_FlagTranslateChannel_GuildId_ChannelId",
|
||||||
|
table: "FlagTranslateChannel",
|
||||||
|
columns: new[] { "GuildId", "ChannelId" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "FlagTranslateChannel");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Discriminator",
|
||||||
|
table: "DiscordUser",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -560,9 +560,6 @@ namespace NadekoBot.Migrations
|
|||||||
b.Property<DateTime?>("DateAdded")
|
b.Property<DateTime?>("DateAdded")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Discriminator")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<bool>("IsClubAdmin")
|
b.Property<bool>("IsClubAdmin")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("INTEGER")
|
.HasColumnType("INTEGER")
|
||||||
@@ -743,6 +740,29 @@ namespace NadekoBot.Migrations
|
|||||||
b.ToTable("FilteredWord");
|
b.ToTable("FilteredWord");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Db.Models.FlagTranslateChannel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<ulong>("ChannelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DateAdded")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<ulong>("GuildId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GuildId", "ChannelId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("FlagTranslateChannel");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
|
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
@@ -453,7 +453,6 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||||||
{
|
{
|
||||||
x.UserId,
|
x.UserId,
|
||||||
x.Username,
|
x.Username,
|
||||||
x.Discriminator
|
|
||||||
})
|
})
|
||||||
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
|
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
|
||||||
.ToArrayAsyncEF();
|
.ToArrayAsyncEF();
|
||||||
@@ -465,12 +464,11 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||||||
UserId = x.Id,
|
UserId = x.Id,
|
||||||
AvatarId = x.AvatarId,
|
AvatarId = x.AvatarId,
|
||||||
Username = x.Username,
|
Username = x.Username,
|
||||||
Discriminator = x.Discriminator
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
|
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
|
||||||
var toUpdateUserIds = presentDbUsers
|
var toUpdateUserIds = presentDbUsers
|
||||||
.Where(x => x.Username == "Unknown" && x.Discriminator == "????")
|
.Where(x => x.Username.StartsWith("??"))
|
||||||
.Select(x => x.UserId)
|
.Select(x => x.UserId)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
@@ -481,7 +479,6 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
|||||||
.UpdateAsync(x => new DiscordUser()
|
.UpdateAsync(x => new DiscordUser()
|
||||||
{
|
{
|
||||||
Username = user.Username,
|
Username = user.Username,
|
||||||
Discriminator = user.Discriminator,
|
|
||||||
|
|
||||||
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
|
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
|
||||||
AvatarId = user.AvatarId,
|
AvatarId = user.AvatarId,
|
||||||
|
@@ -603,7 +603,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
.Where(wi => wi.ClaimerId == waifuId)
|
.Where(wi => wi.ClaimerId == waifuId)
|
||||||
.Select(wi => wi.WaifuId)
|
.Select(wi => wi.WaifuId)
|
||||||
.Contains(x.Id))
|
.Contains(x.Id))
|
||||||
.Select(x => $"{x.Username}#{x.Discriminator}")
|
.Select(x => x.Username)
|
||||||
.ToListAsyncEF();
|
.ToListAsyncEF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,7 +615,7 @@ public class WaifuService : INService, IReadyExecutor
|
|||||||
.Where(wi => wi.AffinityId == waifuId)
|
.Where(wi => wi.AffinityId == waifuId)
|
||||||
.Select(wi => wi.WaifuId)
|
.Select(wi => wi.WaifuId)
|
||||||
.Contains(x.Id))
|
.Contains(x.Id))
|
||||||
.Select(x => $"{x.Username}#{x.Discriminator}")
|
.Select(x => x.Username)
|
||||||
.ToListAsyncEF();
|
.ToListAsyncEF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,15 +42,12 @@ public static class WaifuExtensions
|
|||||||
{
|
{
|
||||||
Affinity = x.Affinity == null
|
Affinity = x.Affinity == null
|
||||||
? null
|
? null
|
||||||
: x.Affinity.Username
|
: x.Affinity.Username,
|
||||||
+ (x.Affinity.Discriminator != "0000" ? "#" + x.Affinity.Discriminator : ""),
|
|
||||||
ClaimerName =
|
ClaimerName =
|
||||||
x.Claimer == null
|
x.Claimer == null
|
||||||
? null
|
? null
|
||||||
: x.Claimer.Username
|
: x.Claimer.Username,
|
||||||
+ (x.Claimer.Discriminator != "0000" ? "#" + x.Claimer.Discriminator : ""),
|
WaifuName = x.Waifu.Username,
|
||||||
WaifuName = x.Waifu.Username
|
|
||||||
+ (x.Waifu.Discriminator != "0000" ? "#" + x.Waifu.Discriminator : ""),
|
|
||||||
Price = x.Price
|
Price = x.Price
|
||||||
})
|
})
|
||||||
.ToListAsyncEF();
|
.ToListAsyncEF();
|
||||||
@@ -62,7 +59,7 @@ public static class WaifuExtensions
|
|||||||
public static ulong GetWaifuUserId(this DbSet<WaifuInfo> waifus, ulong ownerId, string name)
|
public static ulong GetWaifuUserId(this DbSet<WaifuInfo> waifus, ulong ownerId, string name)
|
||||||
=> waifus.AsQueryable()
|
=> waifus.AsQueryable()
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.Claimer.UserId == ownerId && x.Waifu.Username + "#" + x.Waifu.Discriminator == name)
|
.Where(x => x.Claimer.UserId == ownerId && x.Waifu.Username == name)
|
||||||
.Select(x => x.Waifu.UserId)
|
.Select(x => x.Waifu.UserId)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
@@ -100,7 +97,7 @@ public static class WaifuExtensions
|
|||||||
ctx.Set<DiscordUser>()
|
ctx.Set<DiscordUser>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(u => u.UserId == userId)
|
.Where(u => u.UserId == userId)
|
||||||
.Select(u => u.Username + "#" + u.Discriminator)
|
.Select(u => u.Username)
|
||||||
.FirstOrDefault(),
|
.FirstOrDefault(),
|
||||||
AffinityCount =
|
AffinityCount =
|
||||||
ctx.Set<WaifuUpdate>()
|
ctx.Set<WaifuUpdate>()
|
||||||
@@ -112,14 +109,14 @@ public static class WaifuExtensions
|
|||||||
ctx.Set<DiscordUser>()
|
ctx.Set<DiscordUser>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(u => u.Id == w.AffinityId)
|
.Where(u => u.Id == w.AffinityId)
|
||||||
.Select(u => u.Username + "#" + u.Discriminator)
|
.Select(u => u.Username)
|
||||||
.FirstOrDefault(),
|
.FirstOrDefault(),
|
||||||
ClaimCount = ctx.Set<WaifuInfo>().AsQueryable().Count(x => x.ClaimerId == w.WaifuId),
|
ClaimCount = ctx.Set<WaifuInfo>().AsQueryable().Count(x => x.ClaimerId == w.WaifuId),
|
||||||
ClaimerName =
|
ClaimerName =
|
||||||
ctx.Set<DiscordUser>()
|
ctx.Set<DiscordUser>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(u => u.Id == w.ClaimerId)
|
.Where(u => u.Id == w.ClaimerId)
|
||||||
.Select(u => u.Username + "#" + u.Discriminator)
|
.Select(u => u.Username)
|
||||||
.FirstOrDefault(),
|
.FirstOrDefault(),
|
||||||
DivorceCount =
|
DivorceCount =
|
||||||
ctx.Set<WaifuUpdate>()
|
ctx.Set<WaifuUpdate>()
|
||||||
|
@@ -29,7 +29,7 @@ public partial class Games
|
|||||||
if (!await nunchi.Join(ctx.User.Id, ctx.User.ToString()))
|
if (!await nunchi.Join(ctx.User.Id, ctx.User.ToString()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await Response().Error(strs.nunchi_joined(nunchi.ParticipantCount)).SendAsync();
|
await Response().Confirm(strs.nunchi_joined(nunchi.ParticipantCount)).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -122,11 +122,11 @@ public sealed class CurrencyRewardService : INService, IReadyExecutor
|
|||||||
var dollarValue = pledgeCents / 100;
|
var dollarValue = pledgeCents / 100;
|
||||||
percentBonus = dollarValue switch
|
percentBonus = dollarValue switch
|
||||||
{
|
{
|
||||||
>= 100 => 100,
|
>= 100 => 20,
|
||||||
>= 50 => 50,
|
>= 50 => 10,
|
||||||
>= 20 => 20,
|
>= 20 => 5,
|
||||||
>= 10 => 10,
|
>= 10 => 3,
|
||||||
>= 5 => 5,
|
>= 5 => 1,
|
||||||
_ => 0
|
_ => 0
|
||||||
};
|
};
|
||||||
return (long)(modifiedAmount * (1 + (percentBonus / 100.0f)));
|
return (long)(modifiedAmount * (1 + (percentBonus / 100.0f)));
|
||||||
|
191
src/NadekoBot/Modules/Searches/Translate/FlagTranslateService.cs
Normal file
191
src/NadekoBot/Modules/Searches/Translate/FlagTranslateService.cs
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
#nullable disable
|
||||||
|
using LinqToDB;
|
||||||
|
using LinqToDB.EntityFrameworkCore;
|
||||||
|
using NadekoBot.Common.ModuleBehaviors;
|
||||||
|
using NadekoBot.Db.Models;
|
||||||
|
using System.Collections.Frozen;
|
||||||
|
|
||||||
|
namespace NadekoBot.Modules.Searches;
|
||||||
|
|
||||||
|
public sealed partial class FlagTranslateService : IReadyExecutor, INService
|
||||||
|
{
|
||||||
|
private readonly IBotCreds _creds;
|
||||||
|
private readonly DiscordSocketClient _client;
|
||||||
|
private readonly TranslateService _ts;
|
||||||
|
private readonly IMessageSenderService _sender;
|
||||||
|
private IReadOnlyDictionary<string, string> _supportedFlags;
|
||||||
|
private readonly DbService _db;
|
||||||
|
private ConcurrentHashSet<ulong> _enabledChannels;
|
||||||
|
private readonly IBotCache _cache;
|
||||||
|
|
||||||
|
// disallow same message being translated multiple times to the same language
|
||||||
|
private readonly ConcurrentHashSet<(ulong, string)> _msgLangs = new();
|
||||||
|
|
||||||
|
public FlagTranslateService(
|
||||||
|
IBotCreds creds,
|
||||||
|
DiscordSocketClient client,
|
||||||
|
TranslateService ts,
|
||||||
|
IMessageSenderService sender,
|
||||||
|
DbService db,
|
||||||
|
IBotCache cache)
|
||||||
|
{
|
||||||
|
_creds = creds;
|
||||||
|
_client = client;
|
||||||
|
_ts = ts;
|
||||||
|
_sender = sender;
|
||||||
|
_db = db;
|
||||||
|
_cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnReadyAsync()
|
||||||
|
{
|
||||||
|
_supportedFlags = COUNTRIES
|
||||||
|
.Split('\n')
|
||||||
|
.Select(x => x.Split(' '))
|
||||||
|
.ToDictionary(x => x[0], x => x[1].TrimEnd())
|
||||||
|
.ToFrozenDictionary();
|
||||||
|
|
||||||
|
await using (var uow = _db.GetDbContext())
|
||||||
|
{
|
||||||
|
_enabledChannels = (await uow.GetTable<FlagTranslateChannel>()
|
||||||
|
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||||
|
_creds.TotalShards,
|
||||||
|
_client.ShardId))
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.ChannelId,
|
||||||
|
x.GuildId
|
||||||
|
})
|
||||||
|
.ToListAsyncLinqToDB())
|
||||||
|
.Select(x => x.ChannelId)
|
||||||
|
.ToHashSet()
|
||||||
|
.ToConcurrentSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
_client.ReactionAdded += OnReactionAdded;
|
||||||
|
|
||||||
|
var periodicCleanup = new PeriodicTimer(TimeSpan.FromHours(24));
|
||||||
|
|
||||||
|
while (await periodicCleanup.WaitForNextTickAsync())
|
||||||
|
{
|
||||||
|
_msgLangs.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int FLAG_START = 127462;
|
||||||
|
|
||||||
|
private static TypedKey<bool> CdKey(ulong userId)
|
||||||
|
=> new($"flagtranslate:{userId}");
|
||||||
|
|
||||||
|
private Task OnReactionAdded(
|
||||||
|
Cacheable<IUserMessage, ulong> arg1,
|
||||||
|
Cacheable<IMessageChannel, ulong> arg2,
|
||||||
|
SocketReaction reaction)
|
||||||
|
{
|
||||||
|
if (!_enabledChannels.Contains(reaction.Channel.Id))
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
var runes = reaction.Emote.Name.EnumerateRunes();
|
||||||
|
if (!runes.MoveNext()
|
||||||
|
|| runes.Current is not { Value: >= 127462 and <= 127487 } l1
|
||||||
|
|| !runes.MoveNext()
|
||||||
|
|| runes.Current is not { Value: >= 127462 and <= 127487 } l2)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
if (reaction.Channel is not SocketTextChannel tc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var user = await ((IGuild)tc.Guild).GetUserAsync(reaction.UserId);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!user.GetPermissions(tc).SendMessages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!tc.Guild.CurrentUser.GetPermissions(tc).SendMessages
|
||||||
|
|| !tc.Guild.CurrentUser.GetPermissions(tc).EmbedLinks)
|
||||||
|
{
|
||||||
|
await Disable(tc.Guild.Id, tc.Id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1 = (char)(l1.Value - FLAG_START + 65);
|
||||||
|
var c2 = (char)(l2.Value - FLAG_START + 65);
|
||||||
|
|
||||||
|
var code = $"{c1}{c2}".ToUpper();
|
||||||
|
|
||||||
|
if (!_supportedFlags.TryGetValue(code, out var lang))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_msgLangs.Add((reaction.MessageId, lang)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var result = await _cache.GetAsync(CdKey(reaction.UserId));
|
||||||
|
if (result.TryPickT0(out _, out _))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await _cache.AddAsync(CdKey(reaction.UserId), true, TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
|
var msg = await arg1.GetOrDownloadAsync();
|
||||||
|
|
||||||
|
var response = await _ts.Translate("", lang, msg.Content).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await msg.ReplyAsync(embed: _sender.CreateEmbed()
|
||||||
|
.WithOkColor()
|
||||||
|
.WithFooter(user.ToString() ?? reaction.UserId.ToString(),
|
||||||
|
user.RealAvatarUrl().ToString())
|
||||||
|
.WithDescription(response)
|
||||||
|
.WithAuthor(reaction.Emote.ToString())
|
||||||
|
.Build(),
|
||||||
|
allowedMentions: AllowedMentions.None
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Disable(ulong guildId, ulong tcId)
|
||||||
|
{
|
||||||
|
if (!_enabledChannels.TryRemove(tcId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
await uow.GetTable<FlagTranslateChannel>()
|
||||||
|
.Where(x => x.GuildId == guildId
|
||||||
|
&& x.ChannelId == tcId)
|
||||||
|
.DeleteAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> Toggle(ulong guildId, ulong tcId)
|
||||||
|
{
|
||||||
|
if (_enabledChannels.Contains(tcId))
|
||||||
|
{
|
||||||
|
await Disable(guildId, tcId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Enable(guildId, tcId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Enable(ulong guildId, ulong tcId)
|
||||||
|
{
|
||||||
|
if (!_enabledChannels.Add(tcId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
await uow.GetTable<FlagTranslateChannel>()
|
||||||
|
.InsertAsync(() => new FlagTranslateChannel
|
||||||
|
{
|
||||||
|
GuildId = guildId,
|
||||||
|
ChannelId = tcId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,73 @@
|
|||||||
|
namespace NadekoBot.Modules.Searches;
|
||||||
|
|
||||||
|
public partial class FlagTranslateService
|
||||||
|
{
|
||||||
|
private const string COUNTRIES = """
|
||||||
|
CN zh
|
||||||
|
IN hi
|
||||||
|
US en
|
||||||
|
ID id
|
||||||
|
PK ur
|
||||||
|
BR pt
|
||||||
|
NG ha
|
||||||
|
BD bn
|
||||||
|
RU ru
|
||||||
|
JP ja
|
||||||
|
MX es
|
||||||
|
PH tl
|
||||||
|
VN vi
|
||||||
|
EG ar
|
||||||
|
ET am
|
||||||
|
DE de
|
||||||
|
IR fa
|
||||||
|
TR tr
|
||||||
|
TH th
|
||||||
|
FR fr
|
||||||
|
CD fr
|
||||||
|
MM my
|
||||||
|
UG en
|
||||||
|
MZ pt
|
||||||
|
ZA zu
|
||||||
|
CO es
|
||||||
|
BG bg
|
||||||
|
HR hr
|
||||||
|
MY ms
|
||||||
|
NL nl
|
||||||
|
RO ro
|
||||||
|
CZ cs
|
||||||
|
GR el
|
||||||
|
SK sk
|
||||||
|
PT pt
|
||||||
|
KR ko
|
||||||
|
IT it
|
||||||
|
ES es
|
||||||
|
RS sr
|
||||||
|
TN ar
|
||||||
|
PL pl
|
||||||
|
SD ar
|
||||||
|
CM fr
|
||||||
|
SN fr
|
||||||
|
ML fr
|
||||||
|
NE ha
|
||||||
|
BI fr
|
||||||
|
AO pt
|
||||||
|
AF ps
|
||||||
|
MA ar
|
||||||
|
DZ ar
|
||||||
|
GB en
|
||||||
|
AR es
|
||||||
|
ZW ny
|
||||||
|
KE sw
|
||||||
|
GH en
|
||||||
|
SA ar
|
||||||
|
IL he
|
||||||
|
IQ ar
|
||||||
|
UA ua
|
||||||
|
LY ar
|
||||||
|
KW ar
|
||||||
|
OM ar
|
||||||
|
YE ar
|
||||||
|
AL sq
|
||||||
|
AE ar
|
||||||
|
""";
|
||||||
|
}
|
@@ -44,12 +44,10 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||||||
foreach (var c in cs)
|
foreach (var c in cs)
|
||||||
{
|
{
|
||||||
_atcs[c.ChannelId] = c.AutoDelete;
|
_atcs[c.ChannelId] = c.AutoDelete;
|
||||||
_users[c.ChannelId] =
|
_users[c.ChannelId] = new(c.Users.ToDictionary(x => x.UserId, x => (x.Source.ToLower(), x.Target.ToLower())));
|
||||||
new(c.Users.ToDictionary(x => x.UserId, x => (x.Source.ToLower(), x.Target.ToLower())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(msg.Content))
|
if (string.IsNullOrWhiteSpace(msg.Content))
|
||||||
@@ -95,7 +93,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> Translate(string source, string target, string text = null)
|
public async Task<string> Translate(string source, string target, string text)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
throw new ArgumentException("Text is empty or null", nameof(text));
|
throw new ArgumentException("Text is empty or null", nameof(text));
|
||||||
|
@@ -6,6 +6,14 @@ public partial class Searches
|
|||||||
[Group]
|
[Group]
|
||||||
public partial class TranslateCommands : NadekoModule<ITranslateService>
|
public partial class TranslateCommands : NadekoModule<ITranslateService>
|
||||||
{
|
{
|
||||||
|
private readonly FlagTranslateService _flagSvc;
|
||||||
|
|
||||||
|
public TranslateCommands(FlagTranslateService flagSvc)
|
||||||
|
{
|
||||||
|
_flagSvc = flagSvc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum AutoDeleteAutoTranslate
|
public enum AutoDeleteAutoTranslate
|
||||||
{
|
{
|
||||||
Del,
|
Del,
|
||||||
@@ -91,5 +99,18 @@ public partial class Searches
|
|||||||
|
|
||||||
await Response().Embed(eb).SendAsync();
|
await Response().Embed(eb).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(ChannelPermission.ManageChannels)]
|
||||||
|
[BotPerm(ChannelPermission.SendMessages | ChannelPermission.EmbedLinks)]
|
||||||
|
public async Task TranslateFlags()
|
||||||
|
{
|
||||||
|
var enabled = await _flagSvc.Toggle(ctx.Guild.Id, ctx.Channel.Id);
|
||||||
|
if (enabled)
|
||||||
|
await Response().Confirm(strs.trfl_enabled).SendAsync();
|
||||||
|
else
|
||||||
|
await Response().Confirm(strs.trfl_disabled).SendAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -28,6 +28,8 @@ public class XpSvc : GrpcXp.GrpcXpBase, IGrpcSvc, INService
|
|||||||
GetXpSettingsRequest request,
|
GetXpSettingsRequest request,
|
||||||
ServerCallContext context)
|
ServerCallContext context)
|
||||||
{
|
{
|
||||||
|
await Task.Yield();
|
||||||
|
|
||||||
var guild = _client.GetGuild(request.GuildId);
|
var guild = _client.GetGuild(request.GuildId);
|
||||||
|
|
||||||
if (guild is null)
|
if (guild is null)
|
||||||
@@ -54,6 +56,26 @@ public class XpSvc : GrpcXp.GrpcXpBase, IGrpcSvc, INService
|
|||||||
Name = guild.GetRole(x)?.Name ?? "????"
|
Name = guild.GetRole(x)?.Name ?? "????"
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
var curRews = _xp.GetCurrencyRewards(request.GuildId);
|
||||||
|
var roleRews = _xp.GetRoleRewards(request.GuildId);
|
||||||
|
|
||||||
|
var rews = curRews.Select(x => new RewItemReply()
|
||||||
|
{
|
||||||
|
Level = x.Level,
|
||||||
|
Type = "Currency",
|
||||||
|
Value = x.Amount.ToString()
|
||||||
|
});
|
||||||
|
|
||||||
|
rews = rews.Concat(roleRews.Select(x => new RewItemReply()
|
||||||
|
{
|
||||||
|
Level = x.Level,
|
||||||
|
Type = "Role",
|
||||||
|
Value = guild.GetRole(x.RoleId)?.ToString() ?? x.RoleId.ToString()
|
||||||
|
}))
|
||||||
|
.OrderBy(x => x.Level);
|
||||||
|
|
||||||
|
reply.Rewards.AddRange(rews);
|
||||||
|
|
||||||
reply.ServerExcluded = isServerExcluded;
|
reply.ServerExcluded = isServerExcluded;
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
|
@@ -201,9 +201,12 @@ public sealed partial class GoogleApiService : IGoogleApiService, INService
|
|||||||
{
|
{
|
||||||
string text;
|
string text;
|
||||||
|
|
||||||
if (!Languages.ContainsKey(sourceLanguage) || !Languages.ContainsKey(targetLanguage))
|
if (!Languages.ContainsKey(targetLanguage))
|
||||||
throw new ArgumentException(nameof(sourceLanguage) + "/" + nameof(targetLanguage));
|
throw new ArgumentException(nameof(sourceLanguage) + "/" + nameof(targetLanguage));
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(sourceLanguage) || !Languages.ContainsKey(sourceLanguage))
|
||||||
|
sourceLanguage = "auto";
|
||||||
|
|
||||||
|
|
||||||
var url = new Uri(string.Format(
|
var url = new Uri(string.Format(
|
||||||
"https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
|
"https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
|
||||||
@@ -223,7 +226,7 @@ public sealed partial class GoogleApiService : IGoogleApiService, INService
|
|||||||
private string ConvertToLanguageCode(string language)
|
private string ConvertToLanguageCode(string language)
|
||||||
{
|
{
|
||||||
Languages.TryGetValue(language, out var mode);
|
Languages.TryGetValue(language, out var mode);
|
||||||
return mode;
|
return string.IsNullOrWhiteSpace(mode) ? language : mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -154,7 +154,6 @@ public sealed partial class GoogleApiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
Languages = langs;
|
Languages = langs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -77,8 +77,7 @@ public class DefaultWallet : IWallet
|
|||||||
.InsertOrUpdateAsync(() => new()
|
.InsertOrUpdateAsync(() => new()
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Username = "Unknown",
|
Username = "??Unknown",
|
||||||
Discriminator = "????",
|
|
||||||
CurrencyAmount = amount,
|
CurrencyAmount = amount,
|
||||||
},
|
},
|
||||||
(old) => new()
|
(old) => new()
|
||||||
|
@@ -193,7 +193,7 @@ public sealed class StatsService : IStatsService, IReadyExecutor, INService
|
|||||||
Id = g.Id,
|
Id = g.Id,
|
||||||
IconUrl = g.IconUrl,
|
IconUrl = g.IconUrl,
|
||||||
Name = g.Name,
|
Name = g.Name,
|
||||||
Owner = (await ig.GetUserAsync(g.OwnerId))?.Username ?? "Unknown",
|
Owner = (await ig.GetUserAsync(g.OwnerId))?.Username ?? "??Unknown",
|
||||||
OwnerId = g.OwnerId,
|
OwnerId = g.OwnerId,
|
||||||
CreatedAt = g.CreatedAt.UtcDateTime,
|
CreatedAt = g.CreatedAt.UtcDateTime,
|
||||||
VoiceChannels = g.VoiceChannels.Count,
|
VoiceChannels = g.VoiceChannels.Count,
|
||||||
|
@@ -1444,4 +1444,9 @@ ncpixel:
|
|||||||
- ncp
|
- ncp
|
||||||
- ncgp
|
- ncgp
|
||||||
ncreset:
|
ncreset:
|
||||||
- ncreset
|
- ncreset
|
||||||
|
translateflags:
|
||||||
|
- translateflags
|
||||||
|
- trfl
|
||||||
|
- fltr
|
||||||
|
- transflags
|
@@ -4632,5 +4632,13 @@ ncreset:
|
|||||||
This command is dangerous and irreversible.
|
This command is dangerous and irreversible.
|
||||||
ex:
|
ex:
|
||||||
- ''
|
- ''
|
||||||
|
params:
|
||||||
|
- { }
|
||||||
|
translateflags:
|
||||||
|
desc: |-
|
||||||
|
Toggles translate flags on the current channel.
|
||||||
|
Reacting with a country flag will translate the message to that country's language.
|
||||||
|
ex:
|
||||||
|
- ''
|
||||||
params:
|
params:
|
||||||
- { }
|
- { }
|
@@ -1111,5 +1111,7 @@
|
|||||||
"nc_hint": "Use `{0}nczoom x y` command to zoom in. Image is {1}x{2} pixels.",
|
"nc_hint": "Use `{0}nczoom x y` command to zoom in. Image is {1}x{2} pixels.",
|
||||||
"nc_insuff_payment": "Invalid payment.",
|
"nc_insuff_payment": "Invalid payment.",
|
||||||
"invalid_img_size": "Image must to be {0}x{1} pixels.",
|
"invalid_img_size": "Image must to be {0}x{1} pixels.",
|
||||||
"no_attach_found": "No attachment found. Please send the image along with this command."
|
"no_attach_found": "No attachment found. Please send the image along with this command." ,
|
||||||
|
"trfl_enabled": "Flag translation enabled on this channel. Reacting to a message with a flag will translate it to that language.",
|
||||||
|
"trfl_disabled": "Flag translation disabled."
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user