2017-05-27 08:19:27 +00:00
|
|
|
|
using Discord;
|
|
|
|
|
using Discord.WebSocket;
|
|
|
|
|
using NadekoBot.Extensions;
|
|
|
|
|
using NadekoBot.Services.Database.Models;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using NLog;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace NadekoBot.Services.Games
|
|
|
|
|
{
|
|
|
|
|
public class GamesService
|
|
|
|
|
{
|
|
|
|
|
private readonly BotConfig _bc;
|
|
|
|
|
|
|
|
|
|
public readonly ConcurrentDictionary<ulong, GirlRating> GirlRatings = new ConcurrentDictionary<ulong, GirlRating>();
|
|
|
|
|
public readonly ImmutableArray<string> EightBallResponses;
|
|
|
|
|
|
|
|
|
|
private readonly Timer _t;
|
|
|
|
|
private readonly DiscordShardedClient _client;
|
|
|
|
|
private readonly NadekoStrings _strings;
|
|
|
|
|
private readonly IImagesService _images;
|
|
|
|
|
private readonly Logger _log;
|
|
|
|
|
|
|
|
|
|
public readonly string TypingArticlesPath = "data/typing_articles2.json";
|
|
|
|
|
public List<TypingArticle> TypingArticles { get; } = new List<TypingArticle>();
|
|
|
|
|
|
|
|
|
|
public GamesService(DiscordShardedClient client, BotConfig bc, IEnumerable<GuildConfig> gcs,
|
|
|
|
|
NadekoStrings strings, IImagesService images)
|
|
|
|
|
{
|
|
|
|
|
_bc = bc;
|
|
|
|
|
_client = client;
|
|
|
|
|
_strings = strings;
|
|
|
|
|
_images = images;
|
|
|
|
|
_log = LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
|
|
|
|
//8ball
|
|
|
|
|
EightBallResponses = _bc.EightBallResponses.Select(ebr => ebr.Text).ToImmutableArray();
|
|
|
|
|
|
|
|
|
|
//girl ratings
|
|
|
|
|
_t = new Timer((_) =>
|
|
|
|
|
{
|
|
|
|
|
GirlRatings.Clear();
|
|
|
|
|
|
|
|
|
|
}, null, TimeSpan.FromDays(1), TimeSpan.FromDays(1));
|
|
|
|
|
|
|
|
|
|
//plantpick
|
|
|
|
|
client.MessageReceived += PotentialFlowerGeneration;
|
|
|
|
|
GenerationChannels = new ConcurrentHashSet<ulong>(gcs
|
|
|
|
|
.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId)));
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
TypingArticles = JsonConvert.DeserializeObject<List<TypingArticle>>(File.ReadAllText(TypingArticlesPath));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_log.Warn("Error while loading typing articles {0}", ex.ToString());
|
|
|
|
|
TypingArticles = new List<TypingArticle>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
public void AddTypingArticle(IUser user, string text)
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
TypingArticles.Add(new TypingArticle
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
Title = $"Text added on {DateTime.UtcNow} by {user}",
|
|
|
|
|
Text = text.SanitizeMentions(),
|
|
|
|
|
});
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
File.WriteAllText(TypingArticlesPath, JsonConvert.SerializeObject(TypingArticles));
|
2017-05-27 08:19:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ConcurrentHashSet<ulong> GenerationChannels { get; }
|
|
|
|
|
//channelid/message
|
|
|
|
|
public ConcurrentDictionary<ulong, List<IUserMessage>> PlantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>();
|
|
|
|
|
//channelId/last generation
|
|
|
|
|
public ConcurrentDictionary<ulong, DateTime> LastGenerations { get; } = new ConcurrentDictionary<ulong, DateTime>();
|
2017-05-29 04:13:22 +00:00
|
|
|
|
|
|
|
|
|
private ConcurrentDictionary<ulong, object> _locks { get; } = new ConcurrentDictionary<ulong, object>();
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
public (string Name, ImmutableArray<byte> Data) GetRandomCurrencyImage()
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
|
|
|
|
var rng = new NadekoRandom();
|
|
|
|
|
return _images.Currency[rng.Next(0, _images.Currency.Length)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetText(ITextChannel ch, string key, params object[] rep)
|
|
|
|
|
=> _strings.GetText(key, ch.GuildId, "Games".ToLowerInvariant(), rep);
|
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
private async Task PotentialFlowerGeneration(SocketMessage imsg)
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
|
|
|
|
var msg = imsg as SocketUserMessage;
|
|
|
|
|
if (msg == null || msg.Author.IsBot)
|
2017-05-29 04:13:22 +00:00
|
|
|
|
return;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
|
|
|
|
var channel = imsg.Channel as ITextChannel;
|
|
|
|
|
if (channel == null)
|
2017-05-29 04:13:22 +00:00
|
|
|
|
return;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
|
|
|
|
if (!GenerationChannels.Contains(channel.Id))
|
2017-05-29 04:13:22 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
try
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
var lastGeneration = LastGenerations.GetOrAdd(channel.Id, DateTime.MinValue);
|
|
|
|
|
var rng = new NadekoRandom();
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
if (DateTime.Now - TimeSpan.FromSeconds(_bc.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again
|
|
|
|
|
return;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
var num = rng.Next(1, 101) + _bc.CurrencyGenerationChance * 100;
|
|
|
|
|
if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.Now, lastGeneration))
|
|
|
|
|
{
|
|
|
|
|
var dropAmount = _bc.CurrencyDropAmount;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
|
2017-05-29 04:13:22 +00:00
|
|
|
|
if (dropAmount > 0)
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
var msgs = new IUserMessage[dropAmount];
|
|
|
|
|
var prefix = NadekoBot.Prefix;
|
|
|
|
|
var toSend = dropAmount == 1
|
|
|
|
|
? GetText(channel, "curgen_sn", _bc.CurrencySign)
|
|
|
|
|
+ " " + GetText(channel, "pick_sn", prefix)
|
|
|
|
|
: GetText(channel, "curgen_pl", dropAmount, _bc.CurrencySign)
|
|
|
|
|
+ " " + GetText(channel, "pick_pl", prefix);
|
|
|
|
|
var file = GetRandomCurrencyImage();
|
|
|
|
|
using (var fileStream = file.Data.ToStream())
|
2017-05-27 08:19:27 +00:00
|
|
|
|
{
|
2017-05-29 04:13:22 +00:00
|
|
|
|
var sent = await channel.SendFileAsync(
|
|
|
|
|
fileStream,
|
|
|
|
|
file.Name,
|
|
|
|
|
toSend).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
msgs[0] = sent;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
}
|
2017-05-29 04:13:22 +00:00
|
|
|
|
|
|
|
|
|
PlantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; });
|
2017-05-27 08:19:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-29 04:13:22 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LogManager.GetCurrentClassLogger().Warn(ex);
|
|
|
|
|
}
|
|
|
|
|
return;
|
2017-05-27 08:19:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|