Removed some unnecessary fonts
Removed gold/silver frames as they are unnecessary Updated XP card and updated xp_template.json Started simplification of Patron system. There will only be 3 tiers
This commit is contained in:
parent
0ee5c0dd94
commit
6f64a15cd4
21 changed files with 800 additions and 606 deletions
src/EllieBot
|
@ -97,7 +97,7 @@ public sealed class Bot : IBot
|
|||
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
|
||||
uow.EnsureUserCreated(bot.Id, bot.Username, bot.AvatarId);
|
||||
}
|
||||
|
||||
// var svcs = new StandardKernel(new NinjectSettings()
|
||||
|
|
|
@ -17,7 +17,6 @@ public static class DiscordUserExtensions
|
|||
this DbContext ctx,
|
||||
ulong userId,
|
||||
string username,
|
||||
string discrim,
|
||||
string avatarId)
|
||||
=> ctx.GetTable<DiscordUser>()
|
||||
.InsertOrUpdate(
|
||||
|
@ -65,11 +64,10 @@ public static class DiscordUserExtensions
|
|||
this DbContext ctx,
|
||||
ulong userId,
|
||||
string username,
|
||||
string discrim,
|
||||
string avatarId,
|
||||
Func<IQueryable<DiscordUser>, IQueryable<DiscordUser>> includes = null)
|
||||
{
|
||||
ctx.EnsureUserCreated(userId, username, discrim, avatarId);
|
||||
ctx.EnsureUserCreated(userId, username, avatarId);
|
||||
|
||||
IQueryable<DiscordUser> queryable = ctx.Set<DiscordUser>();
|
||||
if (includes is not null)
|
||||
|
@ -78,13 +76,6 @@ public static class DiscordUserExtensions
|
|||
}
|
||||
|
||||
|
||||
public static int GetUserGlobalRank(this DbSet<DiscordUser> users, ulong id)
|
||||
=> users.AsQueryable()
|
||||
.Where(x => x.TotalXp
|
||||
> users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault())
|
||||
.Count()
|
||||
+ 1;
|
||||
|
||||
public static Task<List<DiscordUser>> GetTopRichest(
|
||||
this DbSet<DiscordUser> users,
|
||||
ulong botId,
|
||||
|
|
|
@ -180,17 +180,17 @@ public partial class Gambling
|
|||
|
||||
Color fontColor = Config.Slots.CurrencyFontColor;
|
||||
|
||||
bgImage.Mutate<Rgba32>(x => x.DrawText(new RichTextOptions(_fonts.DottyFont.CreateFont(65))
|
||||
bgImage.Mutate<Rgba32>(x => x.DrawText(new RichTextOptions(_fonts.NotoSans.CreateFont(35))
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
WrappingLength = 140,
|
||||
Origin = new(298, 100)
|
||||
Origin = new(295, 100)
|
||||
},
|
||||
((long)result.Won).ToString(),
|
||||
fontColor));
|
||||
|
||||
var bottomFont = _fonts.DottyFont.CreateFont(50);
|
||||
var bottomFont = _fonts.NotoSans.CreateFont(50);
|
||||
|
||||
bgImage.Mutate(x => x.DrawText(new RichTextOptions(bottomFont)
|
||||
{
|
||||
|
@ -206,7 +206,7 @@ public partial class Gambling
|
|||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Origin = new(393, 480)
|
||||
Origin = new(393, 479)
|
||||
},
|
||||
ownedAmount.ToString(),
|
||||
fontColor));
|
||||
|
|
|
@ -384,12 +384,9 @@ public sealed class PatronageService
|
|||
|
||||
return user.AmountCents switch
|
||||
{
|
||||
>= 10_000 => PatronTier.C,
|
||||
>= 5000 => PatronTier.L,
|
||||
>= 2000 => PatronTier.XX,
|
||||
>= 1000 => PatronTier.X,
|
||||
>= 500 => PatronTier.V,
|
||||
>= 100 => PatronTier.I,
|
||||
<= 200 => PatronTier.I,
|
||||
<= 1_000 => PatronTier.C,
|
||||
<= 5_000 => PatronTier.L,
|
||||
_ => PatronTier.None
|
||||
};
|
||||
}
|
||||
|
@ -402,12 +399,10 @@ public sealed class PatronageService
|
|||
public int PercentBonus(long amount)
|
||||
=> amount switch
|
||||
{
|
||||
>= 10_000 => 100,
|
||||
>= 5000 => 50,
|
||||
>= 2000 => 30,
|
||||
>= 1000 => 20,
|
||||
>= 500 => 10,
|
||||
_ => 0
|
||||
< 200 => 0,
|
||||
< 1_000 => 10,
|
||||
< 5_000 => 50,
|
||||
_ => 100
|
||||
};
|
||||
|
||||
private async Task SendWelcomeMessage(Patron patron)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#nullable disable
|
||||
using System.Text;
|
||||
using EllieBot.Modules.Patronage;
|
||||
|
||||
namespace EllieBot.Modules.Utility;
|
||||
|
@ -34,31 +33,35 @@ public partial class Utility
|
|||
{
|
||||
var guild = (IGuild)_client.GetGuild(guildId)
|
||||
?? await _client.Rest.GetGuildAsync(guildId);
|
||||
|
||||
|
||||
if (guild is null)
|
||||
return;
|
||||
|
||||
var ownername = await guild.GetUserAsync(guild.OwnerId);
|
||||
var textchn = (await guild.GetTextChannelsAsync()).Count;
|
||||
var voicechn = (await guild.GetVoiceChannelsAsync()).Count;
|
||||
var channels = $@"{GetText(strs.text_channels(textchn))}
|
||||
{GetText(strs.voice_channels(voicechn))}";
|
||||
var channels = $"""
|
||||
{GetText(strs.text_channels(textchn))}
|
||||
{GetText(strs.voice_channels(voicechn))}
|
||||
""";
|
||||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22);
|
||||
var features = guild.Features.Value.ToString();
|
||||
if (string.IsNullOrWhiteSpace(features))
|
||||
features = "-";
|
||||
|
||||
var embed = CreateEmbed()
|
||||
.WithAuthor(GetText(strs.server_info))
|
||||
.WithTitle(guild.Name)
|
||||
.AddField(GetText(strs.id), guild.Id.ToString(), true)
|
||||
.AddField(GetText(strs.owner), ownername.ToString(), true)
|
||||
.AddField(GetText(strs.members), (guild as SocketGuild)?.MemberCount.ToString() ?? guild.ApproximateMemberCount?.ToString() ?? "?", true)
|
||||
.AddField(GetText(strs.channels), channels, true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.roles), (guild.Roles.Count - 1).ToString(), true)
|
||||
.AddField(GetText(strs.features), features)
|
||||
.WithOkColor();
|
||||
.WithAuthor(GetText(strs.server_info))
|
||||
.WithTitle(guild.Name)
|
||||
.AddField(GetText(strs.id), guild.Id.ToString(), true)
|
||||
.AddField(GetText(strs.owner), ownername.ToString(), true)
|
||||
.AddField(GetText(strs.members),
|
||||
(guild as SocketGuild)?.MemberCount.ToString() ?? guild.ApproximateMemberCount?.ToString() ?? "?",
|
||||
true)
|
||||
.AddField(GetText(strs.channels), channels, true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.roles), (guild.Roles.Count - 1).ToString(), true)
|
||||
.AddField(GetText(strs.features), features)
|
||||
.WithOkColor();
|
||||
|
||||
if (Uri.IsWellFormedUriString(guild.IconUrl, UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(guild.IconUrl);
|
||||
|
@ -82,12 +85,12 @@ public partial class Utility
|
|||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22);
|
||||
var usercount = (await ch.GetUsersAsync().FlattenAsync()).Count();
|
||||
var embed = CreateEmbed()
|
||||
.WithTitle(ch.Name)
|
||||
.WithDescription(ch.Topic?.SanitizeMentions(true))
|
||||
.AddField(GetText(strs.id), ch.Id.ToString(), true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.users), usercount.ToString(), true)
|
||||
.WithOkColor();
|
||||
.WithTitle(ch.Name)
|
||||
.WithDescription(ch.Topic?.SanitizeMentions(true))
|
||||
.AddField(GetText(strs.id), ch.Id.ToString(), true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.users), usercount.ToString(), true)
|
||||
.WithOkColor();
|
||||
await Response().Embed(embed).SendAsync();
|
||||
}
|
||||
|
||||
|
@ -102,17 +105,17 @@ public partial class Utility
|
|||
.AddMilliseconds(role.Id >> 22);
|
||||
var usercount = role.Members.LongCount();
|
||||
var embed = CreateEmbed()
|
||||
.WithTitle(role.Name.TrimTo(128))
|
||||
.WithDescription(role.Permissions.ToList().Join(" | "))
|
||||
.AddField(GetText(strs.id), role.Id.ToString(), true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.users), usercount.ToString(), true)
|
||||
.AddField(GetText(strs.color),
|
||||
$"#{role.Color.R:X2}{role.Color.G:X2}{role.Color.B:X2}",
|
||||
true)
|
||||
.AddField(GetText(strs.mentionable), role.IsMentionable.ToString(), true)
|
||||
.AddField(GetText(strs.hoisted), role.IsHoisted.ToString(), true)
|
||||
.WithOkColor();
|
||||
.WithTitle(role.Name.TrimTo(128))
|
||||
.WithDescription(role.Permissions.ToList().Join(" | "))
|
||||
.AddField(GetText(strs.id), role.Id.ToString(), true)
|
||||
.AddField(GetText(strs.created_at), $"{createdAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.users), usercount.ToString(), true)
|
||||
.AddField(GetText(strs.color),
|
||||
$"#{role.Color.R:X2}{role.Color.G:X2}{role.Color.B:X2}",
|
||||
true)
|
||||
.AddField(GetText(strs.mentionable), role.IsMentionable.ToString(), true)
|
||||
.AddField(GetText(strs.hoisted), role.IsHoisted.ToString(), true)
|
||||
.WithOkColor();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(role.GetIconUrl()))
|
||||
embed = embed.WithThumbnailUrl(role.GetIconUrl());
|
||||
|
@ -130,31 +133,29 @@ public partial class Utility
|
|||
return;
|
||||
|
||||
var embed = CreateEmbed()
|
||||
.AddField(GetText(strs.name), $"**{user.Username}**#{user.Discriminator}", true);
|
||||
.AddField(GetText(strs.name), $"**{user.Username}**#{user.Discriminator}", true);
|
||||
if (!string.IsNullOrWhiteSpace(user.Nickname))
|
||||
embed.AddField(GetText(strs.nickname), user.Nickname, true);
|
||||
|
||||
var joinedAt = GetJoinedAt(user);
|
||||
|
||||
embed.AddField(GetText(strs.id), user.Id.ToString(), true)
|
||||
.AddField(GetText(strs.joined_server), $"{joinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}", true)
|
||||
.AddField(GetText(strs.joined_discord), $"{user.CreatedAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.roles),
|
||||
$"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions(true)}",
|
||||
true)
|
||||
.WithOkColor();
|
||||
.AddField(GetText(strs.joined_server), $"{joinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}", true)
|
||||
.AddField(GetText(strs.joined_discord), $"{user.CreatedAt:dd.MM.yyyy HH:mm}", true)
|
||||
.AddField(GetText(strs.roles),
|
||||
$"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions(true)}",
|
||||
true)
|
||||
.WithOkColor();
|
||||
|
||||
var mPatron = await _ps.GetPatronAsync(user.Id);
|
||||
|
||||
if (mPatron is {} patron && patron.Tier != PatronTier.None)
|
||||
if (mPatron is { } patron && patron.Tier != PatronTier.None)
|
||||
{
|
||||
embed.WithFooter(patron.Tier switch
|
||||
embed.WithFooter((int)patron.Tier switch
|
||||
{
|
||||
PatronTier.V => "❤️❤️",
|
||||
PatronTier.X => "❤️❤️❤️",
|
||||
PatronTier.XX => "❤️❤️❤️❤️",
|
||||
PatronTier.L => "❤️❤️❤️❤️❤️",
|
||||
_ => "❤️",
|
||||
< (int)PatronTier.X => "❤️",
|
||||
< (int)PatronTier.L => "❤️❤️❤️",
|
||||
_ => "❤️❤️❤️❤️❤️",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,15 +167,6 @@ public partial class Utility
|
|||
}
|
||||
|
||||
private DateTimeOffset? GetJoinedAt(IGuildUser user)
|
||||
{
|
||||
var joinedAt = user.JoinedAt;
|
||||
if (user.GuildId != 117523346618318850)
|
||||
return joinedAt;
|
||||
|
||||
if (user.Id == 351244576092192778)
|
||||
return new DateTimeOffset(2019, 12, 25, 9, 33, 0, TimeSpan.Zero);
|
||||
|
||||
return joinedAt;
|
||||
}
|
||||
=> user.JoinedAt;
|
||||
}
|
||||
}
|
|
@ -26,10 +26,6 @@ public class ClubService : IEService, IClubService
|
|||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var du = uow.GetOrCreateUser(user);
|
||||
var xp = new LevelStats(du.TotalXp);
|
||||
|
||||
if (xp.Level < 5)
|
||||
return ClubCreateResult.InsufficientLevel;
|
||||
|
||||
if (du.ClubId is not null)
|
||||
return ClubCreateResult.AlreadyInAClub;
|
||||
|
|
|
@ -3,7 +3,6 @@ using LinqToDB;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using Newtonsoft.Json;
|
||||
using SixLabors.Fonts;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
|
@ -600,17 +599,13 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var du = uow.GetOrCreateUser(user, set => set.Include(x => x.Club));
|
||||
var totalXp = du.TotalXp;
|
||||
var globalRank = uow.Set<DiscordUser>().GetUserGlobalRank(user.Id);
|
||||
var guildRank = await uow.Set<UserXpStats>().GetUserGuildRanking(user.Id, user.GuildId);
|
||||
var stats = uow.GetOrCreateUserXpStats(user.GuildId, user.Id);
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
return new(du,
|
||||
stats,
|
||||
new(totalXp),
|
||||
new(stats.Xp),
|
||||
globalRank,
|
||||
guildRank);
|
||||
}
|
||||
|
||||
|
@ -620,7 +615,6 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
return await GenerateXpImageAsync(stats);
|
||||
}
|
||||
|
||||
|
||||
public Task<(Stream Image, IImageFormat Format)> GenerateXpImageAsync(FullUserStats stats)
|
||||
=> Task.Run(async () =>
|
||||
{
|
||||
|
@ -662,8 +656,6 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
}
|
||||
}
|
||||
|
||||
var outlinePen = new SolidPen(Color.Black, 1f);
|
||||
|
||||
using var img = Image.Load<Rgba32>(bgBytes);
|
||||
|
||||
if (template.User.Name.Show)
|
||||
|
@ -687,8 +679,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
Origin = new(template.User.Name.Pos.X, template.User.Name.Pos.Y + 8)
|
||||
},
|
||||
"@" + username,
|
||||
Brushes.Solid(template.User.Name.Color),
|
||||
outlinePen);
|
||||
Brushes.Solid(template.User.Name.Color));
|
||||
|
||||
|
||||
//club name
|
||||
|
@ -707,8 +698,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
Origin = new(template.Club.Name.Pos.X + 50, template.Club.Name.Pos.Y - 8)
|
||||
},
|
||||
clubName,
|
||||
Brushes.Solid(template.Club.Name.Color),
|
||||
outlinePen);
|
||||
Brushes.Solid(template.Club.Name.Color));
|
||||
}
|
||||
|
||||
Font GetTruncatedFont(
|
||||
|
@ -728,68 +718,32 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
}
|
||||
|
||||
|
||||
if (template.User.GlobalLevel.Show)
|
||||
{
|
||||
// up to 83 width
|
||||
|
||||
var globalLevelFont = GetTruncatedFont(
|
||||
_fonts.NotoSans,
|
||||
template.User.GlobalLevel.FontSize,
|
||||
FontStyle.Bold,
|
||||
stats.Global.Level.ToString(),
|
||||
75);
|
||||
|
||||
|
||||
x.DrawText(stats.Global.Level.ToString(),
|
||||
globalLevelFont,
|
||||
template.User.GlobalLevel.Color,
|
||||
new(template.User.GlobalLevel.Pos.X, template.User.GlobalLevel.Pos.Y)); //level
|
||||
}
|
||||
|
||||
if (template.User.GuildLevel.Show)
|
||||
if (template.User.Level.Show)
|
||||
{
|
||||
var guildLevelFont = GetTruncatedFont(
|
||||
_fonts.NotoSans,
|
||||
template.User.GuildLevel.FontSize,
|
||||
template.User.Level.FontSize,
|
||||
FontStyle.Bold,
|
||||
stats.Guild.Level.ToString(),
|
||||
75);
|
||||
33);
|
||||
|
||||
|
||||
x.DrawText(stats.Guild.Level.ToString(),
|
||||
guildLevelFont,
|
||||
template.User.GuildLevel.Color,
|
||||
new(template.User.GuildLevel.Pos.X, template.User.GuildLevel.Pos.Y));
|
||||
template.User.Level.Color,
|
||||
new(template.User.Level.Pos.X, template.User.Level.Pos.Y));
|
||||
}
|
||||
|
||||
|
||||
var global = stats.Global;
|
||||
var guild = stats.Guild;
|
||||
|
||||
//xp bar
|
||||
if (template.User.Xp.Bar.Show)
|
||||
{
|
||||
var xpPercent = global.LevelXp / (float)global.RequiredXp;
|
||||
DrawXpBar(xpPercent, template.User.Xp.Bar.Global, img);
|
||||
xpPercent = guild.LevelXp / (float)guild.RequiredXp;
|
||||
var xpPercent = guild.LevelXp / (float)guild.RequiredXp;
|
||||
DrawXpBar(xpPercent, template.User.Xp.Bar.Guild, img);
|
||||
}
|
||||
|
||||
if (template.User.Xp.Global.Show)
|
||||
{
|
||||
x.DrawText(
|
||||
new RichTextOptions(_fonts.NotoSans.CreateFont(template.User.Xp.Global.FontSize,
|
||||
FontStyle.Bold))
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Origin = new(template.User.Xp.Global.Pos.X, template.User.Xp.Global.Pos.Y),
|
||||
},
|
||||
$"{global.LevelXp}/{global.RequiredXp}",
|
||||
Brushes.Solid(template.User.Xp.Global.Color),
|
||||
outlinePen);
|
||||
}
|
||||
|
||||
if (template.User.Xp.Guild.Show)
|
||||
{
|
||||
x.DrawText(
|
||||
|
@ -801,52 +755,30 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
Origin = new(template.User.Xp.Guild.Pos.X, template.User.Xp.Guild.Pos.Y)
|
||||
},
|
||||
$"{guild.LevelXp}/{guild.RequiredXp}",
|
||||
Brushes.Solid(template.User.Xp.Guild.Color),
|
||||
outlinePen);
|
||||
Brushes.Solid(template.User.Xp.Guild.Color));
|
||||
}
|
||||
|
||||
var rankPen = new SolidPen(Color.White, 1);
|
||||
//ranking
|
||||
if (template.User.GlobalRank.Show)
|
||||
{
|
||||
var globalRankStr = stats.GlobalRanking.ToString();
|
||||
|
||||
var globalRankFont = GetTruncatedFont(
|
||||
_fonts.UniSans,
|
||||
template.User.GlobalRank.FontSize,
|
||||
FontStyle.Bold,
|
||||
globalRankStr,
|
||||
68);
|
||||
|
||||
x.DrawText(
|
||||
new RichTextOptions(globalRankFont)
|
||||
{
|
||||
Origin = new(template.User.GlobalRank.Pos.X, template.User.GlobalRank.Pos.Y)
|
||||
},
|
||||
globalRankStr,
|
||||
Brushes.Solid(template.User.GlobalRank.Color),
|
||||
rankPen
|
||||
);
|
||||
}
|
||||
|
||||
if (template.User.GuildRank.Show)
|
||||
if (template.User.Rank.Show)
|
||||
{
|
||||
var guildRankStr = stats.GuildRanking.ToString();
|
||||
|
||||
var guildRankFont = GetTruncatedFont(
|
||||
_fonts.UniSans,
|
||||
template.User.GuildRank.FontSize,
|
||||
_fonts.NotoSans,
|
||||
template.User.Rank.FontSize,
|
||||
FontStyle.Bold,
|
||||
guildRankStr,
|
||||
43);
|
||||
22);
|
||||
|
||||
x.DrawText(
|
||||
new RichTextOptions(guildRankFont)
|
||||
{
|
||||
Origin = new(template.User.GuildRank.Pos.X, template.User.GuildRank.Pos.Y)
|
||||
Origin = new(template.User.Rank.Pos.X, template.User.Rank.Pos.Y)
|
||||
},
|
||||
guildRankStr,
|
||||
Brushes.Solid(template.User.GuildRank.Color),
|
||||
Brushes.Solid(template.User.Rank.Color),
|
||||
rankPen
|
||||
);
|
||||
}
|
||||
|
@ -908,19 +840,10 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
|
||||
private async Task DrawFrame(Image<Rgba32> img, ulong userId)
|
||||
{
|
||||
var patron = await _ps.GetPatronAsync(userId);
|
||||
|
||||
var item = await GetItemInUse(userId, XpShopItemType.Frame);
|
||||
|
||||
Image? frame = null;
|
||||
if (item is null)
|
||||
{
|
||||
if (patron?.Tier == PatronTier.V)
|
||||
frame = Image.Load<Rgba32>(File.OpenRead("data/images/frame_silver.png"));
|
||||
else if (patron?.Tier >= PatronTier.X || _creds.IsOwner(userId))
|
||||
frame = Image.Load<Rgba32>(File.OpenRead("data/images/frame_gold.png"));
|
||||
}
|
||||
else
|
||||
if (item is not null)
|
||||
{
|
||||
var url = _xpConfig.Data.Shop.GetItemUrl(XpShopItemType.Frame, item.ItemKey);
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
|
@ -1207,7 +1130,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
=> type switch
|
||||
{
|
||||
Xp.XpShopInputType.F => _xpConfig.Data.Shop.FramesTierRequirement,
|
||||
_ => _xpConfig.Data.Shop.BgsTierRequirement,
|
||||
_ => PatronTier.None,
|
||||
};
|
||||
|
||||
public bool IsShopEnabled()
|
||||
|
@ -1246,64 +1169,6 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class XpTemplateService : IEService, IReadyExecutor
|
||||
{
|
||||
private const string XP_TEMPLATE_PATH = "./data/xp_template.json";
|
||||
|
||||
private readonly IPubSub _pubSub;
|
||||
private XpTemplate _template = new();
|
||||
private readonly TypedKey<bool> _xpTemplateReloadKey = new("xp.template.reload");
|
||||
|
||||
public XpTemplateService(IPubSub pubSub)
|
||||
{
|
||||
_pubSub = pubSub;
|
||||
}
|
||||
|
||||
private void InternalReloadXpTemplate()
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new RequireObjectPropertiesContractResolver()
|
||||
};
|
||||
|
||||
if (!File.Exists(XP_TEMPLATE_PATH))
|
||||
{
|
||||
var newTemp = new XpTemplate();
|
||||
newTemp.Version = 2;
|
||||
File.WriteAllText(XP_TEMPLATE_PATH, JsonConvert.SerializeObject(newTemp, Formatting.Indented));
|
||||
}
|
||||
|
||||
_template = JsonConvert.DeserializeObject<XpTemplate>(
|
||||
File.ReadAllText(XP_TEMPLATE_PATH),
|
||||
settings)!;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "xp_template.json is invalid. Loaded default values");
|
||||
_template = new();
|
||||
}
|
||||
}
|
||||
|
||||
public void ReloadXpTemplate()
|
||||
=> _pubSub.Pub(_xpTemplateReloadKey, true);
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
InternalReloadXpTemplate();
|
||||
await _pubSub.Sub(_xpTemplateReloadKey,
|
||||
_ =>
|
||||
{
|
||||
InternalReloadXpTemplate();
|
||||
return default;
|
||||
});
|
||||
}
|
||||
|
||||
public XpTemplate GetTemplate()
|
||||
=> _template;
|
||||
}
|
||||
|
||||
public readonly record struct XpQueueEntry(IGuildUser User, long Xp)
|
||||
{
|
||||
public bool Equals(XpQueueEntry? other)
|
||||
|
|
82
src/EllieBot/Modules/Xp/XpTemplateService.cs
Normal file
82
src/EllieBot/Modules/Xp/XpTemplateService.cs
Normal file
|
@ -0,0 +1,82 @@
|
|||
#nullable disable warnings
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace EllieBot.Modules.Xp.Services;
|
||||
|
||||
public sealed class XpTemplateService : IEService, IReadyExecutor
|
||||
{
|
||||
private const string XP_TEMPLATE_PATH = "./data/xp_template.json";
|
||||
|
||||
private readonly IPubSub _pubSub;
|
||||
private XpTemplate _template = new();
|
||||
private readonly TypedKey<bool> _xpTemplateReloadKey = new("xp.template.reload");
|
||||
|
||||
public XpTemplateService(IPubSub pubSub)
|
||||
{
|
||||
_pubSub = pubSub;
|
||||
}
|
||||
|
||||
private void InternalReloadXpTemplate()
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new RequireObjectPropertiesContractResolver()
|
||||
};
|
||||
|
||||
if (!File.Exists(XP_TEMPLATE_PATH))
|
||||
{
|
||||
var newTemp = new XpTemplate();
|
||||
newTemp.Version = 3;
|
||||
File.WriteAllText(XP_TEMPLATE_PATH, JsonConvert.SerializeObject(newTemp, Formatting.Indented));
|
||||
}
|
||||
|
||||
_template = JsonConvert.DeserializeObject<XpTemplate>(
|
||||
File.ReadAllText(XP_TEMPLATE_PATH),
|
||||
settings)!;
|
||||
|
||||
if (_template.Version < 3)
|
||||
{
|
||||
if (_template.OutputSize is
|
||||
{
|
||||
X: 800,
|
||||
Y: 392
|
||||
})
|
||||
{
|
||||
_template.OutputSize = new()
|
||||
{
|
||||
X = 500,
|
||||
Y = 245
|
||||
};
|
||||
_template.Version = 3;
|
||||
|
||||
File.WriteAllText(XP_TEMPLATE_PATH, JsonConvert.SerializeObject(_template, Formatting.Indented));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "xp_template.json is invalid. Loaded default values");
|
||||
_template = new();
|
||||
}
|
||||
}
|
||||
|
||||
public void ReloadXpTemplate()
|
||||
=> _pubSub.Pub(_xpTemplateReloadKey, true);
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
InternalReloadXpTemplate();
|
||||
await _pubSub.Sub(_xpTemplateReloadKey,
|
||||
_ =>
|
||||
{
|
||||
InternalReloadXpTemplate();
|
||||
return default;
|
||||
});
|
||||
}
|
||||
|
||||
public XpTemplate GetTemplate()
|
||||
=> _template;
|
||||
}
|
|
@ -7,23 +7,17 @@ public class FullUserStats
|
|||
{
|
||||
public DiscordUser User { get; }
|
||||
public UserXpStats FullGuildStats { get; }
|
||||
public LevelStats Global { get; }
|
||||
public LevelStats Guild { get; }
|
||||
public int GlobalRanking { get; }
|
||||
public int GuildRanking { get; }
|
||||
|
||||
public FullUserStats(
|
||||
DiscordUser usr,
|
||||
UserXpStats fullGuildStats,
|
||||
LevelStats global,
|
||||
LevelStats guild,
|
||||
int globalRanking,
|
||||
int guildRanking)
|
||||
{
|
||||
User = usr;
|
||||
Global = global;
|
||||
Guild = guild;
|
||||
GlobalRanking = globalRanking;
|
||||
GuildRanking = guildRanking;
|
||||
FullGuildStats = fullGuildStats;
|
||||
}
|
||||
|
|
|
@ -7,25 +7,25 @@ namespace EllieBot.Modules.Xp;
|
|||
|
||||
public class XpTemplate
|
||||
{
|
||||
public int Version { get; set; } = 2;
|
||||
public int Version { get; set; } = 3;
|
||||
|
||||
[JsonProperty("output_size")]
|
||||
public XpTemplatePos OutputSize { get; set; } = new()
|
||||
{
|
||||
X = 800,
|
||||
Y = 392
|
||||
X = 500,
|
||||
Y = 245
|
||||
};
|
||||
|
||||
public XpTemplateUser User { get; set; } = new()
|
||||
{
|
||||
Name = new()
|
||||
{
|
||||
FontSize = 50,
|
||||
FontSize = 25,
|
||||
Show = true,
|
||||
Pos = new()
|
||||
{
|
||||
X = 130,
|
||||
Y = 17
|
||||
X = 65,
|
||||
Y = 8
|
||||
}
|
||||
},
|
||||
Icon = new()
|
||||
|
@ -33,53 +33,33 @@ public class XpTemplate
|
|||
Show = true,
|
||||
Pos = new()
|
||||
{
|
||||
X = 14,
|
||||
Y = 14
|
||||
X = 11,
|
||||
Y = 11
|
||||
},
|
||||
Size = new()
|
||||
{
|
||||
X = 72,
|
||||
Y = 71
|
||||
X = 38,
|
||||
Y = 38
|
||||
}
|
||||
},
|
||||
GuildLevel = new()
|
||||
Level = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 45,
|
||||
FontSize = 22,
|
||||
Pos = new()
|
||||
{
|
||||
X = 47,
|
||||
Y = 308
|
||||
X = 35,
|
||||
Y = 101
|
||||
}
|
||||
},
|
||||
GlobalLevel = new()
|
||||
Rank = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 45,
|
||||
FontSize = 20,
|
||||
Pos = new()
|
||||
{
|
||||
X = 47,
|
||||
Y = 160
|
||||
}
|
||||
},
|
||||
GuildRank = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 30,
|
||||
Pos = new()
|
||||
{
|
||||
X = 148,
|
||||
Y = 326
|
||||
}
|
||||
},
|
||||
GlobalRank = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 30,
|
||||
Pos = new()
|
||||
{
|
||||
X = 148,
|
||||
Y = 179
|
||||
X = 100,
|
||||
Y = 115
|
||||
}
|
||||
},
|
||||
Xp = new()
|
||||
|
@ -87,67 +67,31 @@ public class XpTemplate
|
|||
Bar = new()
|
||||
{
|
||||
Show = true,
|
||||
Global = new()
|
||||
{
|
||||
Direction = XpTemplateDirection.Right,
|
||||
Length = 450,
|
||||
Color = new(0, 0, 0, 0.4f),
|
||||
PointA = new()
|
||||
{
|
||||
X = 321,
|
||||
Y = 104
|
||||
},
|
||||
PointB = new()
|
||||
{
|
||||
X = 286,
|
||||
Y = 235
|
||||
}
|
||||
},
|
||||
Guild = new()
|
||||
{
|
||||
Direction = XpTemplateDirection.Right,
|
||||
Length = 450,
|
||||
Length = 225,
|
||||
Color = new(0, 0, 0, 0.4f),
|
||||
PointA = new()
|
||||
{
|
||||
X = 282,
|
||||
Y = 248
|
||||
X = 202,
|
||||
Y = 66
|
||||
},
|
||||
PointB = new()
|
||||
{
|
||||
X = 247,
|
||||
Y = 379
|
||||
X = 180,
|
||||
Y = 145
|
||||
}
|
||||
}
|
||||
},
|
||||
Global = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 50,
|
||||
Pos = new()
|
||||
{
|
||||
X = 528,
|
||||
Y = 170
|
||||
}
|
||||
},
|
||||
Guild = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 50,
|
||||
Pos = new()
|
||||
{
|
||||
X = 490,
|
||||
Y = 313
|
||||
}
|
||||
},
|
||||
Awarded = new()
|
||||
{
|
||||
Show = true,
|
||||
FontSize = 25,
|
||||
Pos = new()
|
||||
{
|
||||
X = 490,
|
||||
Y = 345
|
||||
X = 330,
|
||||
Y = 104
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,22 +104,22 @@ public class XpTemplate
|
|||
Show = true,
|
||||
Pos = new()
|
||||
{
|
||||
X = 722,
|
||||
Y = 25
|
||||
X = 451,
|
||||
Y = 15
|
||||
},
|
||||
Size = new()
|
||||
{
|
||||
X = 45,
|
||||
Y = 45
|
||||
X = 29,
|
||||
Y = 29
|
||||
}
|
||||
},
|
||||
Name = new()
|
||||
{
|
||||
FontSize = 35,
|
||||
FontSize = 20,
|
||||
Pos = new()
|
||||
{
|
||||
X = 650,
|
||||
Y = 49
|
||||
X = 394,
|
||||
Y = 35
|
||||
},
|
||||
Show = true
|
||||
}
|
||||
|
@ -199,10 +143,8 @@ public class XpTemplateUser
|
|||
{
|
||||
public XpTemplateText Name { get; set; }
|
||||
public XpTemplateIcon Icon { get; set; }
|
||||
public XpTemplateText GlobalLevel { get; set; }
|
||||
public XpTemplateText GuildLevel { get; set; }
|
||||
public XpTemplateText GlobalRank { get; set; }
|
||||
public XpTemplateText GuildRank { get; set; }
|
||||
public XpTemplateText Level { get; set; }
|
||||
public XpTemplateText Rank { get; set; }
|
||||
public XpTemplateXp Xp { get; set; }
|
||||
}
|
||||
|
||||
|
@ -225,15 +167,12 @@ public class XpTemplateText
|
|||
public class XpTemplateXp
|
||||
{
|
||||
public XpTemplateXpBar Bar { get; set; }
|
||||
public XpTemplateText Global { get; set; }
|
||||
public XpTemplateText Guild { get; set; }
|
||||
public XpTemplateText Awarded { get; set; }
|
||||
}
|
||||
|
||||
public class XpTemplateXpBar
|
||||
{
|
||||
public bool Show { get; set; }
|
||||
public XpBar Global { get; set; }
|
||||
public XpBar Guild { get; set; }
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,7 @@ public enum PatronTier
|
|||
{
|
||||
None,
|
||||
I,
|
||||
V,
|
||||
X,
|
||||
XX,
|
||||
L,
|
||||
C,
|
||||
ComingSoon
|
||||
C
|
||||
}
|
|
@ -5,13 +5,7 @@ namespace EllieBot.Services;
|
|||
|
||||
public class FontProvider : IEService
|
||||
{
|
||||
public FontFamily DottyFont { get; }
|
||||
|
||||
public FontFamily UniSans { get; }
|
||||
|
||||
public FontFamily NotoSans { get; }
|
||||
//public FontFamily Emojis { get; }
|
||||
|
||||
public List<FontFamily> FallBackFonts { get; }
|
||||
private readonly FontCollection _fonts;
|
||||
|
||||
|
@ -20,12 +14,9 @@ public class FontProvider : IEService
|
|||
_fonts = new();
|
||||
|
||||
NotoSans = _fonts.Add("data/fonts/NotoSans-Bold.ttf");
|
||||
UniSans = _fonts.Add("data/fonts/Uni Sans.ttf");
|
||||
|
||||
FallBackFonts = new();
|
||||
|
||||
//FallBackFonts.Add(_fonts.Install("data/fonts/OpenSansEmoji.ttf"));
|
||||
|
||||
// try loading some emoji and jap fonts on windows as fallback fonts
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
|
@ -48,7 +39,5 @@ public class FontProvider : IEService
|
|||
else if (font.EndsWith(".ttc"))
|
||||
FallBackFonts.AddRange(_fonts.AddCollection(font));
|
||||
}
|
||||
|
||||
DottyFont = FallBackFonts.First(x => x.Name == "dotty");
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ public sealed class ImagesConfig : ConfigServiceBase<ImageUrls>
|
|||
|
||||
private static readonly TypedKey<ImageUrls> _changeKey =
|
||||
new("config.images.updated");
|
||||
|
||||
|
||||
public override string Name
|
||||
=> "images";
|
||||
|
||||
|
@ -20,28 +20,13 @@ public sealed class ImagesConfig : ConfigServiceBase<ImageUrls>
|
|||
|
||||
private void Migrate()
|
||||
{
|
||||
if (data.Version < 5)
|
||||
if (data.Version < 10)
|
||||
{
|
||||
ModifyConfig(c =>
|
||||
{
|
||||
c.Version = 5;
|
||||
});
|
||||
}
|
||||
|
||||
if (data.Version < 6)
|
||||
{
|
||||
ModifyConfig(c =>
|
||||
{
|
||||
if (c.Slots.Emojis?.Length == 6)
|
||||
{
|
||||
c.Slots.Emojis =
|
||||
[
|
||||
new("https://cdn.nadeko.bot/slots/15.png"),
|
||||
..c.Slots.Emojis
|
||||
];
|
||||
}
|
||||
|
||||
c.Version = 6;
|
||||
if (c.Xp.Bg.ToString().Contains("cdn.nadeko.bot"))
|
||||
c.Xp.Bg = new("https://cdn.nadeko.bot/xp/bgs/v6.png");
|
||||
c.Version = 10;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ namespace EllieBot.Extensions;
|
|||
public static class DbExtensions
|
||||
{
|
||||
public static DiscordUser GetOrCreateUser(this DbContext ctx, IUser original, Func<IQueryable<DiscordUser>, IQueryable<DiscordUser>>? includes = null)
|
||||
=> ctx.GetOrCreateUser(original.Id, original.Username, original.Discriminator, original.AvatarId, includes);
|
||||
=> ctx.GetOrCreateUser(original.Id, original.Username, original.AvatarId, includes);
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
# DO NOT CHANGE
|
||||
version: 6
|
||||
version: 10
|
||||
coins:
|
||||
heads:
|
||||
- https://cdn.nadeko.bot/coins/heads3.png
|
||||
|
@ -21,7 +21,7 @@ dice:
|
|||
- https://cdn.nadeko.bot/other/dice/8.png
|
||||
- https://cdn.nadeko.bot/other/dice/9.png
|
||||
xp:
|
||||
bg: https://cdn.nadeko.bot/other/xp/bg_k.png
|
||||
bg: https://cdn.nadeko.bot/xp/bgs/v6.png
|
||||
slots:
|
||||
emojis:
|
||||
- https://cdn.nadeko.bot/slots/10.png
|
||||
|
|
Binary file not shown.
Before ![]() (image error) Size: 49 KiB |
Binary file not shown.
Before ![]() (image error) Size: 13 KiB |
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"Version": 2,
|
||||
"Version": 3,
|
||||
"output_size": {
|
||||
"X": 800,
|
||||
"Y": 392
|
||||
"X": 500,
|
||||
"Y": 245
|
||||
},
|
||||
"User": {
|
||||
"Name": {
|
||||
|
@ -25,58 +25,27 @@
|
|||
"Y": 71
|
||||
}
|
||||
},
|
||||
"GlobalLevel": {
|
||||
"Level": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 45,
|
||||
"FontSize": 22,
|
||||
"Pos": {
|
||||
"X": 47,
|
||||
"Y": 160
|
||||
"X": 35,
|
||||
"Y": 101
|
||||
}
|
||||
},
|
||||
"GuildLevel": {
|
||||
"Rank": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 45,
|
||||
"FontSize": 20,
|
||||
"Pos": {
|
||||
"X": 47,
|
||||
"Y": 308
|
||||
}
|
||||
},
|
||||
"GlobalRank": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 30,
|
||||
"Pos": {
|
||||
"X": 148,
|
||||
"Y": 179
|
||||
}
|
||||
},
|
||||
"GuildRank": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 30,
|
||||
"Pos": {
|
||||
"X": 148,
|
||||
"Y": 326
|
||||
"X": 100,
|
||||
"Y": 115
|
||||
}
|
||||
},
|
||||
"Xp": {
|
||||
"Bar": {
|
||||
"Show": true,
|
||||
"Global": {
|
||||
"Color": "00000095",
|
||||
"PointA": {
|
||||
"X": 321,
|
||||
"Y": 104
|
||||
},
|
||||
"PointB": {
|
||||
"X": 286,
|
||||
"Y": 235
|
||||
},
|
||||
"Length": 450,
|
||||
"Direction": 3
|
||||
},
|
||||
"Guild": {
|
||||
"Color": "00000095",
|
||||
"PointA": {
|
||||
|
@ -91,15 +60,6 @@
|
|||
"Direction": 3
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 50,
|
||||
"Pos": {
|
||||
"X": 528,
|
||||
"Y": 170
|
||||
}
|
||||
},
|
||||
"Guild": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
|
@ -108,15 +68,6 @@
|
|||
"X": 490,
|
||||
"Y": 313
|
||||
}
|
||||
},
|
||||
"Awarded": {
|
||||
"Color": "ffffffff",
|
||||
"Show": true,
|
||||
"FontSize": 25,
|
||||
"Pos": {
|
||||
"X": 450,
|
||||
"Y": 345
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue