games module done too. Searches and music left.

This commit is contained in:
Kwoth 2017-02-23 23:30:38 +01:00
parent d0fa050c30
commit 00629fa45f
12 changed files with 544 additions and 170 deletions

View File

@ -19,9 +19,9 @@ namespace NadekoBot.Modules.Games
[Group] [Group]
public class CleverBotCommands : NadekoSubmodule public class CleverBotCommands : NadekoSubmodule
{ {
private static new Logger _log { get; } private new static Logger _log { get; }
public static ConcurrentDictionary<ulong, Lazy<ChatterBotSession>> CleverbotGuilds { get; } = new ConcurrentDictionary<ulong, Lazy<ChatterBotSession>>(); public static ConcurrentDictionary<ulong, Lazy<ChatterBotSession>> CleverbotGuilds { get; }
static CleverBotCommands() static CleverBotCommands()
{ {
@ -96,7 +96,7 @@ namespace NadekoBot.Modules.Games
uow.GuildConfigs.SetCleverbotEnabled(Context.Guild.Id, false); uow.GuildConfigs.SetCleverbotEnabled(Context.Guild.Id, false);
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await Context.Channel.SendConfirmAsync($"{Context.User.Mention} Disabled cleverbot on this server.").ConfigureAwait(false); await ReplyConfirmLocalized("cleverbot_disabled").ConfigureAwait(false);
return; return;
} }
@ -110,7 +110,7 @@ namespace NadekoBot.Modules.Games
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await Context.Channel.SendConfirmAsync($"{Context.User.Mention} Enabled cleverbot on this server.").ConfigureAwait(false); await ReplyConfirmLocalized("cleverbot_enabled").ConfigureAwait(false);
} }
} }
} }

View File

@ -1,8 +1,6 @@
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Modules.Games.Commands.Hangman;
using NLog;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -21,7 +19,7 @@ namespace NadekoBot.Modules.Games
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Hangmanlist() public async Task Hangmanlist()
{ {
await Context.Channel.SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + String.Join(", ", HangmanTermPool.data.Keys)); await Context.Channel.SendConfirmAsync(Format.Code(GetText("hangman_types", Prefix)) + "\n" + string.Join(", ", HangmanTermPool.data.Keys));
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -35,7 +33,7 @@ namespace NadekoBot.Modules.Games
return; return;
} }
hm.OnEnded += (g) => hm.OnEnded += g =>
{ {
HangmanGame throwaway; HangmanGame throwaway;
HangmanGames.TryRemove(g.GameChannel.Id, out throwaway); HangmanGames.TryRemove(g.GameChannel.Id, out throwaway);

View File

@ -11,10 +11,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
@ -31,7 +28,7 @@ namespace NadekoBot.Modules.Games
[Group] [Group]
public class PlantPickCommands : NadekoSubmodule public class PlantPickCommands : NadekoSubmodule
{ {
private static ConcurrentHashSet<ulong> generationChannels { get; } = new ConcurrentHashSet<ulong>(); private static ConcurrentHashSet<ulong> generationChannels { get; }
//channelid/message //channelid/message
private static ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>(); private static ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>();
//channelId/last generation //channelId/last generation
@ -82,25 +79,17 @@ namespace NadekoBot.Modules.Games
if (dropAmount > 0) if (dropAmount > 0)
{ {
var msgs = new IUserMessage[dropAmount]; var msgs = new IUserMessage[dropAmount];
var prefix = NadekoBot.ModulePrefixes[typeof(Games).Name];
string firstPart; var toSend = dropAmount == 1
if (dropAmount == 1) ? GetLocalText(channel, "curgen_sn", NadekoBot.BotConfig.CurrencySign, prefix)
{ : GetLocalText(channel, "curgen_pl", NadekoBot.BotConfig.CurrencySign, prefix);
firstPart = $"A random { NadekoBot.BotConfig.CurrencyName } appeared!";
}
else
{
firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!";
}
var file = GetRandomCurrencyImage(); var file = GetRandomCurrencyImage();
using (var fileStream = file.Value.ToStream()) using (var fileStream = file.Value.ToStream())
{ {
var sent = await channel.SendFileAsync( var sent = await channel.SendFileAsync(
fileStream, fileStream,
file.Key, file.Key,
string.Format("❗ {0} Pick it up by typing `{1}pick`", firstPart, toSend).ConfigureAwait(false);
NadekoBot.ModulePrefixes[typeof(Games).Name]))
.ConfigureAwait(false);
msgs[0] = sent; msgs[0] = sent;
} }
@ -117,6 +106,12 @@ namespace NadekoBot.Modules.Games
return Task.CompletedTask; return Task.CompletedTask;
} }
public static string GetLocalText(ITextChannel channel, string key, params object[] replacements) =>
NadekoTopLevelModule.GetTextStatic(key,
NadekoBot.Localization.GetCultureInfo(channel.GuildId),
typeof(Games).Name.ToLowerInvariant(),
replacements);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Pick() public async Task Pick()
@ -135,7 +130,8 @@ namespace NadekoBot.Modules.Games
await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false); await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false);
await CurrencyHandler.AddCurrencyAsync((IGuildUser)Context.User, $"Picked {NadekoBot.BotConfig.CurrencyPluralName}", msgs.Count, false).ConfigureAwait(false); await CurrencyHandler.AddCurrencyAsync((IGuildUser)Context.User, $"Picked {NadekoBot.BotConfig.CurrencyPluralName}", msgs.Count, false).ConfigureAwait(false);
var msg = await channel.SendConfirmAsync($"**{Context.User}** picked {msgs.Count}{NadekoBot.BotConfig.CurrencySign}!").ConfigureAwait(false); var msg = await ReplyConfirmLocalized("picked", msgs.Count + NadekoBot.BotConfig.CurrencySign)
.ConfigureAwait(false);
msg.DeleteAfter(10); msg.DeleteAfter(10);
} }
@ -149,14 +145,19 @@ namespace NadekoBot.Modules.Games
var removed = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)Context.User, $"Planted a {NadekoBot.BotConfig.CurrencyName}", amount, false).ConfigureAwait(false); var removed = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)Context.User, $"Planted a {NadekoBot.BotConfig.CurrencyName}", amount, false).ConfigureAwait(false);
if (!removed) if (!removed)
{ {
await Context.Channel.SendErrorAsync($"You don't have enough {NadekoBot.BotConfig.CurrencyPluralName}.").ConfigureAwait(false); await ReplyErrorLocalized("not_enough", NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false);
return; return;
} }
var imgData = GetRandomCurrencyImage(); var imgData = GetRandomCurrencyImage();
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.BotConfig.CurrencyName[0]);
var msgToSend = $"Oh how Nice! **{Context.User.Username}** planted {(amount == 1 ? (vowelFirst ? "an" : "a") : amount.ToString())} {(amount > 1 ? NadekoBot.BotConfig.CurrencyPluralName : NadekoBot.BotConfig.CurrencyName)}. Pick it using {Prefix}pick"; //todo upload all currency images to transfer.sh and use that one as cdn
//and then
var msgToSend = GetText("planted",
Format.Bold(Context.User.ToString()),
amount + NadekoBot.BotConfig.CurrencySign,
Prefix);
IUserMessage msg; IUserMessage msg;
using (var toSend = imgData.Value.ToStream()) using (var toSend = imgData.Value.ToStream())

