Removed module projects because it can't work like that atm. Commented out package commands.
This commit is contained in:
		
							
								
								
									
										145
									
								
								NadekoBot.Core/Modules/Games/Services/ChatterbotService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								NadekoBot.Core/Modules/Games/Services/ChatterbotService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Common.ModuleBehaviors; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules.Permissions.Common; | ||||
| using NadekoBot.Modules.Permissions.Services; | ||||
| using NadekoBot.Core.Services; | ||||
| using NadekoBot.Core.Services.Database.Models; | ||||
| using NadekoBot.Core.Services.Impl; | ||||
| using NLog; | ||||
| using NadekoBot.Modules.Games.Common.ChatterBot; | ||||
|  | ||||
| namespace NadekoBot.Modules.Games.Services | ||||
| { | ||||
|     public class ChatterBotService : IEarlyBlockingExecutor, INService | ||||
|     { | ||||
|         private readonly DiscordSocketClient _client; | ||||
|         private readonly Logger _log; | ||||
|         private readonly PermissionService _perms; | ||||
|         private readonly CommandHandler _cmd; | ||||
|         private readonly NadekoStrings _strings; | ||||
|         private readonly IBotCredentials _creds; | ||||
|  | ||||
|         public ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; } | ||||
|  | ||||
|         public ChatterBotService(DiscordSocketClient client, PermissionService perms,  | ||||
|             NadekoBot bot, CommandHandler cmd, NadekoStrings strings,  | ||||
|             IBotCredentials creds) | ||||
|         { | ||||
|             _client = client; | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|             _perms = perms; | ||||
|             _cmd = cmd; | ||||
|             _strings = strings; | ||||
|             _creds = creds; | ||||
|  | ||||
|             ChatterBotGuilds = new ConcurrentDictionary<ulong, Lazy<IChatterBotSession>>( | ||||
|                     bot.AllGuildConfigs | ||||
|                         .Where(gc => gc.CleverbotEnabled) | ||||
|                         .ToDictionary(gc => gc.GuildId, gc => new Lazy<IChatterBotSession>(() => CreateSession(), true))); | ||||
|         } | ||||
|  | ||||
|         public IChatterBotSession CreateSession() | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(_creds.CleverbotApiKey)) | ||||
|                 return new ChatterBotSession(); | ||||
|             else | ||||
|                 return new OfficialCleverbotSession(_creds.CleverbotApiKey); | ||||
|         } | ||||
|  | ||||
|         public string PrepareMessage(IUserMessage msg, out IChatterBotSession cleverbot) | ||||
|         { | ||||
|             var channel = msg.Channel as ITextChannel; | ||||
|             cleverbot = null; | ||||
|  | ||||
|             if (channel == null) | ||||
|                 return null; | ||||
|  | ||||
|             if (!ChatterBotGuilds.TryGetValue(channel.Guild.Id, out Lazy<IChatterBotSession> lazyCleverbot)) | ||||
|                 return null; | ||||
|  | ||||
|             cleverbot = lazyCleverbot.Value; | ||||
|  | ||||
|             var nadekoId = _client.CurrentUser.Id; | ||||
|             var normalMention = $"<@{nadekoId}> "; | ||||
|             var nickMention = $"<@!{nadekoId}> "; | ||||
|             string message; | ||||
|             if (msg.Content.StartsWith(normalMention)) | ||||
|             { | ||||
|                 message = msg.Content.Substring(normalMention.Length).Trim(); | ||||
|             } | ||||
|             else if (msg.Content.StartsWith(nickMention)) | ||||
|             { | ||||
|                 message = msg.Content.Substring(nickMention.Length).Trim(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             return message; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> TryAsk(IChatterBotSession cleverbot, ITextChannel channel, string message) | ||||
|         { | ||||
|             await channel.TriggerTypingAsync().ConfigureAwait(false); | ||||
|  | ||||
|             var response = await cleverbot.Think(message).ConfigureAwait(false); | ||||
|             try | ||||
|             { | ||||
|                 await channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 await channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); // try twice :\ | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage usrMsg) | ||||
|         { | ||||
|             if (!(guild is SocketGuild sg)) | ||||
|                 return false; | ||||
|             try | ||||
|             { | ||||
|                 var message = PrepareMessage(usrMsg, out IChatterBotSession cbs); | ||||
|                 if (message == null || cbs == null) | ||||
|                     return false; | ||||
|                  | ||||
|                 var pc = _perms.GetCache(guild.Id); | ||||
|                 if (!pc.Permissions.CheckPermissions(usrMsg, | ||||
|                     "cleverbot", | ||||
|                     "Games".ToLowerInvariant(), | ||||
|                     out int index)) | ||||
|                 { | ||||
|                     if (pc.Verbose) | ||||
|                     { | ||||
|                         var returnMsg = _strings.GetText("trigger", guild.Id, "Permissions".ToLowerInvariant(), index + 1, Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild)guild))); | ||||
|                         try { await usrMsg.Channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { } | ||||
|                         _log.Info(returnMsg); | ||||
|                     } | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 var cleverbotExecuted = await TryAsk(cbs, (ITextChannel)usrMsg.Channel, message).ConfigureAwait(false); | ||||
|                 if (cleverbotExecuted) | ||||
|                 { | ||||
|                     _log.Info($@"CleverBot Executed | ||||
| Server: {guild.Name} [{guild.Id}] | ||||
| Channel: {usrMsg.Channel?.Name} [{usrMsg.Channel?.Id}] | ||||
| UserId: {usrMsg.Author} [{usrMsg.Author.Id}] | ||||
| Message: {usrMsg.Content}"); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); } | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										215
									
								
								NadekoBot.Core/Modules/Games/Services/GamesService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								NadekoBot.Core/Modules/Games/Services/GamesService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Common; | ||||
| using NadekoBot.Common.Collections; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules.Games.Common; | ||||
| using NadekoBot.Core.Services; | ||||
| using NadekoBot.Core.Services.Database.Models; | ||||
| using NadekoBot.Core.Services.Impl; | ||||
| using Newtonsoft.Json; | ||||
| using NLog; | ||||
| using NadekoBot.Modules.Games.Common.Acrophobia; | ||||
| using NadekoBot.Modules.Games.Common.Connect4; | ||||
| using NadekoBot.Modules.Games.Common.Hangman; | ||||
| using NadekoBot.Modules.Games.Common.Trivia; | ||||
| using NadekoBot.Modules.Games.Common.Nunchi; | ||||
|  | ||||
| namespace NadekoBot.Modules.Games.Services | ||||
| { | ||||
|     public class GamesService : INService, IUnloadableService | ||||
|     { | ||||
|         private readonly IBotConfigProvider _bc; | ||||
|  | ||||
|         public readonly ConcurrentDictionary<ulong, GirlRating> GirlRatings = new ConcurrentDictionary<ulong, GirlRating>(); | ||||
|         public readonly ImmutableArray<string> EightBallResponses; | ||||
|  | ||||
|         private readonly Timer _t; | ||||
|         private readonly CommandHandler _cmd; | ||||
|         private readonly NadekoStrings _strings; | ||||
|         private readonly IImagesService _images; | ||||
|         private readonly Logger _log; | ||||
|  | ||||
|         public readonly string TypingArticlesPath = "data/typing_articles2.json"; | ||||
|         private readonly CommandHandler _cmdHandler; | ||||
|  | ||||
|         public List<TypingArticle> TypingArticles { get; } = new List<TypingArticle>(); | ||||
|  | ||||
|         //channelId, game | ||||
|         public ConcurrentDictionary<ulong, Acrophobia> AcrophobiaGames { get; } = new ConcurrentDictionary<ulong, Acrophobia>(); | ||||
|         public ConcurrentDictionary<ulong, Connect4Game> Connect4Games { get; } = new ConcurrentDictionary<ulong, Connect4Game>(); | ||||
|  | ||||
|         public ConcurrentDictionary<ulong, Hangman> HangmanGames { get; } = new ConcurrentDictionary<ulong, Hangman>(); | ||||
|         public TermPool TermPool { get; } = new TermPool(); | ||||
|  | ||||
|         public ConcurrentDictionary<ulong, TriviaGame> RunningTrivias { get; } = new ConcurrentDictionary<ulong, TriviaGame>(); | ||||
|         public Dictionary<ulong, TicTacToe> TicTacToeGames { get; } = new Dictionary<ulong, TicTacToe>(); | ||||
|         public ConcurrentDictionary<ulong, TypingGame> RunningContests { get; } = new ConcurrentDictionary<ulong, TypingGame>(); | ||||
|         public ConcurrentDictionary<ulong, Nunchi> NunchiGames { get; } = new ConcurrentDictionary<ulong, Common.Nunchi.Nunchi>(); | ||||
|  | ||||
|         public GamesService(CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot, | ||||
|             NadekoStrings strings, IImagesService images, CommandHandler cmdHandler) | ||||
|         { | ||||
|             _bc = bc; | ||||
|             _cmd = cmd; | ||||
|             _strings = strings; | ||||
|             _images = images; | ||||
|             _cmdHandler = cmdHandler; | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|  | ||||
|             //8ball | ||||
|             EightBallResponses = _bc.BotConfig.EightBallResponses.Select(ebr => ebr.Text).ToImmutableArray(); | ||||
|  | ||||
|             //girl ratings | ||||
|             _t = new Timer((_) => | ||||
|             { | ||||
|                 GirlRatings.Clear(); | ||||
|  | ||||
|             }, null, TimeSpan.FromDays(1), TimeSpan.FromDays(1)); | ||||
|  | ||||
|             //plantpick | ||||
|             _cmd.OnMessageNoTrigger += PotentialFlowerGeneration; | ||||
|             GenerationChannels = new ConcurrentHashSet<ulong>(bot | ||||
|                 .AllGuildConfigs | ||||
|                 .SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId))); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 TypingArticles = JsonConvert.DeserializeObject<List<TypingArticle>>(File.ReadAllText(TypingArticlesPath)); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _log.Warn("Error while loading typing articles {0}", ex.ToString()); | ||||
|                 TypingArticles = new List<TypingArticle>(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task Unload() | ||||
|         { | ||||
|             _t.Change(Timeout.Infinite, Timeout.Infinite); | ||||
|             _cmd.OnMessageNoTrigger -= PotentialFlowerGeneration; | ||||
|  | ||||
|             AcrophobiaGames.ForEach(x => x.Value.Dispose()); | ||||
|             AcrophobiaGames.Clear(); | ||||
|             Connect4Games.ForEach(x => x.Value.Dispose()); | ||||
|             Connect4Games.Clear(); | ||||
|             HangmanGames.ForEach(x => x.Value.Dispose()); | ||||
|             HangmanGames.Clear(); | ||||
|             await Task.WhenAll(RunningTrivias.Select(x => x.Value.StopGame())); | ||||
|             RunningTrivias.Clear(); | ||||
|  | ||||
|             TicTacToeGames.Clear(); | ||||
|  | ||||
|             await Task.WhenAll(RunningContests.Select(x => x.Value.Stop())) | ||||
|                 .ConfigureAwait(false); | ||||
|             RunningContests.Clear(); | ||||
|             NunchiGames.ForEach(x => x.Value.Dispose()); | ||||
|             NunchiGames.Clear(); | ||||
|         } | ||||
|  | ||||
|         private void DisposeElems(IEnumerable<IDisposable> xs) | ||||
|         { | ||||
|             xs.ForEach(x => x.Dispose()); | ||||
|         } | ||||
|  | ||||
|         public void AddTypingArticle(IUser user, string text) | ||||
|         { | ||||
|             TypingArticles.Add(new TypingArticle | ||||
|             { | ||||
|                 Title = $"Text added on {DateTime.UtcNow} by {user}", | ||||
|                 Text = text.SanitizeMentions(), | ||||
|             }); | ||||
|  | ||||
|             File.WriteAllText(TypingArticlesPath, JsonConvert.SerializeObject(TypingArticles)); | ||||
|         } | ||||
|  | ||||
|         public ConcurrentHashSet<ulong> GenerationChannels { get; } | ||||
|         //channelid/message | ||||
|         public ConcurrentDictionary<ulong, List<IUserMessage>> PlantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>(); | ||||
|         //channelId/last generation | ||||
|         public ConcurrentDictionary<ulong, DateTime> LastGenerations { get; } = new ConcurrentDictionary<ulong, DateTime>(); | ||||
|  | ||||
|         private ConcurrentDictionary<ulong, object> _locks { get; } = new ConcurrentDictionary<ulong, object>(); | ||||
|          | ||||
|         public (string Name, ImmutableArray<byte> Data) GetRandomCurrencyImage() | ||||
|         { | ||||
|             var rng = new NadekoRandom(); | ||||
|             return _images.Currency[rng.Next(0, _images.Currency.Length)]; | ||||
|         } | ||||
|  | ||||
|         private string GetText(ITextChannel ch, string key, params object[] rep) | ||||
|             => _strings.GetText(key, ch.GuildId, "Games".ToLowerInvariant(), rep); | ||||
|  | ||||
|         private Task PotentialFlowerGeneration(IUserMessage imsg) | ||||
|         { | ||||
|             var msg = imsg as SocketUserMessage; | ||||
|             if (msg == null || msg.Author.IsBot) | ||||
|                 return Task.CompletedTask; | ||||
|  | ||||
|             var channel = imsg.Channel as ITextChannel; | ||||
|             if (channel == null) | ||||
|                 return Task.CompletedTask; | ||||
|  | ||||
|             if (!GenerationChannels.Contains(channel.Id)) | ||||
|                 return Task.CompletedTask; | ||||
|  | ||||
|             var _ = Task.Run(async () => | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     var lastGeneration = LastGenerations.GetOrAdd(channel.Id, DateTime.MinValue); | ||||
|                     var rng = new NadekoRandom(); | ||||
|  | ||||
|                     if (DateTime.UtcNow - TimeSpan.FromSeconds(_bc.BotConfig.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again | ||||
|                         return; | ||||
|  | ||||
|                     var num = rng.Next(1, 101) + _bc.BotConfig.CurrencyGenerationChance * 100; | ||||
|                     if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.UtcNow, lastGeneration)) | ||||
|                     { | ||||
|                         var dropAmount = _bc.BotConfig.CurrencyDropAmount; | ||||
|                         var dropAmountMax = _bc.BotConfig.CurrencyDropAmountMax; | ||||
|  | ||||
|                         if (dropAmountMax != null && dropAmountMax > dropAmount) | ||||
|                             dropAmount = new NadekoRandom().Next(dropAmount, dropAmountMax.Value + 1); | ||||
|  | ||||
|                         if (dropAmount > 0) | ||||
|                         { | ||||
|                             var msgs = new IUserMessage[dropAmount]; | ||||
|                             var prefix = _cmdHandler.GetPrefix(channel.Guild.Id); | ||||
|                             var toSend = dropAmount == 1 | ||||
|                                 ? GetText(channel, "curgen_sn", _bc.BotConfig.CurrencySign) | ||||
|                                     + " " + GetText(channel, "pick_sn", prefix) | ||||
|                                 : GetText(channel, "curgen_pl", dropAmount, _bc.BotConfig.CurrencySign) | ||||
|                                     + " " + GetText(channel, "pick_pl", prefix); | ||||
|                             var file = GetRandomCurrencyImage(); | ||||
|                             using (var fileStream = file.Data.ToStream()) | ||||
|                             { | ||||
|                                 var sent = await channel.SendFileAsync( | ||||
|                                     fileStream, | ||||
|                                     file.Name, | ||||
|                                     toSend).ConfigureAwait(false); | ||||
|  | ||||
|                                 msgs[0] = sent; | ||||
|                             } | ||||
|  | ||||
|                             PlantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     LogManager.GetCurrentClassLogger().Warn(ex); | ||||
|                 } | ||||
|             }); | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										71
									
								
								NadekoBot.Core/Modules/Games/Services/PollService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								NadekoBot.Core/Modules/Games/Services/PollService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using Discord.WebSocket; | ||||
| using NadekoBot.Common.ModuleBehaviors; | ||||
| using NadekoBot.Modules.Games.Common; | ||||
| using NadekoBot.Core.Services; | ||||
| using NadekoBot.Core.Services.Impl; | ||||
| using NLog; | ||||
|  | ||||
| namespace NadekoBot.Modules.Games.Services | ||||
| { | ||||
|     public class PollService : IEarlyBlockingExecutor, INService | ||||
|     { | ||||
|         public ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>(); | ||||
|         private readonly Logger _log; | ||||
|         private readonly DiscordSocketClient _client; | ||||
|         private readonly NadekoStrings _strings; | ||||
|  | ||||
|         public PollService(DiscordSocketClient client, NadekoStrings strings) | ||||
|         { | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|             _client = client; | ||||
|             _strings = strings; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool?> StartPoll(ITextChannel channel, IUserMessage msg, string arg) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";")) | ||||
|                 return null; | ||||
|             var data = arg.Split(';'); | ||||
|             if (data.Length < 3) | ||||
|                 return null; | ||||
|  | ||||
|             var poll = new Poll(_client, _strings, msg, data[0], data.Skip(1)); | ||||
|             if (ActivePolls.TryAdd(channel.Guild.Id, poll)) | ||||
|             { | ||||
|                 poll.OnEnded += (gid) => | ||||
|                 { | ||||
|                     ActivePolls.TryRemove(gid, out _); | ||||
|                 }; | ||||
|  | ||||
|                 await poll.StartPoll().ConfigureAwait(false); | ||||
|                 return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage msg) | ||||
|         { | ||||
|             if (guild == null) | ||||
|                 return false; | ||||
|  | ||||
|             if (!ActivePolls.TryGetValue(guild.Id, out var poll)) | ||||
|                 return false; | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 return await poll.TryVote(msg).ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _log.Warn(ex); | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user