Esempio n. 1
0
        [ItemCanBeNull] private async Task <IConversation> TryCreateConversation([NotNull] MuteCommandContext context, bool mentionsBot)
        {
            //Find generators which can respond to this message
            var random     = new Random(context.Message.Id.GetHashCode());
            var candidates = new List <IConversation>();

            foreach (var generator in _responses.AsParallel())
            {
                var conversation = await generator.TryRespond(context, mentionsBot);

                if (conversation == null)
                {
                    continue;
                }

                var rand = random.NextDouble();
                if ((mentionsBot && rand < generator.MentionedChance) || (!mentionsBot && rand < generator.BaseChance))
                {
                    candidates.Add(conversation);
                }
            }

            //If there are several pick a random one
            return(IEnumerableExtensions.Random(candidates, _random));
        }
Esempio n. 2
0
        public static async Task <SentimentResult> Sentiment([NotNull] this MuteCommandContext context)
        {
            var r = await context.GetOrAdd <SentimentResultContainer>(async() => {
                var sentiment = (ISentimentService)context.Services.GetService(typeof(ISentimentService));
                return(new SentimentResultContainer(await sentiment.Predict(context.Message.Content)));
            });

            return(r.Result);
        }
Esempio n. 3
0
 public async Task <bool> Process(MuteCommandContext context, IResult result)
 {
     if (result.Error == CommandError.UnknownCommand)
     {
         var input      = context.Message.Content ?? "";
         var spaceIndex = input.IndexOf(' ');
         var inputCmd   = input;
         if (spaceIndex != -1)
         {
             inputCmd = input[..spaceIndex];
Esempio n. 4
0
 public Task <string> Respond(MuteCommandContext context, bool containsMention, CancellationToken ct)
 {
     return(Task.Run(() => {
         lock (_eliza)
         {
             var response = _eliza.ProcessInput(context);
             IsComplete = _eliza.Finished;
             return response;
         }
     }, ct));
 }
Esempio n. 5
0
        public async Task <IConversation?> TryRespond(MuteCommandContext context, bool containsMention)
        {
            //Determine if thie message is a greeting
            var isGreeting = context.Message.Content.Split(' ').Select(CleanWord).Any(a => AllGreetings.Contains(a));

            var gu   = context.User as SocketGuildUser;
            var name = gu?.Nickname ?? context.User.Username;

            return(isGreeting
                ? new HelloConversation(string.Format(ChooseGreeting(), name))
                : null);
        }
Esempio n. 6
0
        private async Task <IConversation> GetOrCreateConversation([NotNull] MuteCommandContext context, bool mentionsBot)
        {
            //Create a new conversation starting with this message
            var newConv = await TryCreateConversation(context, mentionsBot);

            //Use the existing conversation if it is not over, or else replace it with the new conversation
            return(_conversations.AddOrUpdate(
                       context.User,
                       _ => newConv,
                       (_, c) => (c?.IsComplete ?? true) ? newConv : c
                       ));
        }
Esempio n. 7
0
        public async Task <bool> Process(MuteCommandContext context, IResult result)
        {
            // Only respond to strings of all <prefix char>
            if (context.Message.Content.Any(a => a != _config.PrefixCharacter))
            {
                return(false);
            }

            // Don't respond all the time
            if (_random.NextDouble() < 0.5f)
            {
                return(true);
            }

            // Choose a random response for TTS ot text
            var responses = _responses.Random(_random);

            // If user is in voice and bot is already in channel, use TTS to respond
            if (context.User is IVoiceState vs && context.Guild != null)
            {
                var ttsQueue = await _ttsQueue.Get(context.Guild.Id);

                if (ttsQueue.VoicePlayer.Channel?.Id == vs.VoiceChannel.Id)
                {
                    await responses.ToAsyncEnumerable().Select(_tts.Synthesize).ForEachAsync(async clip => {
                        var audio = await clip;
                        await ttsQueue.Enqueue(audio.Name, await audio.Open());
                    });

                    return(true);
                }
            }

            // Respond with some kind of repeated character
            if (_random.NextDouble() < 0.5f)
            {
                var character = "!!!!???¡".Random(_random);

                await context.Channel.SendMessageAsync(new string(Enumerable.Repeat(character, context.Message.Content.Length + 1).ToArray()));

                return(true);
            }

            // Respond with one of a selection of messages
            foreach (var response in responses)
            {
                await context.Channel.TypingReplyAsync(response);

                await Task.Delay(200);
            }
            return(true);
        }
Esempio n. 8
0
        public Task <IConversation> TryRespond(MuteCommandContext context, bool containsMention)
        {
            //Determine if thie message is a greeting
            var isGreeting = context.Message.Content.Split(' ').Select(CleanWord).Any(AllGreetings.Contains);

            var gu   = (SocketGuildUser)context.User;
            var name = gu.Nickname ?? gu.Username;

            return(Task.FromResult <IConversation>(isGreeting
                ? new HelloConversation(string.Format(ChooseGreeting(), name))
                : null
                                                   ));
        }
Esempio n. 9
0
            public async Task <string?> Respond(MuteCommandContext message, bool containsMention, CancellationToken ct)
            {
                async Task <string?> ContinueActiveDiscussion()
                {
                    // if there is an active discussion, try to continue it
                    if (_active is { IsComplete : false })
                    {
                        string?reply;
                        (reply, _knowledge) = await _active.Reply(_knowledge, message);

                        return(reply);
                    }

                    return(null);
                }
Esempio n. 10
0
        public Task <IConversation> TryRespond(MuteCommandContext context, bool containsMention)
        {
            var rgx = new Regex("[^a-zA-Z0-9 -]");
            var msg = rgx.Replace(context.Message.Content, "");

            var words = msg.ToLowerInvariant().Split(' ');

            if (_triggerWords.Overlaps(words))
            {
                return(Task.FromResult <IConversation>(new UrbitConversation(Sarcasm())));
            }
            else
            {
                return(Task.FromResult <IConversation>(null));
            }
        }
Esempio n. 11
0
        public Task <string> Respond(MuteCommandContext context, bool containsMention, CancellationToken ct)
        {
            IsComplete = true;

            if (_reactions != null && _reactions.Length > 0)
            {
                Task.Run(async() => {
                    foreach (var reaction in _reactions)
                    {
                        await context.Message.AddReactionAsync(reaction);
                    }
                }, ct);
            }

            return(Task.FromResult(_response));
        }
Esempio n. 12
0
        private async Task HandleMessage(SocketMessage messageParam)
        {
            // Don't process the command if it was a System Message
            if (!(messageParam is SocketUserMessage message))
            {
                return;
            }

            //Ignore messages from self
            if (message.Author.Id == _client.CurrentUser.Id && !_config.ProcessMessagesFromSelf)
            {
                return;
            }

            // Check if the message starts with the command prefix character
            var prefixPos = 0;
            var hasPrefix = message.HasCharPrefix('!', ref prefixPos);

            // Create a context for this message
            var context = new MuteCommandContext(_client, message, _services);

            //Apply generic message preproccessor
            foreach (var pre in _services.GetServices <IMessagePreprocessor>())
            {
                pre.Process(context);
            }

            //Either process as command or try to process conversationally
            if (hasPrefix)
            {
                foreach (var pre in _services.GetServices <ICommandPreprocessor>())
                {
                    pre.Process(context);
                }
                await ProcessAsCommand(prefixPos, context);
            }
            else
            {
                foreach (var pre in _services.GetServices <IConversationPreprocessor>())
                {
                    pre.Process(context);
                }
                await _services.GetService <ConversationalResponseService>().Respond(context);
            }
        }
Esempio n. 13
0
        public async Task <IConversation?> TryRespond(MuteCommandContext context, bool containsMention)
        {
            var s = await context.Sentiment();

            if (s.ClassificationScore < Bracket || s.Classification == Sentiment.Neutral)
            {
                return(null);
            }

            if (s.Classification == Sentiment.Positive)
            {
                return(new SentimentConversation(new Emoji(Happy.Random(_random))));
            }
            else
            {
                return(new SentimentConversation(new Emoji(Sad.Random(_random))));
            }
        }
Esempio n. 14
0
        public async Task Respond([NotNull] MuteCommandContext context)
        {
            // Check if the bot is directly mentioned
            var mentionsBot = ((IMessage)context.Message).MentionedUserIds.Contains(_client.CurrentUser.Id);

            //Try to get a conversation with this user (either continued from before, or starting with a new one)
            var c = await GetOrCreateConversation(context, mentionsBot);

            //If we have a conversation, try to reply to this message
            if (c != null)
            {
                var r = await c.Respond(context, mentionsBot, CancellationToken.None);

                if (r != null)
                {
                    await context.Channel.TypingReplyAsync(r);
                }
            }
        }
Esempio n. 15
0
            public async Task <(string?, IKnowledge)> Reply(IKnowledge knowledge, MuteCommandContext message)
            {
                if (IsComplete)
                {
                    return(null, knowledge);
                }

                // Get or construct an eliza engine from the knowledge chain
                // If the previous engine has finished a new one will be constructed
                ElizaEngineAdapter engine;

                (engine, knowledge) = knowledge.GetOrAdd(e => !e.Eliza.Finished, k => new ElizaEngineAdapter(k, _script));

                // Get a response from eliza and pass it back
                var response = engine.Eliza.ProcessInput(message);

                IsComplete = engine.Eliza.Finished;
                return(response, knowledge);
            }
Esempio n. 16
0
        public async Task <bool> Process(MuteCommandContext context, [NotNull] IResult result)
        {
            if (result.Error == CommandError.UnknownCommand)
            {
                var input      = context.Message.Content ?? "";
                var spaceIndex = input.IndexOf(' ');
                var inputCmd   = input;
                if (spaceIndex != -1)
                {
                    inputCmd = input.Substring(0, spaceIndex);
                }

                inputCmd = inputCmd.TrimStart(_config.PrefixCharacter);

                //Take a random command from the group of commands which are closest
                var closest = _commands.Commands
                              .Select(c => new { c, d = c.Aliases.Append(c.Name).Min(n => n.Levenshtein(inputCmd)) })
                              .GroupBy(a => a.d)
                              .MinBy(a => a.Key)
                              .Random(_random);

                //If we can't find a command, or the one we found has too many differences to be considered, just exit out
                if (closest == null || closest.d >= inputCmd.Length * 0.5)
                {
                    await context.Channel.SendMessageAsync("I don't know that command :confused:");

                    return(false);
                }

                //Suggest a potential matched command
                await context.Channel.TypingReplyAsync("I don't know that command, did you mean:", embed : Help.FormatCommandDetails(context, _prefix, new[] { closest.c }).Build());
            }
            else
            {
                if (result.ErrorReason != null)
                {
                    await context.Channel.SendMessageAsync(result.ErrorReason);
                }
            }

            return(false);
        }
Esempio n. 17
0
        private async Task ProcessAsCommand(int offset, MuteCommandContext context)
        {
            // When there's a mention the command may or may not include the prefix. Check if it does include it and skip over it if so
            if (context.Message.Content[offset] == _config.PrefixCharacter)
            {
                offset++;
            }

            // Execute the command
            try
            {
                foreach (var pre in _services.GetServices <ICommandPreprocessor>())
                {
                    await pre.Process(context);
                }

                var result = await _commands.ExecuteAsync(context, offset, _services);

                if (result.IsSuccess)
                {
                    foreach (var post in _services.GetServices <ISuccessfulCommandPostprocessor>())
                    {
                        await post.Process(context);
                    }
                }
                else
                {
                    foreach (var post in _services.GetServices <IUnsuccessfulCommandPostprocessor>().OrderBy(a => a.Order))
                    {
                        if (await post.Process(context, result))
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Esempio n. 18
0
        public Task <IConversation> TryRespond(MuteCommandContext context, bool containsMention)
        {
            return(Task.Run <IConversation>(() => {
                if (_scripts.Count == 0)
                {
                    return null;
                }

                //Determine if thie message is a greeting
                var isGreeting = context.Message.Content.Split(' ').Select(CleanWord).Any(_greetings.Contains);

                if (isGreeting)
                {
                    var seed = context.Message.Id.GetHashCode();
                    var rand = new Random(seed);
                    return new ElizaConversation(IEnumerableExtensions.Random(_scripts, rand), seed);
                }
                else
                {
                    return null;
                }
            }));
        }
Esempio n. 19
0
        public async Task <bool> Process(MuteCommandContext context, IResult result)
        {
            // Only respond to strings of all <prefix char>
            if (context.Message.Content.Any(a => a != _config.PrefixCharacter))
            {
                return(false);
            }

            // Don't respond all the time
            if (_random.NextDouble() < 0.5f)
            {
                return(true);
            }

            // Choose a random response for TTS ot text
            var responses = _responses.Random(_random);

            // Respond with some kind of repeated character
            if (_random.NextDouble() < 0.5f)
            {
                var character = "!!!!???¡".Random(_random);

                await context.Channel.SendMessageAsync(new string(Enumerable.Repeat(character, context.Message.Content.Length + 1).ToArray()));

                return(true);
            }

            // Respond with one of a selection of messages
            foreach (var response in responses)
            {
                await context.Channel.TypingReplyAsync(response);

                await Task.Delay(200);
            }
            return(true);
        }
Esempio n. 20
0
 protected internal override IEndExecute StartExecute(MuteCommandContext context)
 {
     return(new DisposableEnd(context.Channel.EnterTypingState()));
 }
Esempio n. 21
0
        public async Task <string?> Respond(MuteCommandContext context, bool containsMention, CancellationToken ct)
        {
            IsComplete = true;

            if (_reactions is { Length : > 0 })
Esempio n. 22
0
 public async Task <ITopicDiscussion?> TryBegin(MuteCommandContext message, IKnowledge knowledge, CancellationToken ct)
 {
     return(new ElizaKeyDiscussionAdapter(_script));
 }
Esempio n. 23
0
        protected internal override IEndExecute StartExecute(MuteCommandContext context)
        {
            context.Message.AddReactionAsync(_emote);

            return(new EndExecute(context.Message, _emote, context.Client.CurrentUser));
        }
 /// <summary>
 /// Return an object which will be disposed once the command execution is complete
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 [NotNull] protected internal abstract IEndExecute StartExecute([NotNull] MuteCommandContext context);
Esempio n. 25
0
 public async Task <IConversation?> TryRespond(MuteCommandContext context, bool containsMention)
 {
     return(new EllenConversation(_topics, new Root()));
 }