Merge branch 'wip' into 1.9

This commit is contained in:
Master Kwoth 2017-11-05 20:58:21 +01:00
commit f9fc6daca7
19 changed files with 308 additions and 144 deletions

View File

@ -29,19 +29,18 @@ namespace NadekoBot.Modules.Administration
private static readonly object _locker = new object(); private static readonly object _locker = new object();
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IImagesService _images; private readonly IImageCache _images;
private readonly IBotConfigProvider _bc; private readonly IBotConfigProvider _bc;
private readonly NadekoBot _bot; private readonly NadekoBot _bot;
private readonly IBotCredentials _creds; private readonly IBotCredentials _creds;
private readonly IDataCache _cache; private readonly IDataCache _cache;
public SelfCommands(DbService db, NadekoBot bot, DiscordSocketClient client, public SelfCommands(DbService db, NadekoBot bot, DiscordSocketClient client,
IImagesService images, IBotConfigProvider bc, IBotConfigProvider bc, IBotCredentials creds, IDataCache cache)
IBotCredentials creds, IDataCache cache)
{ {
_db = db; _db = db;
_client = client; _client = client;
_images = images; _images = cache.LocalImages;
_bc = bc; _bc = bc;
_bot = bot; _bot = bot;
_creds = creds; _creds = creds;

View File

@ -30,11 +30,11 @@ namespace NadekoBot.Modules.Administration.Services
private readonly IBotCredentials _creds; private readonly IBotCredentials _creds;
private ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels = new ImmutableArray<AsyncLazy<IDMChannel>>(); private ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels = new ImmutableArray<AsyncLazy<IDMChannel>>();
private readonly IBotConfigProvider _bc; private readonly IBotConfigProvider _bc;
private readonly IImagesService _imgs; private readonly IImageCache _imgs;
public SelfService(DiscordSocketClient client, NadekoBot bot, CommandHandler cmdHandler, DbService db, public SelfService(DiscordSocketClient client, NadekoBot bot, CommandHandler cmdHandler, DbService db,
IBotConfigProvider bc, ILocalization localization, NadekoStrings strings, IBotCredentials creds, IBotConfigProvider bc, ILocalization localization, NadekoStrings strings, IBotCredentials creds,
IDataCache cache, IImagesService imgs) IDataCache cache)
{ {
_redis = cache.Redis; _redis = cache.Redis;
_bot = bot; _bot = bot;
@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Administration.Services
_client = client; _client = client;
_creds = creds; _creds = creds;
_bc = bc; _bc = bc;
_imgs = imgs; _imgs = cache.LocalImages;
var sub = _redis.GetSubscriber(); var sub = _redis.GetSubscriber();
sub.Subscribe(_creds.RedisKey() + "_reload_images", sub.Subscribe(_creds.RedisKey() + "_reload_images",

View File

@ -24,11 +24,11 @@ namespace NadekoBot.Modules.Gambling
private static readonly Regex fudgeRegex = new Regex(@"^(?<n1>\d+)d(?:F|f)$", RegexOptions.Compiled); private static readonly Regex fudgeRegex = new Regex(@"^(?<n1>\d+)d(?:F|f)$", RegexOptions.Compiled);
private static readonly char[] _fateRolls = { '-', ' ', '+' }; private static readonly char[] _fateRolls = { '-', ' ', '+' };
private readonly IImagesService _images; private readonly IImageCache _images;
public DriceRollCommands(IImagesService images) public DriceRollCommands(IDataCache data)
{ {
_images = images; _images = data.LocalImages;
} }
@ -141,10 +141,8 @@ namespace NadekoBot.Modules.Gambling
private async Task InternallDndRoll(string arg, bool ordered) private async Task InternallDndRoll(string arg, bool ordered)
{ {
Match match; Match match;
int n1;
int n2;
if ((match = fudgeRegex.Match(arg)).Length != 0 && if ((match = fudgeRegex.Match(arg)).Length != 0 &&
int.TryParse(match.Groups["n1"].ToString(), out n1) && int.TryParse(match.Groups["n1"].ToString(), out int n1) &&
n1 > 0 && n1 < 500) n1 > 0 && n1 < 500)
{ {
var rng = new NadekoRandom(); var rng = new NadekoRandom();
@ -164,13 +162,14 @@ namespace NadekoBot.Modules.Gambling
{ {
var rng = new NadekoRandom(); var rng = new NadekoRandom();
if (int.TryParse(match.Groups["n1"].ToString(), out n1) && if (int.TryParse(match.Groups["n1"].ToString(), out n1) &&
int.TryParse(match.Groups["n2"].ToString(), out n2) && int.TryParse(match.Groups["n2"].ToString(), out int n2) &&
n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0) n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0)
{ {
var add = 0; if (!int.TryParse(match.Groups["add"].Value, out int add) ||
var sub = 0; !int.TryParse(match.Groups["sub"].Value, out int sub))
int.TryParse(match.Groups["add"].Value, out add); {
int.TryParse(match.Groups["sub"].Value, out sub); return;
}
var arr = new int[n1]; var arr = new int[n1];
for (int i = 0; i < n1; i++) for (int i = 0; i < n1; i++)
@ -179,7 +178,7 @@ namespace NadekoBot.Modules.Gambling
} }
var sum = arr.Sum(); var sum = arr.Sum();
var embed = new EmbedBuilder().WithOkColor().WithDescription(Context.User.Mention + " " +GetText("dice_rolled_num", n1) + $"`1 - {n2}`") var embed = new EmbedBuilder().WithOkColor().WithDescription(Context.User.Mention + " " + GetText("dice_rolled_num", n1) + $"`1 - {n2}`")
.AddField(efb => efb.WithName(Format.Bold("Rolls")) .AddField(efb => efb.WithName(Format.Bold("Rolls"))
.WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString()))))) .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString())))))
.AddField(efb => efb.WithName(Format.Bold("Sum")) .AddField(efb => efb.WithName(Format.Bold("Sum"))

View File

@ -17,15 +17,15 @@ namespace NadekoBot.Modules.Gambling
[Group] [Group]
public class FlipCoinCommands : NadekoSubmodule public class FlipCoinCommands : NadekoSubmodule
{ {
private readonly IImagesService _images; private readonly IImageCache _images;
private readonly IBotConfigProvider _bc; private readonly IBotConfigProvider _bc;
private readonly CurrencyService _cs; private readonly CurrencyService _cs;
private static readonly NadekoRandom rng = new NadekoRandom(); private static readonly NadekoRandom rng = new NadekoRandom();
public FlipCoinCommands(IImagesService images, CurrencyService cs, IBotConfigProvider bc) public FlipCoinCommands(IDataCache data, CurrencyService cs, IBotConfigProvider bc)
{ {
_images = images; _images = data.LocalImages;
_bc = bc; _bc = bc;
_cs = cs; _cs = cs;
} }

View File

@ -1,7 +1,5 @@
using Discord; using Discord;
using NadekoBot.Core.Services; using NadekoBot.Core.Services;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Gambling.Services namespace NadekoBot.Modules.Gambling.Services
@ -11,9 +9,6 @@ namespace NadekoBot.Modules.Gambling.Services
private readonly DbService _db; private readonly DbService _db;
private readonly CurrencyService _cs; private readonly CurrencyService _cs;
public ConcurrentDictionary<ulong, DateTime> DivorceCooldowns { get; } = new ConcurrentDictionary<ulong, DateTime>();
public ConcurrentDictionary<ulong, DateTime> AffinityCooldowns { get; } = new ConcurrentDictionary<ulong, DateTime>();
public WaifuService(DbService db, CurrencyService cs) public WaifuService(DbService db, CurrencyService cs)
{ {
_db = db; _db = db;

View File

@ -32,12 +32,12 @@ namespace NadekoBot.Modules.Gambling
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg //https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
//thanks to judge for helping me with this //thanks to judge for helping me with this
private readonly IImagesService _images; private readonly IImageCache _images;
private readonly CurrencyService _cs; private readonly CurrencyService _cs;
public SlotCommands(IImagesService images, IBotConfigProvider bc, CurrencyService cs) public SlotCommands(IDataCache data, IBotConfigProvider bc, CurrencyService cs)
{ {
_images = images; _images = data.LocalImages;
_bc = bc; _bc = bc;
_cs = cs; _cs = cs;
} }

View File

@ -54,17 +54,17 @@ namespace NadekoBot.Modules.Gambling
NotEnoughFunds, NotEnoughFunds,
InsufficientAmount InsufficientAmount
} }
private static readonly TimeSpan _affinityLimit = TimeSpan.FromMinutes(30);
private readonly IBotConfigProvider _bc; private readonly IBotConfigProvider _bc;
private readonly CurrencyService _cs; private readonly CurrencyService _cs;
private readonly DbService _db; private readonly DbService _db;
private readonly IDataCache _cache;
public WaifuClaimCommands(IBotConfigProvider bc, CurrencyService cs, DbService db) public WaifuClaimCommands(IDataCache cache, IBotConfigProvider bc, CurrencyService cs, DbService db)
{ {
_bc = bc; _bc = bc;
_cs = cs; _cs = cs;
_db = db; _db = db;
_cache = cache;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -213,8 +213,6 @@ namespace NadekoBot.Modules.Gambling
Cooldown Cooldown
} }
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[Priority(0)] [Priority(0)]
@ -229,7 +227,7 @@ namespace NadekoBot.Modules.Gambling
return; return;
DivorceResult result; DivorceResult result;
var difference = TimeSpan.Zero; TimeSpan? remaining = null;
var amount = 0; var amount = 0;
WaifuInfo w = null; WaifuInfo w = null;
using (var uow = _db.UnitOfWork) using (var uow = _db.UnitOfWork)
@ -238,9 +236,7 @@ namespace NadekoBot.Modules.Gambling
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id) if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id)
result = DivorceResult.NotYourWife; result = DivorceResult.NotYourWife;
else if (_service.DivorceCooldowns.AddOrUpdate(Context.User.Id, else if (!_cache.TryAddDivorceCooldown(Context.User.Id, out remaining))
now,
(key, old) => ((difference = now.Subtract(old)) > _divorceLimit) ? now : old) != now)
{ {
result = DivorceResult.Cooldown; result = DivorceResult.Cooldown;
} }
@ -289,10 +285,9 @@ namespace NadekoBot.Modules.Gambling
} }
else else
{ {
var remaining = _divorceLimit.Subtract(difference);
await ReplyErrorLocalized("waifu_recent_divorce", await ReplyErrorLocalized("waifu_recent_divorce",
Format.Bold(((int)remaining.TotalHours).ToString()), Format.Bold(((int)remaining?.TotalHours).ToString()),
Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false); Format.Bold(remaining?.Minutes.ToString())).ConfigureAwait(false);
} }
} }
@ -307,8 +302,7 @@ namespace NadekoBot.Modules.Gambling
} }
DiscordUser oldAff = null; DiscordUser oldAff = null;
var sucess = false; var sucess = false;
var cooldown = false; TimeSpan? remaining = null;
var difference = TimeSpan.Zero;
using (var uow = _db.UnitOfWork) using (var uow = _db.UnitOfWork)
{ {
var w = uow.Waifus.ByWaifuUserId(Context.User.Id); var w = uow.Waifus.ByWaifuUserId(Context.User.Id);
@ -318,11 +312,8 @@ namespace NadekoBot.Modules.Gambling
{ {
//todo don't let people change affinity on different shards //todo don't let people change affinity on different shards
} }
else if (_service.AffinityCooldowns.AddOrUpdate(Context.User.Id, else if (!_cache.TryAddAffinityCooldown(Context.User.Id, out remaining))
now,
(key, old) => ((difference = now.Subtract(old)) > _affinityLimit) ? now : old) != now)
{ {
cooldown = true;
} }
else if (w == null) else if (w == null)
{ {
@ -364,12 +355,11 @@ namespace NadekoBot.Modules.Gambling
} }
if (!sucess) if (!sucess)
{ {
if (cooldown) if (remaining != null)
{ {
var remaining = _affinityLimit.Subtract(difference);
await ReplyErrorLocalized("waifu_affinity_cooldown", await ReplyErrorLocalized("waifu_affinity_cooldown",
Format.Bold(((int)remaining.TotalHours).ToString()), Format.Bold(((int)remaining?.TotalHours).ToString()),
Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false); Format.Bold(remaining?.Minutes.ToString())).ConfigureAwait(false);
} }
else else
{ {

View File

@ -14,6 +14,7 @@ namespace NadekoBot.Modules.Games.Common
public class GirlRating public class GirlRating
{ {
private static readonly Logger _log = LogManager.GetCurrentClassLogger(); private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private readonly IImageCache _images;
public double Crazy { get; } public double Crazy { get; }
public double Hot { get; } public double Hot { get; }
@ -21,8 +22,9 @@ namespace NadekoBot.Modules.Games.Common
public string Advice { get; } public string Advice { get; }
public AsyncLazy<string> Url { get; } public AsyncLazy<string> Url { get; }
public GirlRating(IImagesService _images, double crazy, double hot, int roll, string advice) public GirlRating(IImageCache images, double crazy, double hot, int roll, string advice)
{ {
_images = images;
Crazy = crazy; Crazy = crazy;
Hot = hot; Hot = hot;
Roll = roll; Roll = roll;
@ -45,7 +47,7 @@ namespace NadekoBot.Modules.Games.Common
using (var pointMs = new MemoryStream(_images.RategirlDot.ToArray(), false)) using (var pointMs = new MemoryStream(_images.RategirlDot.ToArray(), false))
using (var pointImg = Image.Load(pointMs)) using (var pointImg = Image.Load(pointMs))
{ {
img.DrawImage(pointImg, 100, default(Size), new Point(pointx - 10, pointy - 10)); img.DrawImage(pointImg, 100, default, new Point(pointx - 10, pointy - 10));
} }
string url; string url;

View File

@ -19,11 +19,11 @@ namespace NadekoBot.Modules.Games
//todo update docs //todo update docs
public partial class Games : NadekoTopLevelModule<GamesService> public partial class Games : NadekoTopLevelModule<GamesService>
{ {
private readonly IImagesService _images; private readonly IImageCache _images;
public Games(IImagesService images) public Games(IDataCache data)
{ {
_images = images; _images = data.LocalImages;
} }
//#if GLOBAL_NADEKO //#if GLOBAL_NADEKO
// [NadekoCommand, Usage, Description, Aliases] // [NadekoCommand, Usage, Description, Aliases]

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Common.Attributes; using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Games.Services; using NadekoBot.Modules.Games.Services;
using System;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
@ -88,12 +89,18 @@ namespace NadekoBot.Modules.Games
else else
msgToSend += " " + GetText("pick_sn", Prefix); msgToSend += " " + GetText("pick_sn", Prefix);
using (var toSend = imgData.Data.ToStream()) using (var toSend = imgData.ToStream())
{ {
msg = await Context.Channel.SendFileAsync(toSend, imgData.Name, msgToSend).ConfigureAwait(false); msg = await Context.Channel.SendFileAsync(toSend, "plant.png", msgToSend, options: new RequestOptions()
{
RetryMode = RetryMode.AlwaysRetry
}).ConfigureAwait(false);
} }
} }
catch { } catch (Exception ex)
{
_log.Warn(ex);
}
var msgs = new IUserMessage[amount]; var msgs = new IUserMessage[amount];
msgs[0] = msg; msgs[0] = msg;

View File

@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Games.Services
private readonly Timer _t; private readonly Timer _t;
private readonly CommandHandler _cmd; private readonly CommandHandler _cmd;
private readonly NadekoStrings _strings; private readonly NadekoStrings _strings;
private readonly IImagesService _images; private readonly IImageCache _images;
private readonly Logger _log; private readonly Logger _log;
private readonly NadekoRandom _rng; private readonly NadekoRandom _rng;
private readonly CurrencyService _cs; private readonly CurrencyService _cs;
@ -57,13 +57,13 @@ namespace NadekoBot.Modules.Games.Services
public ConcurrentDictionary<ulong, Nunchi> NunchiGames { get; } = new ConcurrentDictionary<ulong, Common.Nunchi.Nunchi>(); public ConcurrentDictionary<ulong, Nunchi> NunchiGames { get; } = new ConcurrentDictionary<ulong, Common.Nunchi.Nunchi>();
public GamesService(CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot, public GamesService(CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot,
NadekoStrings strings, IImagesService images, CommandHandler cmdHandler, NadekoStrings strings, IDataCache data, CommandHandler cmdHandler,
CurrencyService cs) CurrencyService cs)
{ {
_bc = bc; _bc = bc;
_cmd = cmd; _cmd = cmd;
_strings = strings; _strings = strings;
_images = images; _images = data.LocalImages;
_cmdHandler = cmdHandler; _cmdHandler = cmdHandler;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_rng = new NadekoRandom(); _rng = new NadekoRandom();
@ -144,10 +144,11 @@ namespace NadekoBot.Modules.Games.Services
private ConcurrentDictionary<ulong, object> _locks { get; } = new ConcurrentDictionary<ulong, object>(); private ConcurrentDictionary<ulong, object> _locks { get; } = new ConcurrentDictionary<ulong, object>();
public ConcurrentHashSet<ulong> HalloweenAwardedUsers { get; } = new ConcurrentHashSet<ulong>(); public ConcurrentHashSet<ulong> HalloweenAwardedUsers { get; } = new ConcurrentHashSet<ulong>();
public (string Name, ImmutableArray<byte> Data) GetRandomCurrencyImage() public byte[] GetRandomCurrencyImage()
{ {
var rng = new NadekoRandom(); var rng = new NadekoRandom();
return _images.Currency[rng.Next(0, _images.Currency.Length)]; var cur = _images.Currency;
return cur[rng.Next(0, cur.Length)];
} }
private string GetText(ITextChannel ch, string key, params object[] rep) private string GetText(ITextChannel ch, string key, params object[] rep)
@ -195,11 +196,11 @@ namespace NadekoBot.Modules.Games.Services
: GetText(channel, "curgen_pl", dropAmount, _bc.BotConfig.CurrencySign) : GetText(channel, "curgen_pl", dropAmount, _bc.BotConfig.CurrencySign)
+ " " + GetText(channel, "pick_pl", prefix); + " " + GetText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage(); var file = GetRandomCurrencyImage();
using (var fileStream = file.Data.ToStream()) using (var fileStream = file.ToStream())
{ {
var sent = await channel.SendFileAsync( var sent = await channel.SendFileAsync(
fileStream, fileStream,
file.Name, "drop.png",
toSend).ConfigureAwait(false); toSend).ConfigureAwait(false);
msgs[0] = sent; msgs[0] = sent;

View File

@ -34,7 +34,7 @@ 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 IImageCache _imgs;
private readonly IDataCache _cache; private readonly IDataCache _cache;
private readonly FontProvider _fonts; private readonly FontProvider _fonts;
private readonly HttpClient http; private readonly HttpClient http;
@ -60,7 +60,7 @@ 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, IImagesService imgs, IDataCache cache, DbService db, NadekoBot bot, IDataCache cache,
FontProvider fonts) FontProvider fonts)
{ {
Http = new HttpClient(); Http = new HttpClient();
@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Searches.Services
_google = google; _google = google;
_db = db; _db = db;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_imgs = imgs; _imgs = cache.LocalImages;
_cache = cache; _cache = cache;
_fonts = fonts; _fonts = fonts;
http = new HttpClient(); http = new HttpClient();

View File

@ -19,8 +19,6 @@ using SixLabors.Fonts;
using System.IO; using System.IO;
using SixLabors.Primitives; using SixLabors.Primitives;
using System.Net.Http; using System.Net.Http;
using SixLabors.Shapes;
using System.Numerics;
using ImageSharp.Drawing.Pens; using ImageSharp.Drawing.Pens;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
@ -33,7 +31,7 @@ namespace NadekoBot.Modules.Xp.Services
private readonly DbService _db; private readonly DbService _db;
private readonly CommandHandler _cmd; private readonly CommandHandler _cmd;
private readonly IBotConfigProvider _bc; private readonly IBotConfigProvider _bc;
private readonly IImagesService _images; private readonly IImageCache _images;
private readonly Logger _log; private readonly Logger _log;
private readonly NadekoStrings _strings; private readonly NadekoStrings _strings;
private readonly IDataCache _cache; private readonly IDataCache _cache;
@ -61,14 +59,13 @@ namespace NadekoBot.Modules.Xp.Services
private readonly HttpClient http = new HttpClient(); private readonly HttpClient http = new HttpClient();
public XpService(CommandHandler cmd, IBotConfigProvider bc, public XpService(CommandHandler cmd, IBotConfigProvider bc,
NadekoBot bot, IImagesService images, NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
DbService db, NadekoStrings strings, IDataCache cache,
FontProvider fonts) FontProvider fonts)
{ {
_db = db; _db = db;
_cmd = cmd; _cmd = cmd;
_bc = bc; _bc = bc;
_images = images; _images = cache.LocalImages;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_strings = strings; _strings = strings;
_cache = cache; _cache = cache;

View File

@ -7,6 +7,8 @@ namespace NadekoBot.Core.Services
public interface IDataCache public interface IDataCache
{ {
ConnectionMultiplexer Redis { get; } ConnectionMultiplexer Redis { get; }
IImageCache LocalImages { get; }
Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key); Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key);
Task<(bool Success, string Data)> TryGetAnimeDataAsync(string key); Task<(bool Success, string Data)> TryGetAnimeDataAsync(string key);
Task<(bool Success, string Data)> TryGetNovelDataAsync(string key); Task<(bool Success, string Data)> TryGetNovelDataAsync(string key);
@ -15,5 +17,7 @@ namespace NadekoBot.Core.Services
Task SetNovelDataAsync(string link, string data); Task SetNovelDataAsync(string link, string data);
TimeSpan? AddTimelyClaim(ulong id, int period); TimeSpan? AddTimelyClaim(ulong id, int period);
void RemoveAllTimelyClaims(); void RemoveAllTimelyClaims();
bool TryAddAffinityCooldown(ulong userId, out TimeSpan? time);
bool TryAddDivorceCooldown(ulong userId, out TimeSpan? time);
} }
} }

View File

@ -0,0 +1,27 @@
using System.Collections.Immutable;
namespace NadekoBot.Core.Services
{
public interface IImageCache
{
byte[] Heads { get; }
byte[] Tails { get; }
byte[][] Currency { get; }
byte[][] Dice { get; }
byte[] SlotBackground { get; }
byte[][] SlotEmojis { get; }
byte[][] SlotNumbers { get; }
byte[] WifeMatrix { get; }
byte[] RategirlDot { get; }
byte[] XpCard { get; }
byte[] Rip { get; }
byte[] FlowerCircle { get; }
void Reload();
}
}

View File

@ -1,27 +0,0 @@
using System.Collections.Immutable;
namespace NadekoBot.Core.Services
{
public interface IImagesService : INService
{
ImmutableArray<byte> Heads { get; }
ImmutableArray<byte> Tails { get; }
ImmutableArray<(string, ImmutableArray<byte>)> Currency { get; }
ImmutableArray<ImmutableArray<byte>> Dice { get; }
ImmutableArray<byte> SlotBackground { get; }
ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; }
ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; }
ImmutableArray<byte> WifeMatrix { get; }
ImmutableArray<byte> RategirlDot { get; }
ImmutableArray<byte> XpCard { get; }
ImmutableArray<byte> Rip { get; }
ImmutableArray<byte> FlowerCircle { get; }
void Reload();
}
}

View File

@ -1,16 +1,22 @@
using NLog; using NadekoBot.Extensions;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System; using System;
using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace NadekoBot.Core.Services.Impl namespace NadekoBot.Core.Services.Impl
{ {
//todo move everything to redis //todo move everything to redis
public class ImagesService : IImagesService public class RedisImagesCache : IImageCache
{ {
private readonly ConnectionMultiplexer _con;
private readonly IBotCredentials _creds;
private readonly Logger _log; private readonly Logger _log;
private IDatabase _db => _con.GetDatabase();
private const string _basePath = "data/images/"; private const string _basePath = "data/images/";
private const string _headsPath = _basePath + "coins/heads.png"; private const string _headsPath = _basePath + "coins/heads.png";
@ -31,67 +37,189 @@ namespace NadekoBot.Core.Services.Impl
private const string _ripPath = _basePath + "rip/rip.png"; private const string _ripPath = _basePath + "rip/rip.png";
private const string _ripFlowersPath = _basePath + "rip/rose_overlay.png"; private const string _ripFlowersPath = _basePath + "rip/rose_overlay.png";
public byte[] Heads
public ImmutableArray<byte> Heads { get; private set; }
public ImmutableArray<byte> Tails { get; private set; }
public ImmutableArray<(string, ImmutableArray<byte>)> Currency { get; private set; }
public ImmutableArray<ImmutableArray<byte>> Dice { get; private set; }
public ImmutableArray<byte> SlotBackground { get; private set; }
public ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; private set; }
public ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; private set; }
public ImmutableArray<byte> WifeMatrix { get; private set; }
public ImmutableArray<byte> RategirlDot { 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()
{ {
get
{
return Get<byte[]>("heads");
}
set
{
Set("heads", value);
}
}
public byte[] Tails
{
get
{
return Get<byte[]>("tails");
}
set
{
Set("tails", value);
}
}
public byte[][] Currency
{
get
{
return Get<byte[][]>("currency");
}
set
{
Set("currency", value);
}
}
public byte[][] Dice
{
get
{
return Get<byte[][]>("dice");
}
set
{
Set("dice", value);
}
}
public byte[] SlotBackground
{
get
{
return Get<byte[]>("slot_background");
}
set
{
Set("slot_background", value);
}
}
public byte[][] SlotNumbers
{
get
{
return Get<byte[][]>("slotnumbers");
}
set
{
Set("slotnumbers", value);
}
}
public byte[][] SlotEmojis
{
get
{
return Get<byte[][]>("slotemojis");
}
set
{
Set("slotemojis", value);
}
}
public byte[] WifeMatrix
{
get
{
return Get<byte[]>("wife_matrix");
}
set
{
Set("wife_matrix", value);
}
}
public byte[] RategirlDot
{
get
{
return Get<byte[]>("rategirl_dot");
}
set
{
Set("rategirl_dot", value);
}
}
public byte[] XpCard
{
get
{
return Get<byte[]>("xp_card");
}
set
{
Set("xp_card", value);
}
}
public byte[] Rip
{
get
{
return Get<byte[]>("rip");
}
set
{
Set("rip", value);
}
}
public byte[] FlowerCircle
{
get
{
return Get<byte[]>("flower_circle");
}
set
{
Set("flower_circle", value);
}
}
public RedisImagesCache(ConnectionMultiplexer con, IBotCredentials creds)
{
_con = con;
_creds = creds;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
this.Reload();
} }
public void Reload() public void Reload()
{ {
try try
{ {
Heads = File.ReadAllBytes(_headsPath).ToImmutableArray(); Heads = File.ReadAllBytes(_headsPath);
Tails = File.ReadAllBytes(_tailsPath).ToImmutableArray(); Tails = File.ReadAllBytes(_tailsPath);
Currency = Directory.GetFiles(_currencyImagesPath) Currency = Directory.GetFiles(_currencyImagesPath)
.Select(x => (Path.GetFileName(x), File.ReadAllBytes(x).ToImmutableArray())) .Select(x => File.ReadAllBytes(x))
.ToImmutableArray(); .ToArray();
Dice = Directory.GetFiles(_diceImagesPath) Dice = Directory.GetFiles(_diceImagesPath)
.OrderBy(x => int.Parse(Path.GetFileNameWithoutExtension(x))) .OrderBy(x => int.Parse(Path.GetFileNameWithoutExtension(x)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray()) .Select(x => File.ReadAllBytes(x))
.ToImmutableArray(); .ToArray();
SlotBackground = File.ReadAllBytes(_slotBackgroundPath).ToImmutableArray(); SlotBackground = File.ReadAllBytes(_slotBackgroundPath);
SlotNumbers = Directory.GetFiles(_slotNumbersPath) SlotNumbers = Directory.GetFiles(_slotNumbersPath)
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f))) .OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray()) .Select(x => File.ReadAllBytes(x))
.ToImmutableArray(); .ToArray();
SlotEmojis = Directory.GetFiles(_slotEmojisPath) SlotEmojis = Directory.GetFiles(_slotEmojisPath)
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f))) .OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray()) .Select(x => File.ReadAllBytes(x))
.ToImmutableArray(); .ToArray();
WifeMatrix = File.ReadAllBytes(_wifeMatrixPath).ToImmutableArray(); WifeMatrix = File.ReadAllBytes(_wifeMatrixPath);
RategirlDot = File.ReadAllBytes(_rategirlDot).ToImmutableArray(); RategirlDot = File.ReadAllBytes(_rategirlDot);
XpCard = File.ReadAllBytes(_xpCardPath).ToImmutableArray(); XpCard = File.ReadAllBytes(_xpCardPath);
Rip = File.ReadAllBytes(_ripPath).ToImmutableArray(); Rip = File.ReadAllBytes(_ripPath);
FlowerCircle = File.ReadAllBytes(_ripFlowersPath).ToImmutableArray(); FlowerCircle = File.ReadAllBytes(_ripFlowersPath);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -99,5 +227,15 @@ namespace NadekoBot.Core.Services.Impl
throw; throw;
} }
} }
private T Get<T>(string key) where T : class
{
return JsonConvert.DeserializeObject<T>(_db.StringGet($"{_creds.RedisKey()}_localimg_{key}"));
}
private void Set(string key, object obj)
{
_db.StringSet($"{_creds.RedisKey()}_localimg_{key}", JsonConvert.SerializeObject(obj));
}
} }
} }

View File

@ -9,6 +9,9 @@ namespace NadekoBot.Core.Services.Impl
public class RedisCache : IDataCache public class RedisCache : IDataCache
{ {
public ConnectionMultiplexer Redis { get; } public ConnectionMultiplexer Redis { get; }
public IImageCache LocalImages { get; }
private readonly IDatabase _db; private readonly IDatabase _db;
private readonly string _redisKey; private readonly string _redisKey;
@ -16,6 +19,7 @@ namespace NadekoBot.Core.Services.Impl
{ {
Redis = ConnectionMultiplexer.Connect("127.0.0.1"); Redis = ConnectionMultiplexer.Connect("127.0.0.1");
Redis.PreserveAsyncOrder = false; Redis.PreserveAsyncOrder = false;
LocalImages = new RedisImagesCache(Redis, creds);
_db = Redis.GetDatabase(); _db = Redis.GetDatabase();
_redisKey = creds.RedisKey(); _redisKey = creds.RedisKey();
} }
@ -83,5 +87,31 @@ namespace NadekoBot.Core.Services.Impl
_db.KeyDelete(k, CommandFlags.FireAndForget); _db.KeyDelete(k, CommandFlags.FireAndForget);
} }
} }
public bool TryAddAffinityCooldown(ulong userId, out TimeSpan? time)
{
time = _db.KeyTimeToLive($"{_redisKey}_affinity_{userId}");
if (time == null)
{
time = TimeSpan.FromMinutes(30);
_db.StringSet($"{_redisKey}_affinity_{userId}", true);
_db.KeyExpire($"{_redisKey}_affinity_{userId}", time);
return true;
}
return false;
}
public bool TryAddDivorceCooldown(ulong userId, out TimeSpan? time)
{
time = _db.KeyTimeToLive($"{_redisKey}_divorce_{userId}");
if (time == null)
{
time = TimeSpan.FromHours(6);
_db.StringSet($"{_redisKey}_divorce_{userId}", true);
_db.KeyExpire($"{_redisKey}_divorce_{userId}", time);
return true;
}
return false;
}
} }
} }

View File

@ -72,6 +72,8 @@ namespace NadekoBot.Core.Services
_key = _creds.RedisKey(); _key = _creds.RedisKey();
_redis = ConnectionMultiplexer.Connect("127.0.0.1"); _redis = ConnectionMultiplexer.Connect("127.0.0.1");
new RedisImagesCache(_redis, _creds).Reload(); //reload images into redis
//setup initial shard statuses //setup initial shard statuses
_defaultShardState = new ShardComMessage() _defaultShardState = new ShardComMessage()
{ {