浏览代码

lots of DNS changes...

Paul Klumpp 11 年之前
父节点
当前提交
005db7a51b
共有 1 个文件被更改,包括 130 次插入62 次删除
  1. 130 62
      em_server.rb

+ 130 - 62
em_server.rb

@@ -4,6 +4,7 @@ require 'eventmachine'
 require 'digest/md5'
 require 'fiber'
 require 'geoip'
+require 'socket'
 
 
 
@@ -14,48 +15,108 @@ $version = "0.2EventMachineSocketServer"
 $debug = 0
 
 $role_commands = Hash[
-	"everyone" => ["PING", "WHO", "C", "PART"], 
-	
-	"broadcast_admin" => ["BC_ID", "BC", "BC_ENDCOUNT"],
-	"broadcast" => ["REQ_BC", "BC_RE"],
+  #noinspection RubyStringKeysInHashInspection
+  'everyone' => %w(PING WHO C PART),
+
+  'broadcast_admin' => %w(BC_ID BC BC_ENDCOUNT),
+  'broadcast' => %w(REQ_BC BC_RE),
 	
-	"specbot_admin" => ["REQ_ASSIGN", "REQ_UNASSIGN", "REQ_PING", "REQ_ASSIGNMENTS"],
-	"specbot" => ["ASSIGN_RE", "UNASSIGN_RE", "PING_RE", "ASSIGNMENTS_RE"],
-	]
+	'specbot_admin' => %w(REQ_ASSIGN REQ_UNASSIGN REQ_PING REQ_ASSIGNMENTS),
+	'specbot' => %w(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"],
+  #noinspection RubyStringKeysInHashInspection
+	'everyone' => %w(everyone),
 	
-	"broadcast_admin" => ["broadcast"],
-	"broadcast" => ["broadcast_admin"],
+	'broadcast_admin' => %w(broadcast),
+	'broadcast' => %w(broadcast_admin),
 	
-	"specbot_admin" => ["specbot"],
-	"specbot" => ["specbot_admin"],
+	'specbot_admin' => %w(specbot),
+	'specbot' => %w(specbot_admin),
 	]
 
 $user_roles = Hash[
-	"paul_dev_eggdrop" => ["everyone", "broadcast"],
-	"paul_eggdrop" => ["everyone", "broadcast"],
+  #noinspection RubyStringKeysInHashInspection
+	'paul_dev_eggdrop' => %w(everyone broadcast),
+	'paul_eggdrop' => %w(everyone broadcast),
 	
-	"paul_dev_specbot" => ["everyone", "broadcast", "specbot"],
-	"paul_specbot" => ["everyone", "broadcast", "specbot"],
+	'paul_dev_specbot' => %w(everyone broadcast specbot),
+	'paul_specbot' => %w(everyone broadcast specbot),
 	
-	"qw.nu" => ["everyone", "broadcast"],
-	"qw.nu_poster" => ["everyone", "broadcast"],
+	'qw.nu' => %w(everyone broadcast),
+	'qw.nu_poster' => %w(everyone broadcast),
 	
-	"mihawk_dev_specbot" => ["everyone", "broadcast", "specbot"],
-	"mihawk_specbot" => ["everyone", "broadcast", "specbot"],
+	'mihawk_dev_specbot' => %w(everyone broadcast specbot),
+	'mihawk_specbot' => %w(everyone broadcast specbot),
 	
-	"central_brain" => ["everyone", "broadcast_admin", "specbot_admin"],
-	]
+	'central_brain' => %w(everyone broadcast_admin specbot_admin),
+]
+
+$qw_server = Hash.new
+
+def string2bytearray(text)
+  return_array = Array.new
+  text.each_byte{
+    |b|
+    return_array.push(b)
+  }
+  return_array
+end
+
+def qwstatus(iphost, ipport)
+  udp_payload = [0xFF, 0xFF, 0xFF, 0xFF]
+  udp_payload.concat(string2bytearray("status 23"))
+  udp_payload.concat([0x0a]) # linefeed at the end
+
+  udp_payload = udp_payload.pack("C*")
+  #p udp_payload
+
+  u2 = UDPSocket.new
+  u2.send(udp_payload, 0, iphost, ipport)
+  the_return = u2.recv(1500)
+  u2.close
+
+  put_log "muh #{the_return}"
+  if the_return =~ /\W\W\W\Wn\\(.+)$/
+    line = $1
+    put_log "line #{line}"
+    matches = line.scan(/(.+?)\\(.+?)(\\|$)/)
+
+    the_hash = Hash.new
+    matches.each {
+      |k, v, _|
+      the_hash[k] = "#{v}"
+    }
+    return the_hash
+  else
+    return false
+  end
 
+end
+
+
+module HandleQwStatus
+  attr_accessor :received
 
+  def received
+    puts "lol: #{@data}"
+    @data
+  end
+  def receive_data(data)
+
+    puts "lal: #{data}"
+    @data = data
+
+    self.received
+  end
+end
 
-module InterconnectionPointProtocolHandler
+module CentralProtocolHandler
 	
 	@@connected_clients = Array.new
 	@@broadcasts = Hash.new
@@ -76,18 +137,19 @@ module InterconnectionPointProtocolHandler
 	end
 
 	def my_roles
