|  |  |  | @@ -14,181 +14,184 @@ using System.Threading.Tasks; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | namespace NadekoBot.Modules.Games | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     public class TypingGame | 
		
	
		
			
				|  |  |  |  |     public partial class Games | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         public const float WORD_VALUE = 4.5f; | 
		
	
		
			
				|  |  |  |  |         private readonly ITextChannel channel; | 
		
	
		
			
				|  |  |  |  |         public string CurrentSentence; | 
		
	
		
			
				|  |  |  |  |         public bool IsActive; | 
		
	
		
			
				|  |  |  |  |         private readonly Stopwatch sw; | 
		
	
		
			
				|  |  |  |  |         private readonly List<ulong> finishedUserIds; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         public TypingGame(ITextChannel channel) | 
		
	
		
			
				|  |  |  |  |         public class TypingGame | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             this.channel = channel; | 
		
	
		
			
				|  |  |  |  |             IsActive = false; | 
		
	
		
			
				|  |  |  |  |             sw = new Stopwatch(); | 
		
	
		
			
				|  |  |  |  |             finishedUserIds = new List<ulong>(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |             public const float WORD_VALUE = 4.5f; | 
		
	
		
			
				|  |  |  |  |             private readonly ITextChannel channel; | 
		
	
		
			
				|  |  |  |  |             public string CurrentSentence; | 
		
	
		
			
				|  |  |  |  |             public bool IsActive; | 
		
	
		
			
				|  |  |  |  |             private readonly Stopwatch sw; | 
		
	
		
			
				|  |  |  |  |             private readonly List<ulong> finishedUserIds; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         public ITextChannel Channel { get; set; } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         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) | 
		
	
		
			
				|  |  |  |  |             public TypingGame(ITextChannel channel) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 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); | 
		
	
		
			
				|  |  |  |  |                 this.channel = channel; | 
		
	
		
			
				|  |  |  |  |                 IsActive = false; | 
		
	
		
			
				|  |  |  |  |                 sw = new Stopwatch(); | 
		
	
		
			
				|  |  |  |  |                 finishedUserIds = new List<ulong>(); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |             public ITextChannel Channel { get; set; } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                 var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                 await Task.Delay(1000).ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                 await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **2**...").ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                 await Task.Delay(1000).ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                 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(); | 
		
	
		
			
				|  |  |  |  |             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; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                 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); | 
		
	
		
			
				|  |  |  |  |                     i--; | 
		
	
		
			
				|  |  |  |  |                     if (!IsActive) | 
		
	
		
			
				|  |  |  |  |                         return; | 
		
	
		
			
				|  |  |  |  |                     await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **2**...").ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                     await Task.Delay(1000).ConfigureAwait(false); | 
		
	
		
			
				|  |  |  |  |                     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() | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             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 () => | 
		
	
		
			
				|  |  |  |  |             private void HandleAnswers() | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 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; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                     var guess = msg.Content; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                     var distance = CurrentSentence.LevenshteinDistance(guess); | 
		
	
		
			
				|  |  |  |  |                     var decision = Judge(distance, guess.Length); | 
		
	
		
			
				|  |  |  |  |                     if (decision && !finishedUserIds.Contains(msg.Author.Id)) | 
		
	
		
			
				|  |  |  |  |                     try | 
		
	
		
			
				|  |  |  |  |                     { | 
		
	
		
			
				|  |  |  |  |                         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) | 
		
	
		
			
				|  |  |  |  |                         if (channel == null || channel.Id != channel.Id || msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                         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); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |                 catch { } | 
		
	
		
			
				|  |  |  |  |             }); | 
		
	
		
			
				|  |  |  |  |             return Task.CompletedTask; | 
		
	
		
			
				|  |  |  |  |                 else | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     await game.Start().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); | 
		
	
		
			
				|  |  |  |  |             //} | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         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); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         [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); | 
		
	
		
			
				|  |  |  |  |         //} | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | } |