Переглянути джерело

new central as a socket server.

Paul Klumpp 12 роки тому
батько
коміт
b752bb81a4
1 змінених файлів з 248 додано та 0 видалено
  1. 248 0
      sockcentral.rb

+ 248 - 0
sockcentral.rb

@@ -0,0 +1,248 @@
+#!/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