Class: Participle::Bot
- Inherits:
-
Object
- Object
- Participle::Bot
- Includes:
- CLI, Colors, Events, Log, Token
- Defined in:
- lib/bot.rb
Overview
The basic bot class.
Constant Summary
- PARTICIPLE_VERSION =
what do you think?
"1.4.0"
Constants included from Colors
Colors::ANSI_COLORS_HEX, Colors::ANSI_COLORS_NAMED, Colors::ANSI_STYLES
Instance Attribute Summary (collapse)
-
- (String) __cli_buffer
readonly
private
The bot's command-line buffer.
-
- (Array<Command>) _commands
readonly
All the bot's commands.
-
- (String) current_room
The current room to which the bot is joined.
-
- (Boolean) logging
readonly
Whether we are logging or not.
-
- (Hash<Class, Object>) modules
readonly
All of the bot's modules (coupled with instances).
-
- (Hash<String, DA::Room>) rooms
Currently joined rooms.
-
- (TCPSocket) server
readonly
The server connection.
-
- (Boolean) silent
Whether the bot is on silent mode or not.
-
- (String) token
readonly
The bot's authtoken.
Instance Method Summary (collapse)
-
- (void) action(line, room)
Send an action in room.
-
- (String) command(pktname, pktparam = nil, opts = {})
Send a command to the server.
-
- (OpenStruct) configuration(opts = {}) {|config| ... }
Access to bot configuration.
-
- (void) debug(*str)
Debug messages.
-
- (void) disconnect(status)
The clean way to disconnect from the server; finishes the logs, closes the database connection, disconnects gracefully from dAmn.
-
- (Array<Command>) each_command(key) {|command| ... }
When called in block format, just yields all the commands in order; otherwise, returns the appropriate commands array.
-
- (String) filter(line)
Encode and HTML-escape a line.
-
- (Bot) initialize { ... }
constructor
Creates a new bot.
-
- (Object) kick(user, room, reason = nil)
Kick a user from room.
-
- (Boolean) load_module(modname)
Adds all of a module's commands and adds an instance to the @modules hash.
-
- (Boolean) module_exists(modname)
This merely checks if a properly named module file is found in ext/.
-
- (Command) on(msgtype, pattern = nil, opts = {}, &blk)
Add a command to the hash.
-
- (void) save_config
Removes unnecessary keys and saves the current configuration to the config file.
-
- (void) say(line, room, parsed = true)
Say something in room.
-
- (Object) set_configuration_option(key, value)
Simple frontend method for editing the bot's configuration.
-
- (void) start!
Starts the bot.
-
- (Boolean) unload_module(modname)
Removes all the commands of the named module and deletes its instance.
-
- (Object) wait_for(msgtype, opts = {}) {|Packet| ... }
Executes a block when a packet meeting certain requirements is found.
-
- (Fixnum) write(data)
Write some data to the server.
Methods included from CLI
Methods included from Token
Methods included from Events
Methods included from Log
#add_logger, #error_display, #flush_logs, #log, #remove_logger, #setup_logging
Methods included from Colors
#ansi_colorize, #ansi_stylize, #chromaticied, #closest_to, #color_difference, #colorize, #embolden, #format_html, #format_user, #get_term_size, #italicize, #loggerify, #room_name, #timestamp, #to_hex, #unchrome, #underscore
Constructor Details
- (Bot) initialize { ... }
Creates a new bot.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/bot.rb', line 89 def initialize &blk @silent = false @modules = {} @eventhandler = Suplex.new @reconnect_wait = 0 @__cli_buffer = "" # commands for each message type @_commands = {:join => [], :message => [], :part => [], :botjoin => [], :botpart => []} # hash, key names are room names and values are arrays of usernames @rooms = {} # bot configuration! @conf = OpenStruct.new :version => PARTICIPLE_VERSION, :trigger => "!", :blacklist => [], :logging => true, :pretty_display => true @__conv = Iconv.new("UTF-8", "LATIN1") # server connection @server = TCPSocket.new "chat.deviantart.com", 3900 @buffer = Queue.new Extension.bot = self Message.bot = self self.bind_event("dAmnServer", self.method(:on_handshake)) if blk instance_eval(&blk) else setup_from_conf_file() end @token = self.get_token() if @token.nil? && (@token = self.get_token(false)).nil? log "Authentication failed. Check your password." self.disconnect(0) end end |
Instance Attribute Details
- (String) __cli_buffer (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The bot's command-line buffer
60 61 62 |
# File 'lib/bot.rb', line 60 def __cli_buffer @__cli_buffer end |
- (Array<Command>) _commands (readonly)
All the bot's commands
63 64 65 |
# File 'lib/bot.rb', line 63 def _commands @_commands end |
- (String) current_room
The current room to which the bot is joined
56 57 58 |
# File 'lib/bot.rb', line 56 def current_room @current_room end |
- (Boolean) logging (readonly)
Whether we are logging or not
75 76 77 |
# File 'lib/bot.rb', line 75 def logging @logging end |
- (Hash<Class, Object>) modules (readonly)
All of the bot's modules (coupled with instances)
69 70 71 |
# File 'lib/bot.rb', line 69 def modules @modules end |
- (Hash<String, DA::Room>) rooms
Currently joined rooms
50 51 52 |
# File 'lib/bot.rb', line 50 def rooms @rooms end |
- (TCPSocket) server (readonly)
The server connection
66 67 68 |
# File 'lib/bot.rb', line 66 def server @server end |
- (Boolean) silent
Whether the bot is on silent mode or not
53 54 55 |
# File 'lib/bot.rb', line 53 def silent @silent end |
- (String) token (readonly)
The bot's authtoken
72 73 74 |
# File 'lib/bot.rb', line 72 def token @token end |
Instance Method Details
- (void) action(line, room)
This method returns an undefined value.
Send an action in room.
365 366 367 |
# File 'lib/bot.rb', line 365 def action line, room self.command "send", room, :body => "action main\n\n#{self.filter(line)}" end |
- (String) command(pktname, pktparam = nil, opts = {})
Send a command to the server
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/bot.rb', line 330 def command pktname, pktparam = nil, opts = {} str = "" str << pktname.to_s if pktparam str << " #{pktparam.to_s}" end opts.each{|k,v| next if k == :body str << "\n#{k}=#{v}" } if opts[:body] str << "\n\n" str << opts.delete(:body).to_s end str << "\n" unless pktname == "send" str << "\0" @server.write str str end |
- (OpenStruct) configuration(opts = {}) {|config| ... }
Access to bot configuration.
195 196 197 198 199 200 201 |
# File 'lib/bot.rb', line 195 def configuration opts = {} return @conf unless block_given? yield @conf return if opts[:nocallbacks] run_post_conf_callbacks log "Loaded configuration." end |
- (void) debug(*str)
This method returns an undefined value.
Debug messages.
161 162 163 164 |
# File 'lib/bot.rb', line 161 def debug *str str.map(&:to_s).each{|st|st.split("\n").each{|line|log "\e[1mdebug #\e[33m#{Time.now.to_i}\e[0m: #{line}"}} nil end |
- (void) disconnect(status)
This method returns an undefined value.
The clean way to disconnect from the server; finishes the logs, closes the database connection, disconnects gracefully from dAmn.
265 266 267 268 269 270 271 272 273 274 |
# File 'lib/bot.rb', line 265 def disconnect status log "Socket error! Forced exit." if status == 99 Storage.close command "disconnect" log "Disconnected from server." log "participle shutting down." print "\e[1000D\e[K" flush_logs exit(status) end |
- (Array<Command>) each_command(key) {|command| ... }
When called in block format, just yields all the commands in order; otherwise, returns the appropriate commands array.
298 299 300 301 302 303 304 305 306 |
# File 'lib/bot.rb', line 298 def each_command key if block_given? @_commands[key].each do |cmd| yield cmd end else @_commands[key] end end |
- (String) filter(line)
Encode and HTML-escape a line. Ideally, should be run on all commands that send some kind of intended human readable data to the server.
380 381 382 |
# File 'lib/bot.rb', line 380 def filter(line) line.to_s.gsub(/([^ a-zA-Z0-9_.\-'",;!@#\$%^&\*\(\)\{\}\?\/<>=\+:])/u){"&##{$1.unpack("U*")[0]};"} end |
- (Object) kick(user, room, reason = nil)
Kick a user from room.
373 374 375 |
# File 'lib/bot.rb', line 373 def kick user, room, reason = nil self.command "kick", room, :u => user, :body => reason end |
- (Boolean) load_module(modname)
Adds all of a module's commands and adds an instance to the @modules hash.
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/bot.rb', line 237 def load_module(modname) return false unless module_exists(modname) begin if @modules[Object.const_get(modname)] log "#{embolden(modname)} is already loaded." return false end rescue end begin load "ext/%s.rb" % modname.underscore rescue log "Uh-oh, couldn't load #{embolden(modname)}." raise end begin name = Object.const_get(modname) @modules[name] = name.new log "Loaded module #{embolden(name.to_s)}." rescue NameError return false end true end |
- (Boolean) module_exists(modname)
This merely checks if a properly named module file is found in ext/. The bot doesn't validate the file in any other way.
214 215 216 |
# File 'lib/bot.rb', line 214 def module_exists(modname) File.file?("ext/%s.rb" % modname.underscore) end |
- (Command) on(msgtype, pattern = nil, opts = {}, &blk)
Add a command to the hash.
319 320 321 322 |
# File 'lib/bot.rb', line 319 def on msgtype, pattern = nil, opts = {}, &blk = {:trigger => true, :usage => nil, :admin => false, :klass => nil, :level => 1}.merge(opts) @_commands[msgtype] << Participle::Command.new(pattern, blk, , @conf.trigger, self) end |
- (void) save_config
This method returns an undefined value.
Removes unnecessary keys and saves the current configuration to the config file. This method should always be used instead of attempting to write to the config file yourself.
285 286 287 288 289 290 291 292 |
# File 'lib/bot.rb', line 285 def save_config accepts = [:trigger, :blacklist, :logging, :pretty_display, :nick, :password, :admin, :channels, :extensions] items = Hash[@conf.marshal_dump.select{|k,v|accepts.include?(k)}] items.extensions.reject!{|a|%w[System Damn].include?(a)}.sort! open("conf/conf.yaml", "w") {|file| file.write(YAML.dump(items)) } end |
- (void) say(line, room, parsed = true)
This method returns an undefined value.
Say something in room.
355 356 357 358 359 |
# File 'lib/bot.rb', line 355 def say line, room, parsed = true np = parsed ? "" : "np" line = @conf.chromacity_name && @conf.chromacity_line ? "#{line} <abbr title='colors:#{@conf.chromacity_name.upcase}:#{@conf.chromacity_line.upcase}'></abbr>" : line self.command "send", DA::Room === room ? room.name_formatted : room, :body => "#{np}msg main\n\n%s" % self.filter(line) end |
- (Object) set_configuration_option(key, value)
Simple frontend method for editing the bot's configuration.
207 208 209 |
# File 'lib/bot.rb', line 207 def set_configuration_option key, value @conf.send("#{key}=".to_sym, value) end |
- (void) start!
This method returns an undefined value.
Starts the bot.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/bot.rb', line 168 def start! if $opts[:prompt] && RUBY_PLATFORM =~ /darwin|linux/ @__cli_commands = {} @__cli_tabcomplete = {} @__cli_buffer = "" @__cli_history = [] self.cli_init self.threaded_prompt end @conf.start_time = DateTime.now log "Connecting to dAmn..." begin command "dAmnClient", 0.3, :agent => "participle/beta #{@conf.version}" loop { self.read_buffer } rescue SystemExit => e self.disconnect(e.status) rescue Errno::EPIPE, Errno::ECONNRESET self.reconnect end end |
- (Boolean) unload_module(modname)
Removes all the commands of the named module and deletes its instance.
221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/bot.rb', line 221 def unload_module(modname) @_commands.keys.each{|key| @_commands[key].delete_if{|x|x.opts[:klass].to_s == modname} } log "Unloaded module #{embolden(modname)}." begin @modules.delete(Object.const_get(modname)) rescue NameError return false end true end |
- (Object) wait_for(msgtype, opts = {}) {|Packet| ... }
Executes a block when a packet meeting certain requirements is found.
145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/bot.rb', line 145 def wait_for msgtype, opts = {}, &blk = ({:user => nil, :room => nil, :body => nil}).merge(opts) bind_event(msgtype) do |pkt| if ([:user].nil? || [:user] === pkt.subpkt[:from] || [:user] === pkt.param.sub("login:", "")) && ([:room].nil? || [:room] === pkt.room) && ([:body].nil? || [:body] === unchrome(pkt.body)) blk.call(pkt) self.unbind_last(msgtype) end end end |
- (Fixnum) write(data)
Write some data to the server.
279 280 281 |
# File 'lib/bot.rb', line 279 def write(data) @server.write(data) end |