-		return $user_roles[@username]
+		$user_roles[@username]
 	end
 
 	def my_cmds
-		return my_roles.collect {|v| $role_commands[v]}.flatten
+		my_roles.collect {|v| $role_commands[v]}.flatten
 	end
 
 	# returns online users by default by searching through saved connections
 	def ousers
 		users = Array.new
 		@@connected_clients.each {|c| users.push(c.username)}
-		return users
+
+		users
 	end # of ousers
 
 	### checkers
@@ -98,14 +160,15 @@ module InterconnectionPointProtocolHandler
 				return true
 			end
 		}
-		return false
+
+		false
 	end
 
 	def online(user)
 		if ousers.include? user
-			return true
+			true
 		else
-			return false
+			false
 		end
 	end
 
@@ -118,11 +181,12 @@ module InterconnectionPointProtocolHandler
 
 	# searches through our hash of saved connections and writes them a messages.
 	def	write_user(input, username = nil)
-		if not username
+		if username.nil? || username.empty?
 			username = @username
 		end
-		if connection = @@connected_clients.find { |c| c.username == username }
-			sometime = "#{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S %z")}"
+		if @@connected_clients.find { |c| c.username == username }
+      connection = @@connected_clients.find { |c| c.username == username }
+      sometime = "#{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S %z")}"
 			line = "#{sometime}: #{input}\n"
 			connection.send_data line
 		end
@@ -255,41 +319,49 @@ module InterconnectionPointProtocolHandler
           if source =~ /^qw:\/\/(.+):(\d+)(.*)$/
             # ip address is 15 in length
             iphost = $1
+            domainname = iphost # set a default
             ipport = $2
             rest = $3
 
             if iphost =~ /^\d+\.\d+\.\d+\.\d+/
+
               # find country code
               c = GeoIP.new('GeoIP.dat').country(iphost)[3].to_s.downcase
-              rest.prepend " #{c}" unless c.nil?
+              rest.prepend " #{c}" unless c.nil? || c.empty?
 
-              # resolve it to a dns name
+              # get hostname from a qw status packet! perhaps there's a DNS name inside, which we can use! fixme
+              hum = qwstatus(iphost, ipport)
+              if hum["hostname"] =~ /([\w\.]{3,}\.\w{2,4})/
+                hostnamedns = $1
+                ip_of_hostnamedns = Resolv.getaddress(hostnamedns)
 
-              domainname = Resolv.getname(iphost)
-
-
-              #domainname = ""
-              put_log "domainname: #{domainname}"
+                if ip_of_hostnamedns && (ip_of_hostnamedns == iphost)
+                  # ok, we take it.
+                  domainname = hostnamedns
+                end
 
-              if domainname.nil? || domainname.empty?
-                domainname = iphost
               else
-                put_log "domainname: #{domainname}"
-                # if the resulting dns ...
-                # .. is too long, use ip-address instead.
-                # .. has too many dots, use ip-address instead.
-                # .. has too many numbers, use ip-address instead.
-                if domainname.length > 21 || domainname.split(".").size > 3 || domainname.scan(/\d/).size > 3
-                  put_log "cutting down host_name: #{domainname}, because:"
-                  put_log "#{domainname.length}"
-                  put_log "#{domainname.split(".").size}"
-                  put_log "#{domainname.scan(/\d/).size}"
-
-                  domainname = iphost
-                end
+                # resolve it to a dns name
+                resulting_name = Resolv.getname(iphost)
+                if resulting_name
+                  # if the resulting dns name...
+                  # .. is too long, use ip-address instead.
+                  # .. has too many dots, use ip-address instead.
+                  # .. has too many numbers, use ip-address instead.
+                  if resulting_name.length > 21 || resulting_name.split(".").size > 3 || resulting_name.scan(/\d/).size > 3
+                    put_log "cutting down host_name: #{resulting_name}, because:"
+                    put_log "#{resulting_name.length}"
+                    put_log "#{resulting_name.split(".").size}"
+                    put_log "#{resulting_name.scan(/\d/).size}"
+                  else
+                    domainname = resulting_name
+                  end
+                end # of resolving
               end
-              source = "qw://#{domainname}:#{ipport}#{rest}"
-            end
+
+            end # if ip is x.x.x.x
+
+            source = "qw://#{domainname}:#{ipport}#{rest}"
           end # of if source qw://x.x.x.x:portzzz
 
           # resolve
@@ -380,9 +452,7 @@ module InterconnectionPointProtocolHandler
           @username = username
           @@connected_clients.push(self)
           @ping_timer = EventMachine.add_periodic_timer 90, proc { write_user("PING alive?") }
-
           # starting a pinger
-          write_user("HELLO Hi user '#{@username}'! How are you? I'm '#{$version}'")
 
           put_log("SYS '#{@username}' connected. Online now: #{ousers.join(", ")}")
 
@@ -423,11 +493,9 @@ end
 def main
 	# #run: Note that this will block current thread.
 	EventMachine.run do
+    EventMachine.start_server("0.0.0.0", 7337, CentralProtocolHandler)
+  end
 
-    f = Fiber.new do
-      EventMachine.start_server("0.0.0.0", 7337, InterconnectionPointProtocolHandler)
-    end.resume
-	end
 end
 
 main