Games commands should properly show up now

This commit is contained in:
Kwoth 2016-09-08 22:46:38 +02:00
parent 0a548523ab
commit 74eac23ed3
5 changed files with 163 additions and 159 deletions

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
// because i don't want to waste my time on this cancerous command // because i don't want to waste my time on this cancerous command
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
public partial class GamesModule public partial class Games
{ {
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias] [LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -26,6 +26,7 @@ namespace NadekoBot.Modules.Games
/// Check out GDL (its a growing gamedev community): /// Check out GDL (its a growing gamedev community):
/// https://discord.gg/0TYNJfCU4De7YIk8 /// https://discord.gg/0TYNJfCU4De7YIk8
/// </summary> /// </summary>
[Group]
public class PlantPick public class PlantPick
{ {

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
public partial class GamesModule public partial class Games
{ {
public static ConcurrentDictionary<IGuild, Poll> ActivePolls = new ConcurrentDictionary<IGuild, Poll>(); public static ConcurrentDictionary<IGuild, Poll> ActivePolls = new ConcurrentDictionary<IGuild, Poll>();

View File

@ -14,181 +14,184 @@ using System.Threading.Tasks;
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
public class TypingGame public partial class Games
{ {
public const float WORD_VALUE = 4.5f; public class TypingGame
private readonly ITextChannel channel;
public string CurrentSentence;
public bool IsActive;
private readonly Stopwatch sw;
private readonly List<ulong> finishedUserIds;
public TypingGame(ITextChannel channel)
{ {
this.channel = channel; public const float WORD_VALUE = 4.5f;
IsActive = false; private readonly ITextChannel channel;
sw = new Stopwatch(); public string CurrentSentence;
finishedUserIds = new List<ulong>(); public bool IsActive;
} private readonly Stopwatch sw;
private readonly List<ulong> finishedUserIds;
public ITextChannel Channel { get; set; } public TypingGame(ITextChannel channel)
public async Task<bool> Stop()
{
if (!IsActive) return false;
NadekoBot.Client.MessageReceived -= AnswerReceived;
finishedUserIds.Clear();
IsActive = false;
sw.Stop();
sw.Reset();
await channel.SendMessageAsync("Typing contest stopped").ConfigureAwait(false);
return true;
}
public async Task Start()
{
while (true)
{ {
if (IsActive) return; // can't start running game this.channel = channel;
IsActive = true; IsActive = false;
CurrentSentence = GetRandomSentence(); sw = new Stopwatch();
var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f); finishedUserIds = new List<ulong>();
await channel.SendMessageAsync($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false); }
public ITextChannel Channel { get; set; }
var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false); public async Task<bool> Stop()
await Task.Delay(1000).ConfigureAwait(false); {
await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **2**...").ConfigureAwait(false); if (!IsActive) return false;
await Task.Delay(1000).ConfigureAwait(false); NadekoBot.Client.MessageReceived -= AnswerReceived;
await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **1**...").ConfigureAwait(false); finishedUserIds.Clear();
await Task.Delay(1000).ConfigureAwait(false); IsActive = false;
await msg.ModifyAsync(m => m.Content = $":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false); sw.Stop();
sw.Start(); sw.Reset();
HandleAnswers(); await channel.SendMessageAsync("Typing contest stopped").ConfigureAwait(false);
return true;
}
while (i > 0) public async Task Start()
{
while (true)
{ {
if (IsActive) return; // can't start running game
IsActive = true;
CurrentSentence = GetRandomSentence();
var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
await channel.SendMessageAsync($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false); await Task.Delay(1000).ConfigureAwait(false);
i--; await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **2**...").ConfigureAwait(false);
if (!IsActive) await Task.Delay(1000).ConfigureAwait(false);
return; await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **1**...").ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false);
await msg.ModifyAsync(m => m.Content = $":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false);
sw.Start();
HandleAnswers();
while (i > 0)
{
await Task.Delay(1000).ConfigureAwait(false);
i--;
if (!IsActive)
return;
}
await Stop().ConfigureAwait(false);
}
}
public string GetRandomSentence()
{
using (var uow = DbHandler.UnitOfWork())
{
return uow.TypingArticles.GetRandom()?.Text ?? "No typing articles found. Use `>typeadd` command to add a new article for typing.";
} }
await Stop().ConfigureAwait(false);
}
}
public string GetRandomSentence()
{
using (var uow = DbHandler.UnitOfWork())
{
return uow.TypingArticles.GetRandom()?.Text ?? "No typing articles found. Use `>typeadd` command to add a new article for typing.";
} }
} private void HandleAnswers()
private void HandleAnswers()
{
NadekoBot.Client.MessageReceived += AnswerReceived;
}
private Task AnswerReceived(IMessage imsg)
{
var msg = imsg as IUserMessage;
if (msg == null)
return Task.CompletedTask;
var t = Task.Run(async () =>
{ {
try NadekoBot.Client.MessageReceived += AnswerReceived;
}
private Task AnswerReceived(IMessage imsg)
{
var msg = imsg as IUserMessage;
if (msg == null)
return Task.CompletedTask;
var t = Task.Run(async () =>
{ {
if (channel == null || channel.Id != channel.Id || msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return; try
var guess = msg.Content;
var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(msg.Author.Id))
{ {
finishedUserIds.Add(msg.Author.Id); if (channel == null || channel.Id != channel.Id || msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return;
await channel.SendMessageAsync($"{msg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
if (finishedUserIds.Count % 2 == 0) var guess = msg.Content;
var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(msg.Author.Id))
{ {
await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false); finishedUserIds.Add(msg.Author.Id);
await channel.SendMessageAsync($"{msg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
if (finishedUserIds.Count % 2 == 0)
{
await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false);
}
} }
} }
catch { }
});
return Task.CompletedTask;
}
private bool Judge(int errors, int textLength) => errors <= textLength / 25;
}
[Group]
public class SpeedTypingCommands
{
public static ConcurrentDictionary<ulong, TypingGame> RunningContests;
public SpeedTypingCommands()
{
RunningContests = new ConcurrentDictionary<ulong, TypingGame>();
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
public async Task TypeStart(IUserMessage msg)
{
var channel = (ITextChannel)msg.Channel;
var game = RunningContests.GetOrAdd(channel.Guild.Id, id => new TypingGame(channel));
if (game.IsActive)
{
await channel.SendMessageAsync(
$"Contest already running in " +
$"{game.Channel.Mention} channel.")
.ConfigureAwait(false);
}
else
{
await game.Start().ConfigureAwait(false);
} }
catch { }
});
return Task.CompletedTask;
}
private bool Judge(int errors, int textLength) => errors <= textLength / 25;
}
[Group]
public class SpeedTypingCommands
{
public static ConcurrentDictionary<ulong, TypingGame> RunningContests;
public SpeedTypingCommands()
{
RunningContests = new ConcurrentDictionary<ulong, TypingGame>();
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
public async Task TypeStart(IUserMessage msg)
{
var channel = (ITextChannel)msg.Channel;
var game = RunningContests.GetOrAdd(channel.Guild.Id, id => new TypingGame(channel));
if (game.IsActive)
{
await channel.SendMessageAsync(
$"Contest already running in " +
$"{game.Channel.Mention} channel.")
.ConfigureAwait(false);
} }
else
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
public async Task TypeStop(IUserMessage imsg)
{ {
await game.Start().ConfigureAwait(false); var channel = (ITextChannel)imsg.Channel;
TypingGame game;
if (RunningContests.TryRemove(channel.Guild.Id, out game))
{
await game.Stop().ConfigureAwait(false);
return;
}
await channel.SendMessageAsync("No contest to stop on this channel.").ConfigureAwait(false);
} }
////todo owner only
//[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
//[RequireContext(ContextType.Guild)]
//public async Task Typeadd(IUserMessage imsg, [Remainder] string text)
//{
// var channel = (ITextChannel)imsg.Channel;
// using (var uow = DbHandler.UnitOfWork())
// {
// uow.TypingArticles.Add(new Services.Database.Models.TypingArticle
// {
// Author = imsg.Author.Username,
// Text = text
// });
// }
// await channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
//}
} }
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
public async Task TypeStop(IUserMessage imsg)
{
var channel = (ITextChannel)imsg.Channel;
TypingGame game;
if (RunningContests.TryRemove(channel.Guild.Id, out game))
{
await game.Stop().ConfigureAwait(false);
return;
}
await channel.SendMessageAsync("No contest to stop on this channel.").ConfigureAwait(false);
}
////todo owner only
//[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
//[RequireContext(ContextType.Guild)]
//public async Task Typeadd(IUserMessage imsg, [Remainder] string text)
//{
// var channel = (ITextChannel)imsg.Channel;
// using (var uow = DbHandler.UnitOfWork())
// {
// uow.TypingArticles.Add(new Services.Database.Models.TypingArticle
// {
// Author = imsg.Author.Username,
// Text = text
// });
// }
// await channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
//}
} }
} }

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
//todo Rewrite? Fix trivia not stopping bug //todo Rewrite? Fix trivia not stopping bug
namespace NadekoBot.Modules.Games namespace NadekoBot.Modules.Games
{ {
public partial class GamesModule public partial class Games
{ {
[Group] [Group]
public class TriviaCommands public class TriviaCommands