Added .rip command again :^)
This commit is contained in:
parent
febbb8e36b
commit
099ae62c0b
@ -6,6 +6,8 @@ using Discord;
|
|||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using NadekoBot.Modules.Music.Services;
|
||||||
|
using NadekoBot.Modules.Administration.Services;
|
||||||
|
|
||||||
namespace NadekoBot.Common.Replacements
|
namespace NadekoBot.Common.Replacements
|
||||||
{
|
{
|
||||||
@ -44,19 +46,19 @@ namespace NadekoBot.Common.Replacements
|
|||||||
|
|
||||||
_reps.TryAdd("%sid%", () => g == null ? "DM" : g.Id.ToString());
|
_reps.TryAdd("%sid%", () => g == null ? "DM" : g.Id.ToString());
|
||||||
_reps.TryAdd("%server%", () => g == null ? "DM" : g.Name);
|
_reps.TryAdd("%server%", () => g == null ? "DM" : g.Name);
|
||||||
//_reps.TryAdd("%server_time%", () =>
|
_reps.TryAdd("%server_time%", () =>
|
||||||
//{
|
{
|
||||||
// TimeZoneInfo to = TimeZoneInfo.Local;
|
TimeZoneInfo to = TimeZoneInfo.Local;
|
||||||
// if (g != null)
|
if (g != null)
|
||||||
// {
|
{
|
||||||
// if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
||||||
// to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return TimeZoneInfo.ConvertTime(DateTime.UtcNow,
|
return TimeZoneInfo.ConvertTime(DateTime.UtcNow,
|
||||||
// TimeZoneInfo.Utc,
|
TimeZoneInfo.Utc,
|
||||||
// to).ToString("HH:mm ") + to.StandardName.GetInitials();
|
to).ToString("HH:mm ") + to.StandardName.GetInitials();
|
||||||
//});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,26 +88,26 @@ namespace NadekoBot.Common.Replacements
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public ReplacementBuilder WithMusic(MusicService ms)
|
public ReplacementBuilder WithMusic(MusicService ms)
|
||||||
//{
|
{
|
||||||
// _reps.TryAdd("%playing%", () =>
|
_reps.TryAdd("%playing%", () =>
|
||||||
// {
|
{
|
||||||
// var cnt = ms.MusicPlayers.Count(kvp => kvp.Value.Current.Current != null);
|
var cnt = ms.MusicPlayers.Count(kvp => kvp.Value.Current.Current != null);
|
||||||
// if (cnt != 1) return cnt.ToString();
|
if (cnt != 1) return cnt.ToString();
|
||||||
// try
|
try
|
||||||
// {
|
{
|
||||||
// var mp = ms.MusicPlayers.FirstOrDefault();
|
var mp = ms.MusicPlayers.FirstOrDefault();
|
||||||
// var title = mp.Value?.Current.Current?.Title;
|
var title = mp.Value?.Current.Current?.Title;
|
||||||
// return title ?? "No songs";
|
return title ?? "No songs";
|
||||||
// }
|
}
|
||||||
// catch
|
catch
|
||||||
// {
|
{
|
||||||
// return "error";
|
return "error";
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// _reps.TryAdd("%queued%", () => ms.MusicPlayers.Sum(kvp => kvp.Value.QueueArray().Songs.Length).ToString());
|
_reps.TryAdd("%queued%", () => ms.MusicPlayers.Sum(kvp => kvp.Value.QueueArray().Songs.Length).ToString());
|
||||||
// return this;
|
return this;
|
||||||
//}
|
}
|
||||||
|
|
||||||
public ReplacementBuilder WithRngRegex()
|
public ReplacementBuilder WithRngRegex()
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ using NadekoBot.Common.Replacements;
|
|||||||
using NadekoBot.Core.Services;
|
using NadekoBot.Core.Services;
|
||||||
using NadekoBot.Core.Services.Database.Models;
|
using NadekoBot.Core.Services.Database.Models;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NadekoBot.Modules.Music.Services;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Administration.Services
|
namespace NadekoBot.Modules.Administration.Services
|
||||||
{
|
{
|
||||||
@ -27,7 +28,7 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PlayingRotateService(DiscordSocketClient client, IBotConfigProvider bcp,
|
public PlayingRotateService(DiscordSocketClient client, IBotConfigProvider bcp,
|
||||||
DbService db, IDataCache cache, NadekoBot bot)
|
DbService db, IDataCache cache, NadekoBot bot, MusicService music)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_bcp = bcp;
|
_bcp = bcp;
|
||||||
@ -41,8 +42,7 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
_rep = new ReplacementBuilder()
|
_rep = new ReplacementBuilder()
|
||||||
.WithClient(client)
|
.WithClient(client)
|
||||||
.WithStats(client)
|
.WithStats(client)
|
||||||
//todo how to add music to replacement builder?
|
.WithMusic(music)
|
||||||
//.WithMusic(music)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_t = new Timer(async (objState) =>
|
_t = new Timer(async (objState) =>
|
||||||
|
@ -36,6 +36,22 @@ namespace NadekoBot.Modules.Searches
|
|||||||
_google = google;
|
_google = google;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//for anonymasen :^)
|
||||||
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
public async Task Rip([Remainder]IGuildUser usr)
|
||||||
|
{
|
||||||
|
using (var pic = await _service.GetRipPictureAsync(usr.Nickname ?? usr.Username, usr.RealAvatarUrl()))
|
||||||
|
using (var picStream = pic.ToStream())
|
||||||
|
{
|
||||||
|
await Context.Channel.SendFileAsync(
|
||||||
|
picStream,
|
||||||
|
"rip.png",
|
||||||
|
$"Rip {Format.Bold(usr.ToString())} \n\t- " +
|
||||||
|
Format.Italics(Context.User.ToString()))
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
|
@ -18,6 +18,11 @@ using Newtonsoft.Json.Linq;
|
|||||||
using AngleSharp;
|
using AngleSharp;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NadekoBot.Modules.Searches.Exceptions;
|
using NadekoBot.Modules.Searches.Exceptions;
|
||||||
|
using ImageSharp;
|
||||||
|
using Image = ImageSharp.Image;
|
||||||
|
using SixLabors.Primitives;
|
||||||
|
using SixLabors.Fonts;
|
||||||
|
using NadekoBot.Core.Services.Impl;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Searches.Services
|
namespace NadekoBot.Modules.Searches.Services
|
||||||
{
|
{
|
||||||
@ -29,11 +34,16 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
private readonly IGoogleApiService _google;
|
private readonly IGoogleApiService _google;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
private readonly IImagesService _imgs;
|
||||||
|
private readonly IDataCache _cache;
|
||||||
|
private readonly FontProvider _fonts;
|
||||||
|
private readonly HttpClient http;
|
||||||
|
|
||||||
public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
|
public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
|
||||||
public ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
|
public ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
|
||||||
|
|
||||||
public readonly string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities7.json";
|
public readonly string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities7.json";
|
||||||
|
|
||||||
public readonly string PokemonListFile = "data/pokemon/pokemon_list7.json";
|
public readonly string PokemonListFile = "data/pokemon/pokemon_list7.json";
|
||||||
public Dictionary<string, SearchPokemon> Pokemons { get; } = new Dictionary<string, SearchPokemon>();
|
public Dictionary<string, SearchPokemon> Pokemons { get; } = new Dictionary<string, SearchPokemon>();
|
||||||
public Dictionary<string, SearchPokemonAbility> PokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>();
|
public Dictionary<string, SearchPokemonAbility> PokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>();
|
||||||
@ -50,7 +60,8 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
|
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
|
||||||
|
|
||||||
public SearchesService(DiscordSocketClient client, IGoogleApiService google,
|
public SearchesService(DiscordSocketClient client, IGoogleApiService google,
|
||||||
DbService db, NadekoBot bot)
|
DbService db, NadekoBot bot, IImagesService imgs, IDataCache cache,
|
||||||
|
FontProvider fonts)
|
||||||
{
|
{
|
||||||
Http = new HttpClient();
|
Http = new HttpClient();
|
||||||
Http.AddFakeHeaders();
|
Http.AddFakeHeaders();
|
||||||
@ -58,6 +69,10 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
_google = google;
|
_google = google;
|
||||||
_db = db;
|
_db = db;
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
|
_imgs = imgs;
|
||||||
|
_cache = cache;
|
||||||
|
_fonts = fonts;
|
||||||
|
http = new HttpClient();
|
||||||
|
|
||||||
_blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>(
|
_blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>(
|
||||||
bot.AllGuildConfigs.ToDictionary(
|
bot.AllGuildConfigs.ToDictionary(
|
||||||
@ -126,6 +141,61 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
_log.Warn("data/magicitems.json is missing. Magic items are not loaded.");
|
_log.Warn("data/magicitems.json is missing. Magic items are not loaded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Image<Rgba32>> GetRipPictureAsync(string text, string imgUrl)
|
||||||
|
{
|
||||||
|
var (succ, data) = await _cache.TryGetImageDataAsync(imgUrl);
|
||||||
|
if (!succ)
|
||||||
|
{
|
||||||
|
using (var temp = await http.GetAsync(imgUrl, HttpCompletionOption.ResponseHeadersRead))
|
||||||
|
{
|
||||||
|
if (temp.Content.Headers.ContentType.MediaType != "image/png"
|
||||||
|
&& temp.Content.Headers.ContentType.MediaType != "image/jpeg"
|
||||||
|
&& temp.Content.Headers.ContentType.MediaType != "image/gif")
|
||||||
|
data = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (var tempDraw = ImageSharp.Image.Load(await temp.Content.ReadAsStreamAsync()).Resize(69, 70))
|
||||||
|
{
|
||||||
|
tempDraw.ApplyRoundedCorners(35);
|
||||||
|
data = tempDraw.ToStream().ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _cache.SetImageDataAsync(imgUrl, data);
|
||||||
|
}
|
||||||
|
var bg = ImageSharp.Image.Load(_imgs.Rip.ToArray());
|
||||||
|
|
||||||
|
//avatar 82, 139
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
var avatar = Image.Load(data).Resize(85, 85);
|
||||||
|
bg.DrawImage(avatar,
|
||||||
|
default,
|
||||||
|
new Point(82, 139),
|
||||||
|
GraphicsOptions.Default);
|
||||||
|
}
|
||||||
|
//text 63, 241
|
||||||
|
bg.DrawText(text,
|
||||||
|
_fonts.RipNameFont,
|
||||||
|
Rgba32.Black,
|
||||||
|
new PointF(25, 225),
|
||||||
|
new ImageSharp.Drawing.TextGraphicsOptions()
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
WrapTextWidth = 190,
|
||||||
|
});
|
||||||
|
|
||||||
|
//flowa
|
||||||
|
var flowers = Image.Load(_imgs.FlowerCircle.ToArray());
|
||||||
|
bg.DrawImage(flowers,
|
||||||
|
default,
|
||||||
|
new Point(0, 0),
|
||||||
|
GraphicsOptions.Default);
|
||||||
|
|
||||||
|
return bg;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<string> Translate(string langs, string text = null)
|
public async Task<string> Translate(string langs, string text = null)
|
||||||
{
|
{
|
||||||
var langarr = langs.ToLowerInvariant().Split('>');
|
var langarr = langs.ToLowerInvariant().Split('>');
|
||||||
@ -212,7 +282,7 @@ namespace NadekoBot.Modules.Searches.Services
|
|||||||
|
|
||||||
public async Task<(string Text, string BaseUri)> GetRandomJoke()
|
public async Task<(string Text, string BaseUri)> GetRandomJoke()
|
||||||
{
|
{
|
||||||
var config = Configuration.Default.WithDefaultLoader();
|
var config = AngleSharp.Configuration.Default.WithDefaultLoader();
|
||||||
var document = await BrowsingContext.New(config).OpenAsync("http://www.goodbadjokes.com/random");
|
var document = await BrowsingContext.New(config).OpenAsync("http://www.goodbadjokes.com/random");
|
||||||
|
|
||||||
var html = document.QuerySelector(".post > .joke-content");
|
var html = document.QuerySelector(".post > .joke-content");
|
||||||
|
@ -37,7 +37,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
private readonly NadekoStrings _strings;
|
private readonly NadekoStrings _strings;
|
||||||
private readonly IDataCache _cache;
|
private readonly IDataCache _cache;
|
||||||
private readonly FontCollection _fonts = new FontCollection();
|
private readonly FontProvider _fonts;
|
||||||
public const int XP_REQUIRED_LVL_1 = 36;
|
public const int XP_REQUIRED_LVL_1 = 36;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedRoles
|
private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedRoles
|
||||||
@ -59,17 +59,11 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
private readonly CancellationTokenSource _clearRewardTimerTokenSource;
|
private readonly CancellationTokenSource _clearRewardTimerTokenSource;
|
||||||
private readonly Task _clearRewardTimer;
|
private readonly Task _clearRewardTimer;
|
||||||
private readonly HttpClient http = new HttpClient();
|
private readonly HttpClient http = new HttpClient();
|
||||||
private FontFamily _usernameFontFamily;
|
|
||||||
private FontFamily _clubFontFamily;
|
|
||||||
private Font _levelFont;
|
|
||||||
private Font _xpFont;
|
|
||||||
private Font _awardedFont;
|
|
||||||
private Font _rankFont;
|
|
||||||
private Font _timeFont;
|
|
||||||
|
|
||||||
public XpService(CommandHandler cmd, IBotConfigProvider bc,
|
public XpService(CommandHandler cmd, IBotConfigProvider bc,
|
||||||
NadekoBot bot, IImagesService images,
|
NadekoBot bot, IImagesService images,
|
||||||
DbService db, NadekoStrings strings, IDataCache cache)
|
DbService db, NadekoStrings strings, IDataCache cache,
|
||||||
|
FontProvider fonts)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_cmd = cmd;
|
_cmd = cmd;
|
||||||
@ -78,6 +72,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
_strings = strings;
|
_strings = strings;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
|
_fonts = fonts;
|
||||||
|
|
||||||
//load settings
|
//load settings
|
||||||
var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null);
|
var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null);
|
||||||
@ -105,16 +100,6 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
|
allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
|
||||||
.Select(x => x.GuildId));
|
.Select(x => x.GuildId));
|
||||||
|
|
||||||
//todo 60 move to font provider or somethign
|
|
||||||
_fonts = new FontCollection();
|
|
||||||
if (Directory.Exists("data/fonts"))
|
|
||||||
foreach (var file in Directory.GetFiles("data/fonts"))
|
|
||||||
{
|
|
||||||
_fonts.Install(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeFonts();
|
|
||||||
|
|
||||||
_cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger;
|
_cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger;
|
||||||
|
|
||||||
_updateXpTimer = new Timer(async _ =>
|
_updateXpTimer = new Timer(async _ =>
|
||||||
@ -547,16 +532,6 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
return GenerateImageAsync(GetUserStats(user));
|
return GenerateImageAsync(GetUserStats(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeFonts()
|
|
||||||
{
|
|
||||||
_usernameFontFamily = _fonts.Find("Whitney-Bold");
|
|
||||||
_clubFontFamily = _fonts.Find("Whitney-Bold");
|
|
||||||
_levelFont = _fonts.Find("Whitney-Bold").CreateFont(45);
|
|
||||||
_xpFont = _fonts.Find("Whitney-Bold").CreateFont(50);
|
|
||||||
_awardedFont = _fonts.Find("Whitney-Bold").CreateFont(25);
|
|
||||||
_rankFont = _fonts.Find("Uni Sans Thin CAPS").CreateFont(30);
|
|
||||||
_timeFont = _fonts.Find("Whitney-Bold").CreateFont(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<MemoryStream> GenerateImageAsync(FullUserStats stats) => Task.Run(async () =>
|
public Task<MemoryStream> GenerateImageAsync(FullUserStats stats) => Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -564,7 +539,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
{
|
{
|
||||||
|
|
||||||
var username = stats.User.ToString();
|
var username = stats.User.ToString();
|
||||||
var usernameFont = _usernameFontFamily
|
var usernameFont = _fonts.UsernameFontFamily
|
||||||
.CreateFont(username.Length <= 6
|
.CreateFont(username.Length <= 6
|
||||||
? 50
|
? 50
|
||||||
: 50 - username.Length);
|
: 50 - username.Length);
|
||||||
@ -574,17 +549,17 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
|
|
||||||
// level
|
// level
|
||||||
|
|
||||||
img.DrawText(stats.Global.Level.ToString(), _levelFont, Rgba32.White,
|
img.DrawText(stats.Global.Level.ToString(), _fonts.LevelFont, Rgba32.White,
|
||||||
new PointF(47, 137));
|
new PointF(47, 137));
|
||||||
|
|
||||||
img.DrawText(stats.Guild.Level.ToString(), _levelFont, Rgba32.White,
|
img.DrawText(stats.Guild.Level.ToString(), _fonts.LevelFont, Rgba32.White,
|
||||||
new PointF(47, 285));
|
new PointF(47, 285));
|
||||||
|
|
||||||
//club name
|
//club name
|
||||||
|
|
||||||
var clubName = stats.User.Club?.ToString() ?? "-";
|
var clubName = stats.User.Club?.ToString() ?? "-";
|
||||||
|
|
||||||
var clubFont = _clubFontFamily
|
var clubFont = _fonts.ClubFontFamily
|
||||||
.CreateFont(clubName.Length <= 8
|
.CreateFont(clubName.Length <= 8
|
||||||
? 35
|
? 35
|
||||||
: 35 - (clubName.Length / 2));
|
: 35 - (clubName.Length / 2));
|
||||||
@ -607,7 +582,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
new PointF(286 + (450 * (global.LevelXp / (float)global.RequiredXp)), 235),
|
new PointF(286 + (450 * (global.LevelXp / (float)global.RequiredXp)), 235),
|
||||||
new PointF(286, 235),
|
new PointF(286, 235),
|
||||||
});
|
});
|
||||||
img.DrawText($"{global.LevelXp}/{global.RequiredXp}", _xpFont, brush, pen,
|
img.DrawText($"{global.LevelXp}/{global.RequiredXp}", _fonts.XpFont, brush, pen,
|
||||||
new PointF(430, 130));
|
new PointF(430, 130));
|
||||||
|
|
||||||
img.FillPolygon(xpBgBrush, new[] {
|
img.FillPolygon(xpBgBrush, new[] {
|
||||||
@ -616,7 +591,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
new PointF(247 + (450 * (guild.LevelXp / (float)guild.RequiredXp)), 379),
|
new PointF(247 + (450 * (guild.LevelXp / (float)guild.RequiredXp)), 379),
|
||||||
new PointF(247, 379),
|
new PointF(247, 379),
|
||||||
});
|
});
|
||||||
img.DrawText($"{guild.LevelXp}/{guild.RequiredXp}", _xpFont, brush, pen,
|
img.DrawText($"{guild.LevelXp}/{guild.RequiredXp}", _fonts.XpFont, brush, pen,
|
||||||
new PointF(400, 270));
|
new PointF(400, 270));
|
||||||
|
|
||||||
if (stats.FullGuildStats.AwardedXp != 0)
|
if (stats.FullGuildStats.AwardedXp != 0)
|
||||||
@ -624,16 +599,16 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
var sign = stats.FullGuildStats.AwardedXp > 0
|
var sign = stats.FullGuildStats.AwardedXp > 0
|
||||||
? "+ "
|
? "+ "
|
||||||
: "";
|
: "";
|
||||||
img.DrawText($"({sign}{stats.FullGuildStats.AwardedXp})", _awardedFont, brush, pen,
|
img.DrawText($"({sign}{stats.FullGuildStats.AwardedXp})", _fonts.AwardedFont, brush, pen,
|
||||||
new PointF(445 - (Math.Max(0, (stats.FullGuildStats.AwardedXp.ToString().Length - 2)) * 5), 335));
|
new PointF(445 - (Math.Max(0, (stats.FullGuildStats.AwardedXp.ToString().Length - 2)) * 5), 335));
|
||||||
}
|
}
|
||||||
|
|
||||||
//ranking
|
//ranking
|
||||||
|
|
||||||
img.DrawText(stats.GlobalRanking.ToString(), _rankFont, Rgba32.White,
|
img.DrawText(stats.GlobalRanking.ToString(), _fonts.RankFont, Rgba32.White,
|
||||||
new PointF(148, 170));
|
new PointF(148, 170));
|
||||||
|
|
||||||
img.DrawText(stats.GuildRanking.ToString(), _rankFont, Rgba32.White,
|
img.DrawText(stats.GuildRanking.ToString(), _fonts.RankFont, Rgba32.White,
|
||||||
new PointF(148, 317));
|
new PointF(148, 317));
|
||||||
|
|
||||||
//time on this level
|
//time on this level
|
||||||
@ -644,10 +619,10 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
return $"{offset.Days}d{offset.Hours}h{offset.Minutes}m";
|
return $"{offset.Days}d{offset.Hours}h{offset.Minutes}m";
|
||||||
}
|
}
|
||||||
|
|
||||||
img.DrawText(GetTimeSpent(stats.User.LastLevelUp), _timeFont, Rgba32.White,
|
img.DrawText(GetTimeSpent(stats.User.LastLevelUp), _fonts.TimeFont, Rgba32.White,
|
||||||
new PointF(50, 197));
|
new PointF(50, 197));
|
||||||
|
|
||||||
img.DrawText(GetTimeSpent(stats.FullGuildStats.LastLevelUp), _timeFont, Rgba32.White,
|
img.DrawText(GetTimeSpent(stats.FullGuildStats.LastLevelUp), _fonts.TimeFont, Rgba32.White,
|
||||||
new PointF(50, 344));
|
new PointF(50, 344));
|
||||||
|
|
||||||
//avatar
|
//avatar
|
||||||
@ -664,7 +639,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
using (var temp = await http.GetStreamAsync(avatarUrl))
|
using (var temp = await http.GetStreamAsync(avatarUrl))
|
||||||
using (var tempDraw = Image.Load(temp).Resize(69, 70))
|
using (var tempDraw = Image.Load(temp).Resize(69, 70))
|
||||||
{
|
{
|
||||||
ApplyRoundedCorners(tempDraw, 35);
|
tempDraw.ApplyRoundedCorners(35);
|
||||||
data = tempDraw.ToStream().ToArray();
|
data = tempDraw.ToStream().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +685,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
return;
|
return;
|
||||||
using (var tempDraw = Image.Load(await temp.Content.ReadAsStreamAsync()).Resize(45, 45))
|
using (var tempDraw = Image.Load(await temp.Content.ReadAsStreamAsync()).Resize(45, 45))
|
||||||
{
|
{
|
||||||
ApplyRoundedCorners(tempDraw, 22.5f);
|
tempDraw.ApplyRoundedCorners(22.5f);
|
||||||
data = tempDraw.ToStream().ToArray();
|
data = tempDraw.ToStream().ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,40 +706,6 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/SixLabors/ImageSharp/tree/master/samples/AvatarWithRoundedCorner
|
|
||||||
public static void ApplyRoundedCorners(Image<Rgba32> img, float cornerRadius)
|
|
||||||
{
|
|
||||||
var corners = BuildCorners(img.Width, img.Height, cornerRadius);
|
|
||||||
// now we have our corners time to draw them
|
|
||||||
img.Fill(Rgba32.Transparent, corners, new GraphicsOptions(true)
|
|
||||||
{
|
|
||||||
BlenderMode = ImageSharp.PixelFormats.PixelBlenderMode.Src // enforces that any part of this shape that has color is punched out of the background
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
|
|
||||||
{
|
|
||||||
// first create a square
|
|
||||||
var rect = new RectangularePolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
|
|
||||||
|
|
||||||
// then cut out of the square a circle so we are left with a corner
|
|
||||||
var cornerToptLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
|
|
||||||
|
|
||||||
// corner is now a corner shape positions top left
|
|
||||||
//lets make 3 more positioned correctly, we can do that by translating the orgional around the center of the image
|
|
||||||
var center = new Vector2(imageWidth / 2, imageHeight / 2);
|
|
||||||
|
|
||||||
float rightPos = imageWidth - cornerToptLeft.Bounds.Width + 1;
|
|
||||||
float bottomPos = imageHeight - cornerToptLeft.Bounds.Height + 1;
|
|
||||||
|
|
||||||
// move it across the width of the image - the width of the shape
|
|
||||||
var cornerTopRight = cornerToptLeft.RotateDegree(90).Translate(rightPos, 0);
|
|
||||||
var cornerBottomLeft = cornerToptLeft.RotateDegree(-90).Translate(0, bottomPos);
|
|
||||||
var cornerBottomRight = cornerToptLeft.RotateDegree(180).Translate(rightPos, bottomPos);
|
|
||||||
|
|
||||||
return new PathCollection(cornerToptLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Unload()
|
public Task Unload()
|
||||||
{
|
{
|
||||||
_cmd.OnMessageNoTrigger -= _cmd_OnMessageNoTrigger;
|
_cmd.OnMessageNoTrigger -= _cmd_OnMessageNoTrigger;
|
||||||
|
@ -19,6 +19,9 @@ namespace NadekoBot.Core.Services
|
|||||||
|
|
||||||
ImmutableArray<byte> XpCard { get; }
|
ImmutableArray<byte> XpCard { get; }
|
||||||
|
|
||||||
|
ImmutableArray<byte> Rip { get; }
|
||||||
|
ImmutableArray<byte> FlowerCircle { get; }
|
||||||
|
|
||||||
void Reload();
|
void Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
NadekoBot.Core/Services/Impl/FontProvider.cs
Normal file
38
NadekoBot.Core/Services/Impl/FontProvider.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using SixLabors.Fonts;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NadekoBot.Core.Services.Impl
|
||||||
|
{
|
||||||
|
public class FontProvider : INService
|
||||||
|
{
|
||||||
|
private readonly FontCollection _fonts;
|
||||||
|
|
||||||
|
public FontProvider()
|
||||||
|
{
|
||||||
|
_fonts = new FontCollection();
|
||||||
|
if (Directory.Exists("data/fonts"))
|
||||||
|
foreach (var file in Directory.GetFiles("data/fonts"))
|
||||||
|
{
|
||||||
|
_fonts.Install(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
UsernameFontFamily = _fonts.Find("Whitney-Bold");
|
||||||
|
ClubFontFamily = _fonts.Find("Whitney-Bold");
|
||||||
|
LevelFont = _fonts.Find("Whitney-Bold").CreateFont(45);
|
||||||
|
XpFont = _fonts.Find("Whitney-Bold").CreateFont(50);
|
||||||
|
AwardedFont = _fonts.Find("Whitney-Bold").CreateFont(25);
|
||||||
|
RankFont = _fonts.Find("Uni Sans Thin CAPS").CreateFont(30);
|
||||||
|
TimeFont = _fonts.Find("Whitney-Bold").CreateFont(20);
|
||||||
|
RipNameFont = _fonts.Find("Whitney-Bold").CreateFont(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Font LevelFont { get; }
|
||||||
|
public Font XpFont { get; }
|
||||||
|
public Font AwardedFont { get; }
|
||||||
|
public Font RankFont { get; }
|
||||||
|
public Font TimeFont { get; }
|
||||||
|
public FontFamily UsernameFontFamily { get; }
|
||||||
|
public FontFamily ClubFontFamily { get; }
|
||||||
|
public Font RipNameFont { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,9 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
|
|
||||||
private const string _xpCardPath = _basePath + "xp/xp.png";
|
private const string _xpCardPath = _basePath + "xp/xp.png";
|
||||||
|
|
||||||
|
private const string _ripPath = _basePath + "rip/rip.png";
|
||||||
|
private const string _ripFlowersPath = _basePath + "rip/rose_overlay.png";
|
||||||
|
|
||||||
|
|
||||||
public ImmutableArray<byte> Heads { get; private set; }
|
public ImmutableArray<byte> Heads { get; private set; }
|
||||||
public ImmutableArray<byte> Tails { get; private set; }
|
public ImmutableArray<byte> Tails { get; private set; }
|
||||||
@ -44,6 +47,9 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
|
|
||||||
public ImmutableArray<byte> XpCard { get; private set; }
|
public ImmutableArray<byte> XpCard { get; private set; }
|
||||||
|
|
||||||
|
public ImmutableArray<byte> Rip { get; private set; }
|
||||||
|
public ImmutableArray<byte> FlowerCircle { get; private set; }
|
||||||
|
|
||||||
public ImagesService()
|
public ImagesService()
|
||||||
{
|
{
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
@ -82,6 +88,9 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
RategirlDot = File.ReadAllBytes(_rategirlDot).ToImmutableArray();
|
RategirlDot = File.ReadAllBytes(_rategirlDot).ToImmutableArray();
|
||||||
|
|
||||||
XpCard = File.ReadAllBytes(_xpCardPath).ToImmutableArray();
|
XpCard = File.ReadAllBytes(_xpCardPath).ToImmutableArray();
|
||||||
|
|
||||||
|
Rip = File.ReadAllBytes(_ripPath).ToImmutableArray();
|
||||||
|
FlowerCircle = File.ReadAllBytes(_ripFlowersPath).ToImmutableArray();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -17,11 +17,47 @@ using NadekoBot.Common.Collections;
|
|||||||
using SixLabors.Primitives;
|
using SixLabors.Primitives;
|
||||||
using NadekoBot.Common;
|
using NadekoBot.Common;
|
||||||
using NadekoBot.Core.Services;
|
using NadekoBot.Core.Services;
|
||||||
|
using SixLabors.Shapes;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace NadekoBot.Extensions
|
namespace NadekoBot.Extensions
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
|
// https://github.com/SixLabors/ImageSharp/tree/master/samples/AvatarWithRoundedCorner
|
||||||
|
public static void ApplyRoundedCorners(this Image<Rgba32> img, float cornerRadius)
|
||||||
|
{
|
||||||
|
var corners = BuildCorners(img.Width, img.Height, cornerRadius);
|
||||||
|
// now we have our corners time to draw them
|
||||||
|
img.Fill(Rgba32.Transparent, corners, new GraphicsOptions(true)
|
||||||
|
{
|
||||||
|
BlenderMode = ImageSharp.PixelFormats.PixelBlenderMode.Src // enforces that any part of this shape that has color is punched out of the background
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
|
||||||
|
{
|
||||||
|
// first create a square
|
||||||
|
var rect = new RectangularePolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
|
||||||
|
|
||||||
|
// then cut out of the square a circle so we are left with a corner
|
||||||
|
var cornerToptLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
|
||||||
|
|
||||||
|
// corner is now a corner shape positions top left
|
||||||
|
//lets make 3 more positioned correctly, we can do that by translating the orgional around the center of the image
|
||||||
|
var center = new Vector2(imageWidth / 2, imageHeight / 2);
|
||||||
|
|
||||||
|
float rightPos = imageWidth - cornerToptLeft.Bounds.Width + 1;
|
||||||
|
float bottomPos = imageHeight - cornerToptLeft.Bounds.Height + 1;
|
||||||
|
|
||||||
|
// move it across the width of the image - the width of the shape
|
||||||
|
var cornerTopRight = cornerToptLeft.RotateDegree(90).Translate(rightPos, 0);
|
||||||
|
var cornerBottomLeft = cornerToptLeft.RotateDegree(-90).Translate(0, bottomPos);
|
||||||
|
var cornerBottomRight = cornerToptLeft.RotateDegree(180).Translate(rightPos, bottomPos);
|
||||||
|
|
||||||
|
return new PathCollection(cornerToptLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
|
||||||
|
}
|
||||||
|
|
||||||
public static string RedisKey(this IBotCredentials bc)
|
public static string RedisKey(this IBotCredentials bc)
|
||||||
{
|
{
|
||||||
return bc.Token.Substring(0, 10);
|
return bc.Token.Substring(0, 10);
|
||||||
|
Loading…
Reference in New Issue
Block a user