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:
Toastie 2025-03-01 18:43:46 +13:00
parent 0ee5c0dd94
commit 6f64a15cd4
Signed by: toastie_t0ast
GPG key ID: 0861BE54AD481DC7
21 changed files with 800 additions and 606 deletions

View file

@ -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()

View file

@ -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,

View file

@ -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));

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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)

View 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;
}

View file

@ -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;
}

View file

@ -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; }
}

View file

@ -5,10 +5,7 @@ public enum PatronTier
{
None,
I,
V,
X,
XX,
L,
C,
ComingSoon
C
}

View file

@ -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");
}
}

View file

@ -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;
});
}
}

View file

@ -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.

View file

@ -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

View file

@ -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
}
}
}
},