#!/usr/bin/ruby # vim: expandtab tabstop=2 shiftwidth=2 softtabstop=2 autoindent: require 'rubygems' require 'socket' require 'digest/md5' # .. allowed commands .. ROLES = CAPABILITIES # normal users have ROLE broadcast. Roles are defined on a per-user basis .. in a config. $version = "0.11big_yadda" $debug = 0 $role_commands = Hash[ "everyone" => ["PING", "WHO", "C", "PART"], "broadcast_admin" => ["BC_ID", "BC", "BC_ENDCOUNT"], "broadcast" => ["REQ_BC", "BC_RE"], "specbot_admin" => ["REQ_ASSIGN", "REQ_UNASSIGN", "REQ_PING", "REQ_ASSIGNMENTS"], "specbot" => ["ASSIGN_RE", "UNASSIGN_RE", "PING_RE", "ASSIGNMENTS_RE"], ] $default_role = "everyone" # which role is talking to which role? # effectively it says: this (local) command is sent to that (remote) topic .. that certain topic is read by that user with that role. $role_dialogs = Hash[ "everyone" => ["everyone"], "broadcast_admin" => ["broadcast"], "broadcast" => ["broadcast_admin"], "specbot_admin" => ["specbot"], "specbot" => ["specbot_admin"], ] $user_roles = Hash[ "paul_dev_eggdrop" => ["everyone", "broadcast"], "paul_eggdrop" => ["everyone", "broadcast"], "paul_dev_specbot" => ["everyone", "broadcast", "specbot"], "paul_specbot" => ["everyone", "broadcast", "specbot"], "qw.nu" => ["everyone", "broadcast"], "qw.nu_poster" => ["everyone", "broadcast"], "mihawk_dev_specbot" => ["everyone", "broadcast", "specbot"], "mihawk_specbot" => ["everyone", "broadcast", "specbot"], "central_brain" => ["everyone", "broadcast_admin", "specbot_admin"], ] STDOUT.sync = true def displaying(client, user) #client.puts "#{user} connected." begin loop do while line = $display_queue[user][0] client.puts line $display_queue[user].delete_at(0) end sleep 0.1 end rescue Exception => e puts e.message puts e.backtrace.inspect end end def write_user(user, input) if online_users.user(user) sometime = "#{Time.now.strftime("%Y-%m-%d %H:%M:%S %z")}" line = "#{sometime}: #{input}" $display_queue[user].push(line) end end def inputting(user, input) write_user(user, "You said: #{input}") if input =~ /^w (.+)/ input = $1 write_user("paul_dev_eggdrop", "he said: #{input}") end end def kill_conn(c, user, t_display) sleep 0.5 # delete the key out off $display_queue $display_queue.delete(user) # shut down displaying thread and connection t_display.exit # shut down connection c.close end def online_users def user(user) if online_users.include? user return true else return false end end ousers = Array.new $display_queue.each_key {|k| ousers.push(k)} return ousers end def write_role(role, input) #find users with role users = Array.new $user_roles.each {|k, v| if v.include? role users.push(k) end } # find users that are online and inside Array "users" lala = Array.new users.each {|v| if $display_queue.has_key? v lala.push(v) end } # now write to them lala.each {|user| write_user(user, input) } end def thinking(c, user, t_display) put_log "#{user} connected. Online now: #{online_users.join(", ")}" if not $user_roles.any? {|k, v| k.include? user} put_log "SYS User '#{user}' unknown to me. Saying bye." write_user(user, "SYS User '#{user}' unknown to me. Bye.") return false end my_roles = $user_roles[user] my_cmds = my_roles.collect {|v| $role_commands[v]}.flatten write_user(user, "HELLO Hi user '#{user}'! How are you? I'm #{$version}") write_user(user, "ROLES #{my_roles.join(", ")}") write_user(user, "COMMANDS #{my_cmds.join(", ")}") write_user(user, "SYS User '#{user}' just joined the party.") write_role("broadcast", "to the broadcasting role") # reading the client input ... to write it somewhere, possibly to the client himself. begin while input = c.gets.chomp inputting(user, input) end rescue Exception => e #puts e.message #puts e.backtrace.inspect put_log "#{user} lost connection." end end def spawn_server $display_queue = Hash.new server = TCPServer.new 7337 Thread.abort_on_exception = true loop do Thread.start(server.accept) do |c| user = c.gets.chomp # only one connection from a user allowed - we don't handle multiple display_queues for one user!!!!!11111 if online_users.user(user) c.close else $display_queue[user] = Array.new #p $display_queue # ok we can take $display_queue to check for online users. # this thread reads what others want you to read .. t_user_display = Thread.new{ displaying(c, user) } begin execution = thinking(c, user, t_user_display) if not execution # shut down displaying thread and connection kill_conn(c, user, t_user_display) end rescue Exception => e puts e.message puts e.backtrace.inspect kill_conn(c, user, t_user_display) end # of rescue put_log "Online now: #{online_users.join(", ")}" end end end end def put_debug(msg) if $debug == 1 puts msg end end def put_log(msg) puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S %z")}: #{msg}" end spawn_server