public
Created

Simple Minecraft jabber bot

  • Download Gist
jabber_bot.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
###
# Simple jabber bot to let me talk to users of my minecraft server from gtalk
 
require 'xmpp4r-simple'
 
BOT_USERNAME = '...'
BOT_PASSWORD = '...'
 
ADMIN_USERNAME = '...'
 
SCREEN_NAME = 'minecraft'
 
# The idea for this method came from here but I blockified it:
# http://stackoverflow.com/questions/1293695/watch-read-a-growing-log-file-with-ruby
def watch_file(file, &block)
timeout = 1
f = File.open(file, "r")
f.seek(0, IO::SEEK_END)
 
while true do
select [f]
yield f.gets
sleep timeout
end
end
 
def say(message)
%x{screen -S #{SCREEN_NAME} -p 0 -X stuff "`printf "say #{message}\r"`"}
end
 
jabber = Jabber::Simple.new(BOT_USERNAME, BOT_PASSWORD, nil, 'Minecraft Bot')
 
admin_online = false
 
# Trap CTRL-C to logoff cleanly.
trap("INT") do
jabber.disconnect
puts "\nLogging off."
exit
end
 
watch_file('server.log') do |line|
case line
when /\[INFO\] (.*?) \[[0-9\/\.:]+\] logged in/
jabber.deliver(ADMIN_USERNAME, "#{$1} logged in")
when /\[INFO\] (.*?) lost connection: (.*)/
jabber.deliver(ADMIN_USERNAME, "#{$1} lost connection: #{$2}")
when /\[INFO\] (?:\[.*?\] )?(.*?): (.*)/
jabber.deliver(ADMIN_USERNAME, "#{$1}: #{$2}")
end
 
# Crudely determine if the admin is online
jabber.presence_updates do |update|
admin_online = true if update[0] == ADMIN_USERNAME && update[1] == :online
admin_online = false if update[0] == ADMIN_USERNAME && update[1] == :unavailable
end
 
jabber.received_messages {|msg| say msg.body if admin_online }
end

Hello, I'm new to ruby and would love some more information on how to be able to use this script! Thanks.

Hi, this monitors the server.log for any chat messages and sends them to the admin over jabber. When the admin responds, the message is sent to the server. This requires that you have the minecraft server running in an instance of screen. By default it uses the socket name minecraft; you can start screen with screen -S minecraft then disconnect screen. After you change the username, password and admin account, put this in the same directory as your server.log file and run it. I hope this helps.

Awesome! I'm still unable to get it to work though. :(

I've edited the script (I assume ruby) and have installed xmpp4r-simple, edited bot username/password to my gmail information**, edited Admin username to my minecraft username, and set the screen name to the correct screen which is 'WonderLand'. However I'm unsure how to run it. haha.

I've also tried, instead of my gmail information, to use my own jabber server information. I get no errors either way (except when I supply incorrect information) and it seems to login to my accounts via the scripts just fine, but I'm unable to view any information from chat. :( Makes me believe it has something to do with screen.

I don't have a minecraft server running anymore but I just tested it by echoing text to server.log like the server was actually running. It worked, but it makes me think that it's either an issue with screen like you suggested, or the format of messages from the minecraft server has changed since I wrote this. When you start screen, did you run screen -S WonderLand then run minecraft in that screen? If you send a message to the bot over jabber, do you see it pop up in the screen session?

This script is looking for messages in the format [INFO] <SomeUser> What the user said. Is that what the server log still looks like? If not, post a line here from your log and I can help you match it correctly.

The exact echo in the server.log is formatted such as this:

timestamp - [INFO] - [Groupname] Username: Message
21:33:40 [INFO] [Developer] Xanza: test

Also yes, I did screen -S WonderLand and then did my java command to start the server.

IMAGE: http://i.imgur.com/nrbYX.png

On the left you can see the screen window in which the server is currently running, to the right is my Jabber client (PSI) which as you can see the script is running correctly because I receive no error form "ruby jabber.rb" and the bot successfully logs on. I sent the message "test" to the bot, and as you can see, it's not reflected in the client, or in the server.log. Also just to be sure, I chmodded both the ruby script and the server.log to 0777.

I really appreciate the help! I've been looking for this exact script for what seems like forever! haha.

Hey, I don't mind helping at all. I wish it was easier to use but I only used it for a few months and didn't know it would be useful for anyone else. :) I think I see 2 problems you're having:

Set the admin username to the jabber user (full email address) who will receive the chat messages. This is also the only person who can chat to the server through jabber. It's not your minecraft username.

Another problem is that the regular expression isn't matching the messages anymore. I updated the gist so that it will use the new format for chats.

Let me know if you still have problems.

It's almost totally functioning now! WooHoo!

The only problem I have is that it keeps logging off jabber. :(

IMAGE: http://i.imgur.com/Mk5Ss.png

As you can see, it notifies me of used commands, and I'm able to communicate as [Server], but after about 30 seconds it logs off (even when running in it's own screen!) and any additional messages are sent via a new chat window. Any ideas?

This script is so cash by the way!

I don't think I'll be able to help you with this one. Are you getting any errors from the ruby script when that happens? I can't reproduce it. I remember it staying connected for hours when I used it. Are you running it twice or something? One version might kick another one off.

Yup! That was it. :P For whatever reason a single 'ruby jabber.rb' command was running it twice! I restarted my server and it's working 100% now! Thank you so much for taking the time to help, and to create this little gem!

No problem at all, I'm glad it's useful!

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.