trivia questions and pokemon data will be stored in redis, instead of per-shard

This commit is contained in:
Master Kwoth
2017-11-06 10:01:38 +01:00
parent 817fd7ce31
commit e79b3db818
13 changed files with 195 additions and 77 deletions

View File

@ -19,6 +19,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
{
private readonly SemaphoreSlim _guessLock = new SemaphoreSlim(1, 1);
private readonly Logger _log;
private readonly IDataCache _cache;
private readonly NadekoStrings _strings;
private readonly DiscordSocketClient _client;
private readonly IBotConfigProvider _bc;
@ -43,11 +44,15 @@ namespace NadekoBot.Modules.Games.Common.Trivia
public int WinRequirement { get; }
private readonly TriviaQuestionPool _questionPool;
public TriviaGame(NadekoStrings strings, DiscordSocketClient client, IBotConfigProvider bc,
CurrencyService cs, IGuild guild, ITextChannel channel,
IDataCache cache, CurrencyService cs, IGuild guild, ITextChannel channel,
bool showHints, int winReq, bool isPokemon)
{
_log = LogManager.GetCurrentClassLogger();
_cache = cache;
_questionPool = new TriviaQuestionPool(_cache);
_strings = strings;
_client = client;
_bc = bc;
@ -74,7 +79,7 @@ namespace NadekoBot.Modules.Games.Common.Trivia
_triviaCancelSource = new CancellationTokenSource();
// load question
CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(OldQuestions, IsPokemon);
CurrentQuestion = _questionPool.GetRandomQuestion(OldQuestions, IsPokemon);
if (string.IsNullOrWhiteSpace(CurrentQuestion?.Answer) || string.IsNullOrWhiteSpace(CurrentQuestion.Question))
{
await Channel.SendErrorAsync(GetText("trivia_game"), GetText("failed_loading_question")).ConfigureAwait(false);

View File

@ -1,62 +1,43 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using NadekoBot.Common;
using NadekoBot.Extensions;
using Newtonsoft.Json;
using NadekoBot.Core.Services;
namespace NadekoBot.Modules.Games.Common.Trivia
{
public class TriviaQuestionPool
{
public class PokemonNameId
{
public int Id { get; set; }
public string Name { get; set; }
}
private static TriviaQuestionPool _instance;
public static TriviaQuestionPool Instance { get; } = _instance ?? (_instance = new TriviaQuestionPool());
private const string questionsFile = "data/trivia_questions.json";
private const string pokemonMapPath = "data/pokemon/name-id_map4.json";
private readonly IDataCache _cache;
private readonly int maxPokemonId;
private Random rng { get; } = new NadekoRandom();
private TriviaQuestion[] pool { get; }
private ImmutableDictionary<int, string> map { get; }
private readonly NadekoRandom _rng = new NadekoRandom();
static TriviaQuestionPool() { }
private TriviaQuestion[] Pool => _cache.LocalData.TriviaQuestions;
private IReadOnlyDictionary<int, string> Map => _cache.LocalData.PokemonMap;
private TriviaQuestionPool()
public TriviaQuestionPool(IDataCache cache)
{
pool = JsonConvert.DeserializeObject<TriviaQuestion[]>(File.ReadAllText(questionsFile));
map = JsonConvert.DeserializeObject<PokemonNameId[]>(File.ReadAllText(pokemonMapPath))
.ToDictionary(x => x.Id, x => x.Name)
.ToImmutableDictionary();
_cache = cache;
maxPokemonId = 721; //xd
}
public TriviaQuestion GetRandomQuestion(HashSet<TriviaQuestion> exclude, bool isPokemon)
{
if (pool.Length == 0)
if (Pool.Length == 0)
return null;
if (isPokemon)
{
var num = rng.Next(1, maxPokemonId + 1);
var num = _rng.Next(1, maxPokemonId + 1);
return new TriviaQuestion("Who's That Pokémon?",
map[num].ToTitleCase(),
Map[num].ToTitleCase(),
"Pokemon",
$@"http://nadekobot.me/images/pokemon/shadows/{num}.png",
$@"http://nadekobot.me/images/pokemon/real/{num}.png");
}
TriviaQuestion randomQuestion;
while (exclude.Contains(randomQuestion = pool[rng.Next(0, pool.Length)])) ;
while (exclude.Contains(randomQuestion = Pool[_rng.Next(0, Pool.Length)])) ;
return randomQuestion;
}

View File

@ -15,12 +15,15 @@ namespace NadekoBot.Modules.Games
[Group]
public class TriviaCommands : NadekoSubmodule<GamesService>
{
private readonly IDataCache _cache;
private readonly CurrencyService _cs;
private readonly DiscordSocketClient _client;
private readonly IBotConfigProvider _bc;
public TriviaCommands(DiscordSocketClient client, IBotConfigProvider bc, CurrencyService cs)
public TriviaCommands(DiscordSocketClient client, IDataCache cache,
IBotConfigProvider bc, CurrencyService cs)
{
_cache = cache;
_cs = cs;
_client = client;
_bc = bc;
@ -45,7 +48,7 @@ namespace NadekoBot.Modules.Games
var showHints = !additionalArgs.Contains("nohint");
var isPokemon = additionalArgs.Contains("pokemon");
var trivia = new TriviaGame(_strings, _client, _bc, _cs, channel.Guild, channel, showHints, winReq, isPokemon);
var trivia = new TriviaGame(_strings, _client, _bc, _cache, _cs, channel.Guild, channel, showHints, winReq, isPokemon);
if (_service.RunningTrivias.TryAdd(channel.Guild.Id, trivia))
{
try

View File

@ -1,55 +0,0 @@
using System.Collections.Generic;
namespace NadekoBot.Modules.Searches.Common
{
public class SearchPokemon
{
public class GenderRatioClass
{
public float M { get; set; }
public float F { get; set; }
}
public class BaseStatsClass
{
public int HP { get; set; }
public int ATK { get; set; }
public int DEF { get; set; }
public int SPA { get; set; }
public int SPD { get; set; }
public int SPE { get; set; }
public override string ToString() => $@"**HP:** {HP,-4} **ATK:** {ATK,-4} **DEF:** {DEF,-4}
**SPA:** {SPA,-4} **SPD:** {SPD,-4} **SPE:** {SPE,-4}";
}
public int Id { get; set; }
public string Species { get; set; }
public string[] Types { get; set; }
public GenderRatioClass GenderRatio { get; set; }
public BaseStatsClass BaseStats { get; set; }
public Dictionary<string, string> Abilities { get; set; }
public float HeightM { get; set; }
public float WeightKg { get; set; }
public string Color { get; set; }
public string[] Evos { get; set; }
public string[] EggGroups { get; set; }
// public override string ToString() => $@"`Name:` {Species}
//`Types:` {string.Join(", ", Types)}
//`Stats:` {BaseStats}
//`Height:` {HeightM,4}m `Weight:` {WeightKg}kg
//`Abilities:` {string.Join(", ", Abilities.Values)}";
}
public class SearchPokemonAbility
{
public string Desc { get; set; }
public string ShortDesc { get; set; }
public string Name { get; set; }
public float Rating { get; set; }
// public override string ToString() => $@"`Name:` : {Name}
//`Rating:` {Rating}
//`Description:` {Desc}";
}
}

View File

@ -6,7 +6,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Searches.Common;
using NadekoBot.Core.Common.Pokemon;
using NadekoBot.Core.Services;
namespace NadekoBot.Modules.Searches
{
@ -15,8 +16,15 @@ namespace NadekoBot.Modules.Searches
[Group]
public class PokemonSearchCommands : NadekoSubmodule<SearchesService>
{
public Dictionary<string, SearchPokemon> Pokemons => _service.Pokemons;
public Dictionary<string, SearchPokemonAbility> PokemonAbilities => _service.PokemonAbilities;
private readonly IDataCache _cache;
public IReadOnlyDictionary<string, SearchPokemon> Pokemons => _cache.LocalData.Pokemons;
public IReadOnlyDictionary<string, SearchPokemonAbility> PokemonAbilities => _cache.LocalData.PokemonAbilities;
public PokemonSearchCommands(IDataCache cache)
{
_cache = cache;
}
[NadekoCommand, Usage, Description, Aliases]
public async Task Pokemon([Remainder] string pokemon = null)

View File

@ -17,7 +17,6 @@ using System.Net.Http;
using Newtonsoft.Json.Linq;
using AngleSharp;
using System.Threading;
using NadekoBot.Modules.Searches.Exceptions;
using ImageSharp;
using Image = ImageSharp.Image;
using SixLabors.Primitives;
@ -41,12 +40,6 @@ namespace NadekoBot.Modules.Searches.Services
public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
public ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
public readonly string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities7.json";
public readonly string PokemonListFile = "data/pokemon/pokemon_list7.json";
public Dictionary<string, SearchPokemon> Pokemons { get; } = new Dictionary<string, SearchPokemon>();
public Dictionary<string, SearchPokemonAbility> PokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>();
public List<WoWJoke> WowJokes { get; } = new List<WoWJoke>();
public List<MagicItem> MagicItems { get; } = new List<MagicItem>();
@ -113,17 +106,6 @@ namespace NadekoBot.Modules.Searches.Services
return Task.CompletedTask;
};
//pokemon commands
if (File.Exists(PokemonListFile))
{
Pokemons = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemon>>(File.ReadAllText(PokemonListFile));
}
else
_log.Warn(PokemonListFile + " is missing. Pokemon abilities not loaded.");
if (File.Exists(PokemonAbilitiesFile))
PokemonAbilities = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemonAbility>>(File.ReadAllText(PokemonAbilitiesFile));
else
_log.Warn(PokemonAbilitiesFile + " is missing. Pokemon abilities not loaded.");
//joke commands
if (File.Exists("data/wowjokes.json"))