View File

@ -3,12 +3,10 @@ using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
@ -24,20 +22,20 @@ namespace NadekoBot.Modules.Games
[RequireUserPermission(GuildPermission.ManageMessages)] [RequireUserPermission(GuildPermission.ManageMessages)]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public Task Poll([Remainder] string arg = null) public Task Poll([Remainder] string arg = null)
=> InternalStartPoll(arg, isPublic: false); => InternalStartPoll(arg, false);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireUserPermission(GuildPermission.ManageMessages)] [RequireUserPermission(GuildPermission.ManageMessages)]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public Task PublicPoll([Remainder] string arg = null) public Task PublicPoll([Remainder] string arg = null)
=> InternalStartPoll(arg, isPublic: true); => InternalStartPoll(arg, true);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireUserPermission(GuildPermission.ManageMessages)] [RequireUserPermission(GuildPermission.ManageMessages)]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task PollStats() public async Task PollStats()
{ {
Games.Poll poll; Poll poll;
if (!ActivePolls.TryGetValue(Context.Guild.Id, out poll)) if (!ActivePolls.TryGetValue(Context.Guild.Id, out poll))
return; return;
@ -78,27 +76,25 @@ namespace NadekoBot.Modules.Games
public class Poll public class Poll
{ {
private readonly IUserMessage originalMessage; private readonly IUserMessage _originalMessage;
private readonly IGuild guild; private readonly IGuild _guild;
private string[] Answers { get; } private string[] answers { get; }
private ConcurrentDictionary<ulong, int> participants = new ConcurrentDictionary<ulong, int>(); private readonly ConcurrentDictionary<ulong, int> _participants = new ConcurrentDictionary<ulong, int>();
private readonly string question; private readonly string _question;
private DateTime started;
private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
public bool IsPublic { get; } public bool IsPublic { get; }
public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false) public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false)
{ {
this.originalMessage = umsg; _originalMessage = umsg;
this.guild = ((ITextChannel)umsg.Channel).Guild; _guild = ((ITextChannel)umsg.Channel).Guild;
this.question = question; _question = question;
this.Answers = enumerable as string[] ?? enumerable.ToArray(); answers = enumerable as string[] ?? enumerable.ToArray();
this.IsPublic = isPublic; IsPublic = isPublic;
} }
public EmbedBuilder GetStats(string title) public EmbedBuilder GetStats(string title)
{ {
var results = participants.GroupBy(kvp => kvp.Value) var results = _participants.GroupBy(kvp => kvp.Value)
.ToDictionary(x => x.Key, x => x.Sum(kvp => 1)) .ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
.OrderByDescending(kvp => kvp.Value) .OrderByDescending(kvp => kvp.Value)
.ToArray(); .ToArray();
@ -106,7 +102,7 @@ namespace NadekoBot.Modules.Games
var eb = new EmbedBuilder().WithTitle(title); var eb = new EmbedBuilder().WithTitle(title);
var sb = new StringBuilder() var sb = new StringBuilder()
.AppendLine(Format.Bold(question)) .AppendLine(Format.Bold(_question))
.AppendLine(); .AppendLine();
var totalVotesCast = 0; var totalVotesCast = 0;
@ -119,7 +115,7 @@ namespace NadekoBot.Modules.Games
for (int i = 0; i < results.Length; i++) for (int i = 0; i < results.Length; i++)
{ {
var result = results[i]; var result = results[i];
sb.AppendLine($"`{i + 1}.` {Format.Bold(Answers[result.Key - 1])} with {Format.Bold(result.Value.ToString())} votes."); sb.AppendLine($"`{i + 1}.` {Format.Bold(answers[result.Key - 1])} with {Format.Bold(result.Value.ToString())} votes.");
totalVotesCast += result.Value; totalVotesCast += result.Value;
} }
} }
@ -133,22 +129,21 @@ namespace NadekoBot.Modules.Games
public async Task StartPoll() public async Task StartPoll()
{ {
started = DateTime.Now;
NadekoBot.Client.MessageReceived += Vote; NadekoBot.Client.MessageReceived += Vote;
var msgToSend = $"📃**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; var msgToSend = $"📃**{_originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{_question}**\n";
var num = 1; var num = 1;
msgToSend = Answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
if (!IsPublic) if (!IsPublic)
msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
else else
msgToSend += "\n**Send a Message here with the corresponding number of the answer.**"; msgToSend += "\n**Send a Message here with the corresponding number of the answer.**";
await originalMessage.Channel.SendConfirmAsync(msgToSend).ConfigureAwait(false); await _originalMessage.Channel.SendConfirmAsync(msgToSend).ConfigureAwait(false);
} }
public async Task StopPoll() public async Task StopPoll()
{ {
NadekoBot.Client.MessageReceived -= Vote; NadekoBot.Client.MessageReceived -= Vote;
await originalMessage.Channel.EmbedAsync(GetStats("POLL CLOSED")).ConfigureAwait(false); await _originalMessage.Channel.EmbedAsync(GetStats("POLL CLOSED")).ConfigureAwait(false);
} }
private async Task Vote(SocketMessage imsg) private async Task Vote(SocketMessage imsg)
@ -164,14 +159,14 @@ namespace NadekoBot.Modules.Games
int vote; int vote;
if (!int.TryParse(imsg.Content, out vote)) if (!int.TryParse(imsg.Content, out vote))
return; return;
if (vote < 1 || vote > Answers.Length) if (vote < 1 || vote > answers.Length)
return; return;
IMessageChannel ch; IMessageChannel ch;
if (IsPublic) if (IsPublic)
{ {
//if public, channel must be the same the poll started in //if public, channel must be the same the poll started in
if (originalMessage.Channel.Id != imsg.Channel.Id) if (_originalMessage.Channel.Id != imsg.Channel.Id)
return; return;
ch = imsg.Channel; ch = imsg.Channel;
} }
@ -182,13 +177,13 @@ namespace NadekoBot.Modules.Games
return; return;
// user must be a member of the guild this poll is in // user must be a member of the guild this poll is in
var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); var guildUsers = await _guild.GetUsersAsync().ConfigureAwait(false);
if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) if (guildUsers.All(u => u.Id != imsg.Author.Id))
return; return;
} }
//user can vote only once //user can vote only once
if (participants.TryAdd(msg.Author.Id, vote)) if (_participants.TryAdd(msg.Author.Id, vote))
{ {
if (!IsPublic) if (!IsPublic)
{ {

View File

@ -13,14 +13,13 @@ namespace NadekoBot.Modules.Games
{ {
public partial class Games public partial class Games
{ {
//todo timeout
[Group] [Group]
public class TicTacToeCommands : NadekoSubmodule public class TicTacToeCommands : NadekoSubmodule
{ {
//channelId/game //channelId/game
private static readonly Dictionary<ulong, TicTacToe> _games = new Dictionary<ulong, TicTacToe>(); private static readonly Dictionary<ulong, TicTacToe> _games = new Dictionary<ulong, TicTacToe>();
private readonly SemaphoreSlim sem = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _sem = new SemaphoreSlim(1, 1);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
@ -28,7 +27,7 @@ namespace NadekoBot.Modules.Games
{ {
var channel = (ITextChannel)Context.Channel; var channel = (ITextChannel)Context.Channel;
await sem.WaitAsync(1000); await _sem.WaitAsync(1000);
try try
{ {
TicTacToe game; TicTacToe game;
@ -42,7 +41,7 @@ namespace NadekoBot.Modules.Games
} }
game = new TicTacToe(channel, (IGuildUser)Context.User); game = new TicTacToe(channel, (IGuildUser)Context.User);
_games.Add(channel.Id, game); _games.Add(channel.Id, game);
await Context.Channel.SendConfirmAsync($"{Context.User.Mention} Created a TicTacToe game.").ConfigureAwait(false); await ReplyConfirmLocalized("ttt_created").ConfigureAwait(false);
game.OnEnded += (g) => game.OnEnded += (g) =>
{ {
@ -51,7 +50,7 @@ namespace NadekoBot.Modules.Games
} }
finally finally
{ {
sem.Release(); _sem.Release();
} }
} }
} }
@ -70,42 +69,47 @@ namespace NadekoBot.Modules.Games
private readonly IGuildUser[] _users; private readonly IGuildUser[] _users;
private readonly int?[,] _state; private readonly int?[,] _state;
private Phase _phase; private Phase _phase;
int curUserIndex = 0; private int _curUserIndex;
private readonly SemaphoreSlim moveLock; private readonly SemaphoreSlim _moveLock;
private IGuildUser _winner = null; private IGuildUser _winner;
private readonly string[] numbers = { ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:" }; private readonly string[] _numbers = { ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:" };
public Action<TicTacToe> OnEnded; public Action<TicTacToe> OnEnded;
private IUserMessage previousMessage = null; private IUserMessage _previousMessage;
private Timer timeoutTimer; private Timer _timeoutTimer;
public TicTacToe(ITextChannel channel, IGuildUser firstUser) public TicTacToe(ITextChannel channel, IGuildUser firstUser)
{ {
_channel = channel; _channel = channel;
_users = new IGuildUser[2] { firstUser, null }; _users = new[] { firstUser, null };
_state = new int?[3, 3] { _state = new int?[,] {
{ null, null, null }, { null, null, null },
{ null, null, null }, { null, null, null },
{ null, null, null }, { null, null, null },
}; };
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_log.Warn($"User {firstUser} created a TicTacToe game.");
_phase = Phase.Starting; _phase = Phase.Starting;
moveLock = new SemaphoreSlim(1, 1); _moveLock = new SemaphoreSlim(1, 1);
} }
private string GetText(string key, params object[] replacements) =>
NadekoTopLevelModule.GetTextStatic(key,
NadekoBot.Localization.GetCultureInfo(_channel.GuildId),
typeof(Games).Name.ToLowerInvariant(),
replacements);
public string GetState() public string GetState()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
for (int i = 0; i < _state.GetLength(0); i++) for (var i = 0; i < _state.GetLength(0); i++)
{ {
for (int j = 0; j < _state.GetLength(1); j++) for (var j = 0; j < _state.GetLength(1); j++)
{ {
sb.Append(_state[i, j] == null ? numbers[i * 3 + j] : GetIcon(_state[i, j])); sb.Append(_state[i, j] == null ? _numbers[i * 3 + j] : GetIcon(_state[i, j]));
if (j < _state.GetLength(1) - 1) if (j < _state.GetLength(1) - 1)
sb.Append("┃"); sb.Append("┃");
} }
@ -121,7 +125,7 @@ namespace NadekoBot.Modules.Games
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithDescription(Environment.NewLine + GetState()) .WithDescription(Environment.NewLine + GetState())
.WithAuthor(eab => eab.WithName($"{_users[0]} vs {_users[1]}")); .WithAuthor(eab => eab.WithName(GetText("vs", _users[0], _users[1])));
if (!string.IsNullOrWhiteSpace(title)) if (!string.IsNullOrWhiteSpace(title))
embed.WithTitle(title); embed.WithTitle(title);
@ -129,12 +133,12 @@ namespace NadekoBot.Modules.Games
if (_winner == null) if (_winner == null)
{ {
if (_phase == Phase.Ended) if (_phase == Phase.Ended)
embed.WithFooter(efb => efb.WithText($"No moves left!")); embed.WithFooter(efb => efb.WithText(GetText("ttt_no_moves")));
else else
embed.WithFooter(efb => efb.WithText($"{_users[curUserIndex]}'s move")); embed.WithFooter(efb => efb.WithText(GetText("users_move", _users[_curUserIndex])));
} }
else else
embed.WithFooter(efb => efb.WithText($"{_winner} Won!")); embed.WithFooter(efb => efb.WithText(GetText("ttt_has_won", _winner)));
return embed; return embed;
} }
@ -160,23 +164,22 @@ namespace NadekoBot.Modules.Games
{ {
if (_phase == Phase.Started || _phase == Phase.Ended) if (_phase == Phase.Started || _phase == Phase.Ended)
{ {
await _channel.SendErrorAsync(user.Mention + " TicTacToe Game is already running in this channel.").ConfigureAwait(false); await _channel.SendErrorAsync(user.Mention + GetText("ttt_already_running")).ConfigureAwait(false);
return; return;
} }
else if (_users[0] == user) else if (_users[0] == user)
{ {
await _channel.SendErrorAsync(user.Mention + " You can't play against yourself.").ConfigureAwait(false); await _channel.SendErrorAsync(user.Mention + GetText("ttt_against_yourself")).ConfigureAwait(false);
return; return;
} }
_users[1] = user; _users[1] = user;
_log.Warn($"User {user} joined a TicTacToe game.");
_phase = Phase.Started; _phase = Phase.Started;
timeoutTimer = new Timer(async (_) => _timeoutTimer = new Timer(async (_) =>
{ {
await moveLock.WaitAsync(); await _moveLock.WaitAsync();
try try
{ {
if (_phase == Phase.Ended) if (_phase == Phase.Ended)
@ -185,12 +188,13 @@ namespace NadekoBot.Modules.Games
_phase = Phase.Ended; _phase = Phase.Ended;
if (_users[1] != null) if (_users[1] != null)
{ {
_winner = _users[curUserIndex ^= 1]; _winner = _users[_curUserIndex ^= 1];
var del = previousMessage?.DeleteAsync(); var del = _previousMessage?.DeleteAsync();
try try
{ {
await _channel.EmbedAsync(GetEmbed("Time Expired!")).ConfigureAwait(false); await _channel.EmbedAsync(GetEmbed(GetText("ttt_time_expired"))).ConfigureAwait(false);
await del.ConfigureAwait(false); if (del != null)
await del.ConfigureAwait(false);
} }
catch { } catch { }
} }
@ -200,21 +204,21 @@ namespace NadekoBot.Modules.Games
catch { } catch { }
finally finally
{ {
moveLock.Release(); _moveLock.Release();
} }
}, null, 15000, Timeout.Infinite); }, null, 15000, Timeout.Infinite);
NadekoBot.Client.MessageReceived += Client_MessageReceived; NadekoBot.Client.MessageReceived += Client_MessageReceived;
previousMessage = await _channel.EmbedAsync(GetEmbed("Game Started")).ConfigureAwait(false); _previousMessage = await _channel.EmbedAsync(GetEmbed(GetText("game_started"))).ConfigureAwait(false);
} }
private bool IsDraw() private bool IsDraw()
{ {
for (int i = 0; i < 3; i++) for (var i = 0; i < 3; i++)
{ {
for (int j = 0; j < 3; j++) for (var j = 0; j < 3; j++)
{ {
if (_state[i, j] == null) if (_state[i, j] == null)
return false; return false;
@ -227,10 +231,10 @@ namespace NadekoBot.Modules.Games
{ {
var _ = Task.Run(async () => var _ = Task.Run(async () =>
{ {
await moveLock.WaitAsync().ConfigureAwait(false); await _moveLock.WaitAsync().ConfigureAwait(false);
try try
{ {
var curUser = _users[curUserIndex]; var curUser = _users[_curUserIndex];
if (_phase == Phase.Ended || msg.Author?.Id != curUser.Id) if (_phase == Phase.Ended || msg.Author?.Id != curUser.Id)
return; return;
@ -240,53 +244,53 @@ namespace NadekoBot.Modules.Games
index <= 9 && index <= 9 &&
_state[index / 3, index % 3] == null) _state[index / 3, index % 3] == null)
{ {
_state[index / 3, index % 3] = curUserIndex; _state[index / 3, index % 3] = _curUserIndex;
// i'm lazy // i'm lazy
if (_state[index / 3, 0] == _state[index / 3, 1] && _state[index / 3, 1] == _state[index / 3, 2]) if (_state[index / 3, 0] == _state[index / 3, 1] && _state[index / 3, 1] == _state[index / 3, 2])
{ {
_state[index / 3, 0] = curUserIndex + 2; _state[index / 3, 0] = _curUserIndex + 2;
_state[index / 3, 1] = curUserIndex + 2; _state[index / 3, 1] = _curUserIndex + 2;
_state[index / 3, 2] = curUserIndex + 2; _state[index / 3, 2] = _curUserIndex + 2;
_phase = Phase.Ended; _phase = Phase.Ended;
} }
else if (_state[0, index % 3] == _state[1, index % 3] && _state[1, index % 3] == _state[2, index % 3]) else if (_state[0, index % 3] == _state[1, index % 3] && _state[1, index % 3] == _state[2, index % 3])
{ {
_state[0, index % 3] = curUserIndex + 2; _state[0, index % 3] = _curUserIndex + 2;
_state[1, index % 3] = curUserIndex + 2; _state[1, index % 3] = _curUserIndex + 2;
_state[2, index % 3] = curUserIndex + 2; _state[2, index % 3] = _curUserIndex + 2;
_phase = Phase.Ended; _phase = Phase.Ended;
} }
else if (curUserIndex == _state[0, 0] && _state[0, 0] == _state[1, 1] && _state[1, 1] == _state[2, 2]) else if (_curUserIndex == _state[0, 0] && _state[0, 0] == _state[1, 1] && _state[1, 1] == _state[2, 2])
{ {
_state[0, 0] = curUserIndex + 2; _state[0, 0] = _curUserIndex + 2;
_state[1, 1] = curUserIndex + 2; _state[1, 1] = _curUserIndex + 2;
_state[2, 2] = curUserIndex + 2; _state[2, 2] = _curUserIndex + 2;
_phase = Phase.Ended; _phase = Phase.Ended;
} }
else if (curUserIndex == _state[0, 2] && _state[0, 2] == _state[1, 1] && _state[1, 1] == _state[2, 0]) else if (_curUserIndex == _state[0, 2] && _state[0, 2] == _state[1, 1] && _state[1, 1] == _state[2, 0])
{ {
_state[0, 2] = curUserIndex + 2; _state[0, 2] = _curUserIndex + 2;
_state[1, 1] = curUserIndex + 2; _state[1, 1] = _curUserIndex + 2;
_state[2, 0] = curUserIndex + 2; _state[2, 0] = _curUserIndex + 2;
_phase = Phase.Ended; _phase = Phase.Ended;
} }
string reason = ""; var reason = "";
if (_phase == Phase.Ended) // if user won, stop receiving moves if (_phase == Phase.Ended) // if user won, stop receiving moves
{ {
reason = "Matched three!"; reason = GetText("ttt_matched_three");
_winner = _users[curUserIndex]; _winner = _users[_curUserIndex];
NadekoBot.Client.MessageReceived -= Client_MessageReceived; NadekoBot.Client.MessageReceived -= Client_MessageReceived;
OnEnded?.Invoke(this); OnEnded?.Invoke(this);
} }
else if (IsDraw()) else if (IsDraw())
{ {
reason = "A draw!"; reason = GetText("ttt_a_draw");
_phase = Phase.Ended; _phase = Phase.Ended;
NadekoBot.Client.MessageReceived -= Client_MessageReceived; NadekoBot.Client.MessageReceived -= Client_MessageReceived;
OnEnded?.Invoke(this); OnEnded?.Invoke(this);
@ -295,19 +299,19 @@ namespace NadekoBot.Modules.Games
var sendstate = Task.Run(async () => var sendstate = Task.Run(async () =>
{ {
var del1 = msg.DeleteAsync(); var del1 = msg.DeleteAsync();
var del2 = previousMessage?.DeleteAsync(); var del2 = _previousMessage?.DeleteAsync();
try { previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); } catch { } try { _previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); } catch { }
try { await del1; } catch { } try { await del1; } catch { }
try { if (del2 != null) await del2; } catch { } try { if (del2 != null) await del2; } catch { }
}); });
curUserIndex ^= 1; _curUserIndex ^= 1;
timeoutTimer.Change(15000, Timeout.Infinite); _timeoutTimer.Change(15000, Timeout.Infinite);
} }
} }
finally finally
{ {
moveLock.Release(); _moveLock.Release();
} }
}); });

View File

@ -17,36 +17,42 @@ namespace NadekoBot.Modules.Games.Trivia
public class TriviaGame public class TriviaGame
{ {
private readonly SemaphoreSlim _guessLock = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _guessLock = new SemaphoreSlim(1, 1);
private Logger _log { get; } private readonly Logger _log;
public IGuild guild { get; } public IGuild Guild { get; }
public ITextChannel channel { get; } public ITextChannel Channel { get; }
private int QuestionDurationMiliseconds { get; } = 30000; private int questionDurationMiliseconds { get; } = 30000;
private int HintTimeoutMiliseconds { get; } = 6000; private int hintTimeoutMiliseconds { get; } = 6000;
public bool ShowHints { get; } = true; public bool ShowHints { get; }
private CancellationTokenSource triviaCancelSource { get; set; } private CancellationTokenSource triviaCancelSource { get; set; }
public TriviaQuestion CurrentQuestion { get; private set; } public TriviaQuestion CurrentQuestion { get; private set; }
public HashSet<TriviaQuestion> oldQuestions { get; } = new HashSet<TriviaQuestion>(); public HashSet<TriviaQuestion> OldQuestions { get; } = new HashSet<TriviaQuestion>();
public ConcurrentDictionary<IGuildUser, int> Users { get; } = new ConcurrentDictionary<IGuildUser, int>(); public ConcurrentDictionary<IGuildUser, int> Users { get; } = new ConcurrentDictionary<IGuildUser, int>();
public bool GameActive { get; private set; } = false; public bool GameActive { get; private set; }
public bool ShouldStopGame { get; private set; } public bool ShouldStopGame { get; private set; }
public int WinRequirement { get; } = 10; public int WinRequirement { get; }
public TriviaGame(IGuild guild, ITextChannel channel, bool showHints, int winReq) public TriviaGame(IGuild guild, ITextChannel channel, bool showHints, int winReq)
{ {
this._log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
this.ShowHints = showHints; ShowHints = showHints;
this.guild = guild; Guild = guild;
this.channel = channel; Channel = channel;
this.WinRequirement = winReq; WinRequirement = winReq;
} }
private string GetText(string key, params object[] replacements) =>
NadekoTopLevelModule.GetTextStatic(key,
NadekoBot.Localization.GetCultureInfo(Channel.GuildId),
typeof(Games).Name.ToLowerInvariant(),
replacements);
public async Task StartGame() public async Task StartGame()
{ {
while (!ShouldStopGame) while (!ShouldStopGame)
@ -55,26 +61,24 @@ namespace NadekoBot.Modules.Games.Trivia
triviaCancelSource = new CancellationTokenSource(); triviaCancelSource = new CancellationTokenSource();
// load question // load question
CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(oldQuestions); CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(OldQuestions);
if (CurrentQuestion == null || if (string.IsNullOrWhiteSpace(CurrentQuestion?.Answer) || string.IsNullOrWhiteSpace(CurrentQuestion.Question))
string.IsNullOrWhiteSpace(CurrentQuestion.Answer) ||
string.IsNullOrWhiteSpace(CurrentQuestion.Question))
{ {
await channel.SendErrorAsync("Trivia Game", "Failed loading a question.").ConfigureAwait(false); await Channel.SendErrorAsync(GetText("trivia_game"), GetText("failed_loading_question")).ConfigureAwait(false);
return; return;
} }
oldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again OldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again
EmbedBuilder questionEmbed; EmbedBuilder questionEmbed;
IUserMessage questionMessage; IUserMessage questionMessage;
try try
{ {
questionEmbed = new EmbedBuilder().WithOkColor() questionEmbed = new EmbedBuilder().WithOkColor()
.WithTitle("Trivia Game") .WithTitle(GetText("trivia_game"))
.AddField(eab => eab.WithName("Category").WithValue(CurrentQuestion.Category)) .AddField(eab => eab.WithName(GetText("category")).WithValue(CurrentQuestion.Category))
.AddField(eab => eab.WithName("Question").WithValue(CurrentQuestion.Question)); .AddField(eab => eab.WithName(GetText("question")).WithValue(CurrentQuestion.Question));
questionMessage = await channel.EmbedAsync(questionEmbed).ConfigureAwait(false); questionMessage = await Channel.EmbedAsync(questionEmbed).ConfigureAwait(false);
} }
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound || catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound ||
ex.HttpCode == System.Net.HttpStatusCode.Forbidden || ex.HttpCode == System.Net.HttpStatusCode.Forbidden ||
@ -99,7 +103,7 @@ namespace NadekoBot.Modules.Games.Trivia
try try
{ {
//hint //hint
await Task.Delay(HintTimeoutMiliseconds, triviaCancelSource.Token).ConfigureAwait(false); await Task.Delay(hintTimeoutMiliseconds, triviaCancelSource.Token).ConfigureAwait(false);
if (ShowHints) if (ShowHints)
try try
{ {
@ -113,7 +117,7 @@ namespace NadekoBot.Modules.Games.Trivia
catch (Exception ex) { _log.Warn(ex); } catch (Exception ex) { _log.Warn(ex); }
//timeout //timeout
await Task.Delay(QuestionDurationMiliseconds - HintTimeoutMiliseconds, triviaCancelSource.Token).ConfigureAwait(false); await Task.Delay(questionDurationMiliseconds - hintTimeoutMiliseconds, triviaCancelSource.Token).ConfigureAwait(false);
} }
catch (TaskCanceledException) { } //means someone guessed the answer catch (TaskCanceledException) { } //means someone guessed the answer
@ -124,7 +128,7 @@ namespace NadekoBot.Modules.Games.Trivia
NadekoBot.Client.MessageReceived -= PotentialGuess; NadekoBot.Client.MessageReceived -= PotentialGuess;
} }
if (!triviaCancelSource.IsCancellationRequested) if (!triviaCancelSource.IsCancellationRequested)
try { await channel.SendErrorAsync("Trivia Game", $"**Time's up!** The correct answer was **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } try { await Channel.SendErrorAsync(GetText("trivia_game"), GetText("trivia_times_up", Format.Bold(CurrentQuestion.Answer))).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
await Task.Delay(2000).ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false);
} }
} }
@ -133,7 +137,7 @@ namespace NadekoBot.Modules.Games.Trivia
{ {
ShouldStopGame = true; ShouldStopGame = true;
await channel.EmbedAsync(new EmbedBuilder().WithOkColor() await Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithAuthor(eab => eab.WithName("Trivia Game Ended")) .WithAuthor(eab => eab.WithName("Trivia Game Ended"))
.WithTitle("Final Results") .WithTitle("Final Results")
.WithDescription(GetLeaderboard())).ConfigureAwait(false); .WithDescription(GetLeaderboard())).ConfigureAwait(false);
@ -144,7 +148,7 @@ namespace NadekoBot.Modules.Games.Trivia
var old = ShouldStopGame; var old = ShouldStopGame;
ShouldStopGame = true; ShouldStopGame = true;
if (!old) if (!old)
try { await channel.SendConfirmAsync("Trivia Game", "Stopping after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } try { await Channel.SendConfirmAsync(GetText("trivia_game"), GetText("trivia_stopping")).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
} }
private async Task PotentialGuess(SocketMessage imsg) private async Task PotentialGuess(SocketMessage imsg)
@ -155,11 +159,9 @@ namespace NadekoBot.Modules.Games.Trivia
return; return;
var umsg = imsg as SocketUserMessage; var umsg = imsg as SocketUserMessage;
if (umsg == null)
return;
var textChannel = umsg.Channel as ITextChannel; var textChannel = umsg?.Channel as ITextChannel;
if (textChannel == null || textChannel.Guild != guild) if (textChannel == null || textChannel.Guild != Guild)
return; return;
var guildUser = (IGuildUser)umsg.Author; var guildUser = (IGuildUser)umsg.Author;
@ -182,13 +184,24 @@ namespace NadekoBot.Modules.Games.Trivia
if (Users[guildUser] == WinRequirement) if (Users[guildUser] == WinRequirement)
{ {
ShouldStopGame = true; ShouldStopGame = true;
try { await channel.SendConfirmAsync("Trivia Game", $"{guildUser.Mention} guessed it and WON the game! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch { } try
{
await Channel.SendConfirmAsync(GetText("trivia_game"),
GetText("trivia_win",
guildUser.Mention,
Format.Bold(CurrentQuestion.Answer))).ConfigureAwait(false);
}
catch
{
// ignored
}
var reward = NadekoBot.BotConfig.TriviaCurrencyReward; var reward = NadekoBot.BotConfig.TriviaCurrencyReward;
if (reward > 0) if (reward > 0)
await CurrencyHandler.AddCurrencyAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false); await CurrencyHandler.AddCurrencyAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false);
return; return;
} }
await channel.SendConfirmAsync("Trivia Game", $"{guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); await Channel.SendConfirmAsync(GetText("trivia_game"),
GetText("guess", guildUser.Mention, Format.Bold(CurrentQuestion.Answer))).ConfigureAwait(false);
} }
catch (Exception ex) { _log.Warn(ex); } catch (Exception ex) { _log.Warn(ex); }
@ -197,13 +210,13 @@ namespace NadekoBot.Modules.Games.Trivia
public string GetLeaderboard() public string GetLeaderboard()
{ {
if (Users.Count == 0) if (Users.Count == 0)
return "No results."; return GetText("no_results");
var sb = new StringBuilder(); var sb = new StringBuilder();
foreach (var kvp in Users.OrderByDescending(kvp => kvp.Value)) foreach (var kvp in Users.OrderByDescending(kvp => kvp.Value))
{ {
sb.AppendLine($"**{kvp.Key.Username}** has {kvp.Value} points".ToString().SnPl(kvp.Value)); sb.AppendLine(GetText("trivia_points", Format.Bold(kvp.Key.ToString()), kvp.Value).SnPl(kvp.Value));
} }
return sb.ToString(); return sb.ToString();

View File

@ -3,9 +3,7 @@ using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Modules.Games.Trivia; using NadekoBot.Modules.Games.Trivia;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -31,7 +29,7 @@ namespace NadekoBot.Modules.Games
var showHints = !additionalArgs.Contains("nohint"); var showHints = !additionalArgs.Contains("nohint");
TriviaGame trivia = new TriviaGame(channel.Guild, channel, showHints, winReq); var trivia = new TriviaGame(channel.Guild, channel, showHints, winReq);
if (RunningTrivias.TryAdd(channel.Guild.Id, trivia)) if (RunningTrivias.TryAdd(channel.Guild.Id, trivia))
{ {
try try
@ -45,8 +43,9 @@ namespace NadekoBot.Modules.Games
} }
return; return;
} }
else
await Context.Channel.SendErrorAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false); await Context.Channel.SendErrorAsync(GetText("trivia_already_running") + "\n" + trivia.CurrentQuestion)
.ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -58,11 +57,11 @@ namespace NadekoBot.Modules.Games
TriviaGame trivia; TriviaGame trivia;
if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia))
{ {
await channel.SendConfirmAsync("Leaderboard", trivia.GetLeaderboard()).ConfigureAwait(false); await channel.SendConfirmAsync(GetText("leaderboard"), trivia.GetLeaderboard()).ConfigureAwait(false);
return; return;
} }
await channel.SendErrorAsync("No trivia is running on this server.").ConfigureAwait(false); await ReplyErrorLocalized("trivia_none").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -78,7 +77,7 @@ namespace NadekoBot.Modules.Games
return; return;
} }
await channel.SendErrorAsync("No trivia is running on this server.").ConfigureAwait(false); await ReplyErrorLocalized("trivia_none").ConfigureAwait(false);
} }
} }
} }

View File

@ -23,9 +23,9 @@ namespace NadekoBot.Modules.Permissions
[Group] [Group]
public class BlacklistCommands : ModuleBase public class BlacklistCommands : ModuleBase
{ {
public static ConcurrentHashSet<ulong> BlacklistedUsers { get; set; } = new ConcurrentHashSet<ulong>(); public static ConcurrentHashSet<ulong> BlacklistedUsers { get; set; }
public static ConcurrentHashSet<ulong> BlacklistedGuilds { get; set; } = new ConcurrentHashSet<ulong>(); public static ConcurrentHashSet<ulong> BlacklistedGuilds { get; set; }
public static ConcurrentHashSet<ulong> BlacklistedChannels { get; set; } = new ConcurrentHashSet<ulong>(); public static ConcurrentHashSet<ulong> BlacklistedChannels { get; set; }
static BlacklistCommands() static BlacklistCommands()
{ {
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Permissions
} }
break; break;
case BlacklistType.Channel: case BlacklistType.Channel:
var item = Games.Games.TriviaCommands.RunningTrivias.FirstOrDefault(kvp => kvp.Value.channel.Id == id); var item = Games.Games.TriviaCommands.RunningTrivias.FirstOrDefault(kvp => kvp.Value.Channel.Id == id);
Games.Games.TriviaCommands.RunningTrivias.TryRemove(item.Key, out tg); Games.Games.TriviaCommands.RunningTrivias.TryRemove(item.Key, out tg);
if (tg != null) if (tg != null)
{ {

View File

@ -145,7 +145,7 @@ namespace NadekoBot.Modules.Utility
uow.Quotes.Remove(q); uow.Quotes.Remove(q);
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
sucess = true; sucess = true;
response = GetText("deleted_quote"); response = GetText("quote_deleted");
} }
} }
if(sucess) if(sucess)

View File

@ -2,4 +2,5 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cadministration_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cadministration_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgambling_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgambling_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgames_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgames_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cpermissions_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cutility_005Ccommands/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cutility_005Ccommands/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -2860,6 +2860,33 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Category.
/// </summary>
public static string games_category {
get {
return ResourceManager.GetString("games_category", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disabled cleverbot on this server..
/// </summary>
public static string games_cleverbot_disabled {
get {
return ResourceManager.GetString("games_cleverbot_disabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enabled cleverbot on this server..
/// </summary>
public static string games_cleverbot_enabled {
get {
return ResourceManager.GetString("games_cleverbot_enabled", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Currency generation has been disabled on this channel.. /// Looks up a localized string similar to Currency generation has been disabled on this channel..
/// </summary> /// </summary>
@ -2878,6 +2905,42 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to {0} random {1} appeared! Pick them up by typing `{2}pick`.
/// </summary>
public static string games_curgen_pl {
get {
return ResourceManager.GetString("games_curgen_pl", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A random {0} appeared! Pick it up by typing `{1}pick`.
/// </summary>
public static string games_curgen_sn {
get {
return ResourceManager.GetString("games_curgen_sn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed loading a question..
/// </summary>
public static string games_failed_loading_question {
get {
return ResourceManager.GetString("games_failed_loading_question", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Game Started.
/// </summary>
public static string games_game_started {
get {
return ResourceManager.GetString("games_game_started", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Hangman game started. /// Looks up a localized string similar to Hangman game started.
/// </summary> /// </summary>
@ -2914,6 +2977,51 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Leaderboard.
/// </summary>
public static string games_leaderboard {
get {
return ResourceManager.GetString("games_leaderboard", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No results.
/// </summary>
public static string games_no_results {
get {
return ResourceManager.GetString("games_no_results", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You don&apos;t have enough {0}.
/// </summary>
public static string games_not_enough {
get {
return ResourceManager.GetString("games_not_enough", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to picked {0}.
/// </summary>
public static string games_picked {
get {
return ResourceManager.GetString("games_picked", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} planted {1}.
/// </summary>
public static string games_planted {
get {
return ResourceManager.GetString("games_planted", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Question. /// Looks up a localized string similar to Question.
/// </summary> /// </summary>
@ -2950,6 +3058,168 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Trivia game is already running on this server..
/// </summary>
public static string games_trivia_already_running {
get {
return ResourceManager.GetString("games_trivia_already_running", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trivia Game.
/// </summary>
public static string games_trivia_game {
get {
return ResourceManager.GetString("games_trivia_game", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} guessed it! The answer was: {1}.
/// </summary>
public static string games_trivia_guess {
get {
return ResourceManager.GetString("games_trivia_guess", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No trivia is running on this server..
/// </summary>
public static string games_trivia_none {
get {
return ResourceManager.GetString("games_trivia_none", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} has {1} points.
/// </summary>
public static string games_trivia_points {
get {
return ResourceManager.GetString("games_trivia_points", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stopping after this question..
/// </summary>
public static string games_trivia_stopping {
get {
return ResourceManager.GetString("games_trivia_stopping", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Time&apos;s up! The correct answer was {0}.
/// </summary>
public static string games_trivia_times_up {
get {
return ResourceManager.GetString("games_trivia_times_up", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} guessed it and WON the game! The answer was: {1}.
/// </summary>
public static string games_trivia_win {
get {
return ResourceManager.GetString("games_trivia_win", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A draw!.
/// </summary>
public static string games_ttt_a_draw {
get {
return ResourceManager.GetString("games_ttt_a_draw", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You can&apos;t play against yourself..
/// </summary>
public static string games_ttt_against_yourself {
get {
return ResourceManager.GetString("games_ttt_against_yourself", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TicTacToe Game is already running in this channel..
/// </summary>
public static string games_ttt_already_running {
get {
return ResourceManager.GetString("games_ttt_already_running", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to has created a game of TicTacToe..
/// </summary>
public static string games_ttt_created {
get {
return ResourceManager.GetString("games_ttt_created", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} has Won!.
/// </summary>
public static string games_ttt_has_won {
get {
return ResourceManager.GetString("games_ttt_has_won", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Matched Three.
/// </summary>
public static string games_ttt_matched_three {
get {
return ResourceManager.GetString("games_ttt_matched_three", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No moves left!.
/// </summary>
public static string games_ttt_no_moves {
get {
return ResourceManager.GetString("games_ttt_no_moves", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Time Expired!.
/// </summary>
public static string games_ttt_time_expired {
get {
return ResourceManager.GetString("games_ttt_time_expired", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}&apos;s move.
/// </summary>
public static string games_ttt_users_move {
get {
return ResourceManager.GetString("games_ttt_users_move", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} vs {1}.
/// </summary>
public static string games_vs {
get {
return ResourceManager.GetString("games_vs", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Back to ToC. /// Looks up a localized string similar to Back to ToC.
/// </summary> /// </summary>

View File

@ -1221,12 +1221,34 @@ Don't forget to leave your discord name or id in the message.
<data name="gambling_total_average" xml:space="preserve"> <data name="gambling_total_average" xml:space="preserve">
<value>Total: {0} Average: {1}</value> <value>Total: {0} Average: {1}</value>
</data> </data>
<data name="games_category" xml:space="preserve">
<value>Category</value>
</data>
<data name="games_cleverbot_disabled" xml:space="preserve">
<value>Disabled cleverbot on this server.</value>
</data>
<data name="games_cleverbot_enabled" xml:space="preserve">
<value>Enabled cleverbot on this server.</value>
</data>
<data name="games_curgen_disabled" xml:space="preserve"> <data name="games_curgen_disabled" xml:space="preserve">
<value>Currency generation has been disabled on this channel.</value> <value>Currency generation has been disabled on this channel.</value>
</data> </data>
<data name="games_curgen_enabled" xml:space="preserve"> <data name="games_curgen_enabled" xml:space="preserve">
<value>Currency generation has been enabled on this channel.</value> <value>Currency generation has been enabled on this channel.</value>
</data> </data>
<data name="games_curgen_pl" xml:space="preserve">
<value>{0} random {1} appeared! Pick them up by typing `{2}pick`</value>
<comment>plural</comment>
</data>
<data name="games_curgen_sn" xml:space="preserve">
<value>A random {0} appeared! Pick it up by typing `{1}pick`</value>
</data>
<data name="games_failed_loading_question" xml:space="preserve">
<value>Failed loading a question.</value>
</data>
<data name="games_game_started" xml:space="preserve">
<value>Game Started</value>
</data>
<data name="games_hangman_game_started" xml:space="preserve"> <data name="games_hangman_game_started" xml:space="preserve">
<value>Hangman game started</value> <value>Hangman game started</value>
</data> </data>
@ -1239,6 +1261,77 @@ Don't forget to leave your discord name or id in the message.
<data name="games_hangman_types" xml:space="preserve"> <data name="games_hangman_types" xml:space="preserve">
<value>List of "{0}hangman" term types:</value> <value>List of "{0}hangman" term types:</value>
</data> </data>
<data name="games_leaderboard" xml:space="preserve">
<value>Leaderboard</value>
</data>
<data name="games_not_enough" xml:space="preserve">
<value>You don't have enough {0}</value>
</data>
<data name="games_no_results" xml:space="preserve">
<value>No results</value>
</data>
<data name="games_picked" xml:space="preserve">
<value>picked {0}</value>
<comment>Kwoth picked 5*</comment>
</data>
<data name="games_planted" xml:space="preserve">
<value>{0} planted {1}</value>
<comment>Kwoth planted 5*</comment>
</data>
<data name="games_trivia_already_running" xml:space="preserve">
<value>Trivia game is already running on this server.</value>
</data>
<data name="games_trivia_game" xml:space="preserve">
<value>Trivia Game</value>
</data>
<data name="games_trivia_guess" xml:space="preserve">
<value>{0} guessed it! The answer was: {1}</value>
</data>
<data name="games_trivia_none" xml:space="preserve">
<value>No trivia is running on this server.</value>
</data>
<data name="games_trivia_points" xml:space="preserve">
<value>{0} has {1} points</value>
</data>
<data name="games_trivia_stopping" xml:space="preserve">
<value>Stopping after this question.</value>
</data>
<data name="games_trivia_times_up" xml:space="preserve">
<value>Time's up! The correct answer was {0}</value>
</data>
<data name="games_trivia_win" xml:space="preserve">
<value>{0} guessed it and WON the game! The answer was: {1}</value>
</data>
<data name="games_ttt_against_yourself" xml:space="preserve">
<value>You can't play against yourself.</value>
</data>
<data name="games_ttt_already_running" xml:space="preserve">
<value>TicTacToe Game is already running in this channel.</value>
</data>
<data name="games_ttt_a_draw" xml:space="preserve">
<value>A draw!</value>
</data>
<data name="games_ttt_created" xml:space="preserve">
<value>has created a game of TicTacToe.</value>
</data>
<data name="games_ttt_has_won" xml:space="preserve">
<value>{0} has Won!</value>
</data>
<data name="games_ttt_matched_three" xml:space="preserve">
<value>Matched Three</value>
</data>
<data name="games_ttt_no_moves" xml:space="preserve">
<value>No moves left!</value>
</data>
<data name="games_ttt_time_expired" xml:space="preserve">
<value>Time Expired!</value>
</data>
<data name="games_ttt_users_move" xml:space="preserve">
<value>{0}'s move</value>
</data>
<data name="games_vs" xml:space="preserve">
<value>{0} vs {1}</value>
</data>
<data name="utiliity_joined" xml:space="preserve"> <data name="utiliity_joined" xml:space="preserve">
<value>Joined</value> <value>Joined</value>
</data> </data>