TracNav menu
OC's rbot Recipes and tips
This page will be somewhat of a documentations page covering stuff I do. Hopefully someone will make use out of it
Tips
Login
The old auth command is now replaced by login owner ! More information in RbotSecurity
Recipes
Create a HL2 server query module
As the sample modules might be a bit tricky to understand I've here commented my first module, a Half-Life 2 Source Engine query script.
Step 1, document your plugin! It's important to know what the plugin does and is for immediately, so follow the best practice, and add a short header to your plugin file. rbot is released under GPL v2, you should do this aswell, however MIT, BSD, Apache 2 and Mozilla based licenses should be ok too.
# Plugin for the Ruby IRC bot (http://linuxbrit.co.uk/rbot/) # # Simple Half-Life 2 (Source Engine) plugin to query online # servers to see if its online and kicking and how many users. # # Added 2 seconds timeout to the response. And sockets are now # closing properly. # # (c) 2006 Ole Christian Rynning <oc@rynning.no> # Licensed under GPL V2.
Step 2, Create your plugin. As you might have read before, rbot has a Plugin interface that your plugins should inherit. My example plugin uses two libraries, Socket for (UDP) socket handling and Timeout for ensuring that requests time out properly.
require 'socket' require 'timeout' class HL2Plugin < Plugin
Use constants! This is programming best practise, and consistent with DRY thought. A2S_INFO is the Source Engine server information query string documented at http://developer.valvesoftware.com/wiki/Source_Server_Queries in case you were wondering.
I also use a constant for the TIMEOUT value, here, 2 seconds.
A2S_INFO = "\xFF\xFF\xFF\xFF\x54\x53\x6F\x75\x72\x63\x65\x20\x45\x6E\x67\x69\x6E\x65\x20\x51\x75\x65\x72\x79\x00" TIMEOUT = 2
Now for the actions. Try to split up functionality, this action performs the a2s_info query. Since the plugin for now only support one function ;; a2s_info queries, I have put all of the socket handling, send and receive in one action: Note that the action handles the timeout exceptions by simply ignoring it.
def a2s_info(addr, port)
socket = UDPSocket.new()
socket.send(A2S_INFO, 0, addr, port.to_i)
response = nil
begin
timeout(TIMEOUT) do
response = socket.recvfrom(1400,0)
end
rescue Exception
end
socket.close()
response ? response.first.unpack("iACZ*Z*Z*Z*sCCCaaCCZ*") : nil
end
A plugin should override a simple help action, so that the user can easily know how to use the plugin.
def help(plugin, topic="")
"hl2 'server:port' => show basic information about the given server"
end
Now for the "magic action", the hl2 action handles simple mappings (mappings without a specified target name). As long as you do not specify an action in the mapping (further below) it will automatically use the action with the same name. My action is currently very simple, it takes only one parameter, a connection string in the format hostname:port or ip:port, for example '217.78.96.31:26015'.
You should also note that I make use of Threading for the server request, as the UDPSocket.recvfrom() action will freeze up the bot otherwise. This threading ensures that your bot will still run smoothly if you run an action that requires alot of time to process or CPU, memory, and other resources.
def hl2(m, params)
addr, port = params[:conn_str].split(':')
Thread.start do
info = a2s_info(addr, port)
if info != nil
m.reply "#{info[3]} is online with #{info[8]}/#{info[9]} players."
else
m.reply "Couldn't connect to #{params[:conn_str]}"
end
end
end
Note that m is a special RBOT::Plugin variable that handles the requesters information, such as who invoked the trigger for the plugin.
Finally theres invoking the plugin, and mapping it to a trigger.
The line 'plugin.map 'hl2 :conn_str' simply means that it will execute the hl2 action with a parameter :conn_str if it is triggered.
You could map 'anything' to be the trigger, by i.e.
plugin.map 'anything :conn_str', :action => 'hl2'
end plugin = HL2Plugin.new plugin.map 'hl2 :conn_str'
