1 /++ 2 The Chatbot plugin is a diminishing collection of small, harmless features; 3 like `say`/`echo` for simple repeating of text. 4 5 It's mostly legacy. 6 7 See_Also: 8 https://github.com/zorael/kameloso/wiki/Current-plugins#chatbot, 9 [kameloso.plugins.common.core], 10 [kameloso.plugins.common.misc] 11 12 Copyright: [JR](https://github.com/zorael) 13 License: [Boost Software License 1.0](https://www.boost.org/users/license.html) 14 15 Authors: 16 [JR](https://github.com/zorael) 17 +/ 18 module kameloso.plugins.chatbot; 19 20 version(WithChatbotPlugin): 21 22 private: 23 24 import kameloso.plugins; 25 import kameloso.plugins.common.core; 26 import kameloso.plugins.common.awareness : MinimalAuthentication; 27 import kameloso.messaging; 28 import dialect.defs; 29 import std.typecons : Flag, No, Yes; 30 31 32 // ChatbotSettings 33 /++ 34 Settings for a chatbot, to toggle its features. 35 +/ 36 @Settings struct ChatbotSettings 37 { 38 /// Whether or not the Chatbot plugin should react to events at all. 39 @Enabler bool enabled = true; 40 } 41 42 43 // onCommandSay 44 /++ 45 Repeats text to the channel the event was sent to. 46 47 If it was sent in a query, respond in a private message in kind. 48 +/ 49 @(IRCEventHandler() 50 .onEvent(IRCEvent.Type.CHAN) 51 .onEvent(IRCEvent.Type.QUERY) 52 .permissionsRequired(Permissions.anyone) 53 .channelPolicy(ChannelPolicy.home) 54 .addCommand( 55 IRCEventHandler.Command() 56 .word("say") 57 .policy(PrefixPolicy.prefixed) 58 .description("Repeats text to the current channel. Amazing.") 59 .addSyntax("$command [text to repeat]") 60 ) 61 .addCommand( 62 IRCEventHandler.Command() 63 .word("säg") 64 .policy(PrefixPolicy.nickname) 65 .hidden(true) 66 ) 67 .addCommand( 68 IRCEventHandler.Command() 69 .word("echo") 70 .policy(PrefixPolicy.prefixed) 71 .hidden(true) 72 ) 73 ) 74 void onCommandSay(ChatbotPlugin plugin, const ref IRCEvent event) 75 { 76 immutable message = event.content.length ? 77 event.content : 78 "Say what?"; 79 80 privmsg(plugin.state, event.channel, event.sender.nickname, message); 81 } 82 83 84 // onDance 85 /++ 86 Does the bash.org dance emotes. 87 88 - http://bash.org/?4281 89 +/ 90 @(IRCEventHandler() 91 .onEvent(IRCEvent.Type.CHAN) 92 .permissionsRequired(Permissions.anyone) 93 .channelPolicy(ChannelPolicy.home) 94 ) 95 void onDance(ChatbotPlugin plugin, const /*ref*/ IRCEvent event) 96 { 97 import kameloso.constants : BufferSize; 98 import lu.string : strippedRight; 99 import std.string : indexOf; 100 import core.thread : Fiber; 101 import core.time : seconds; 102 103 immutable content = event.content.strippedRight; 104 immutable dancePos = content.indexOf("DANCE"); 105 106 if (dancePos == -1) return; 107 108 if ((dancePos > 0) && (content[dancePos-1] != ' ')) 109 { 110 return; 111 } 112 else if (content.length > (dancePos+5)) 113 { 114 string trailing = content[dancePos+5..$]; // mutable 115 116 while (trailing.length) 117 { 118 import std.algorithm.comparison : among; 119 if (!trailing[0].among!(' ', '!', '.', '?')) return; 120 trailing = trailing[1..$]; 121 } 122 } 123 124 // Should dance. Stagger it a bit with a second in between. 125 static immutable timeBetweenDances = 1.seconds; 126 127 void danceDg() 128 { 129 import kameloso.plugins.common.delayawait : delay; 130 import kameloso.messaging : emote; 131 132 emote(plugin.state, event.channel, "dances :D-<"); 133 delay(plugin, timeBetweenDances, Yes.yield); 134 135 emote(plugin.state, event.channel, "dances :D|-<"); 136 delay(plugin, timeBetweenDances, Yes.yield); 137 138 emote(plugin.state, event.channel, "dances :D/-<"); 139 } 140 141 Fiber danceFiber = new Fiber(&danceDg, BufferSize.fiberStack); 142 danceFiber.call(); 143 } 144 145 146 mixin MinimalAuthentication; 147 mixin PluginRegistration!ChatbotPlugin; 148 149 public: 150 151 152 // Chatbot 153 /++ 154 The Chatbot plugin provides trivial chat functionality. 155 +/ 156 final class ChatbotPlugin : IRCPlugin 157 { 158 private: 159 /// All Chatbot plugin settings gathered. 160 ChatbotSettings chatbotSettings; 161 162 mixin IRCPluginImpl; 163 }