|
@@ -4,6 +4,7 @@ require 'eventmachine'
|
|
require 'digest/md5'
|
|
require 'digest/md5'
|
|
require 'fiber'
|
|
require 'fiber'
|
|
require 'geoip'
|
|
require 'geoip'
|
|
|
|
+require 'socket'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -14,48 +15,108 @@ $version = "0.2EventMachineSocketServer"
|
|
$debug = 0
|
|
$debug = 0
|
|
|
|
|
|
$role_commands = Hash[
|
|
$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"
|
|
$default_role = "everyone"
|
|
|
|
|
|
# which role is talking to which role?
|
|
# 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.
|
|
# 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[
|
|
$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[
|
|
$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
|
|
@@connected_clients = Array.new
|
|
@@broadcasts = Hash.new
|
|
@@broadcasts = Hash.new
|
|
@@ -76,18 +137,19 @@ module InterconnectionPointProtocolHandler
|
|
end
|
|
end
|
|
|
|
|
|
def my_roles
|
|
def my_roles
|
|
- return $user_roles[@username]
|
|
|
|
|
|
+ $user_roles[@username]
|
|
end
|
|
end
|
|
|
|
|
|
def my_cmds
|
|
def my_cmds
|
|
- return my_roles.collect {|v| $role_commands[v]}.flatten
|
|
|
|
|
|
+ my_roles.collect {|v| $role_commands[v]}.flatten
|
|
end
|
|
end
|
|
|
|
|
|
# returns online users by default by searching through saved connections
|
|
# returns online users by default by searching through saved connections
|
|
def ousers
|
|
def ousers
|
|
users = Array.new
|
|
users = Array.new
|
|
@@connected_clients.each {|c| users.push(c.username)}
|
|
@@connected_clients.each {|c| users.push(c.username)}
|
|
- return users
|
|
|
|
|
|
+
|
|
|
|
+ users
|
|
end # of ousers
|
|
end # of ousers
|
|
|
|
|
|
### checkers
|
|
### checkers
|
|
@@ -98,14 +160,15 @@ module InterconnectionPointProtocolHandler
|
|
return true
|
|
return true
|
|
end
|
|
end
|
|
}
|
|
}
|
|
- return false
|
|
|
|
|
|
+
|
|
|
|
+ false
|
|
end
|
|
end
|
|
|
|
|
|
def online(user)
|
|
def online(user)
|
|
if ousers.include? user
|
|
if ousers.include? user
|
|
- return true
|
|
|
|
|
|
+ true
|
|
else
|
|
else
|
|
- return false
|
|
|
|
|
|
+ false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
@@ -118,11 +181,12 @@ module InterconnectionPointProtocolHandler
|
|
|
|
|
|
# searches through our hash of saved connections and writes them a messages.
|
|
# searches through our hash of saved connections and writes them a messages.
|
|
def write_user(input, username = nil)
|
|
def write_user(input, username = nil)
|
|
- if not username
|
|
|
|
|
|
+ if username.nil? || username.empty?
|
|
username = @username
|
|
username = @username
|
|
end
|
|
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"
|
|
line = "#{sometime}: #{input}\n"
|
|
connection.send_data line
|
|
connection.send_data line
|
|
end
|
|
end
|
|
@@ -255,41 +319,49 @@ module InterconnectionPointProtocolHandler
|
|
if source =~ /^qw:\/\/(.+):(\d+)(.*)$/
|
|
if source =~ /^qw:\/\/(.+):(\d+)(.*)$/
|
|
# ip address is 15 in length
|
|
# ip address is 15 in length
|
|
iphost = $1
|
|
iphost = $1
|
|
|
|
+ domainname = iphost # set a default
|
|
ipport = $2
|
|
ipport = $2
|
|
rest = $3
|
|
rest = $3
|
|
|
|
|
|
if iphost =~ /^\d+\.\d+\.\d+\.\d+/
|
|
if iphost =~ /^\d+\.\d+\.\d+\.\d+/
|
|
|
|
+
|
|
# find country code
|
|
# find country code
|
|
c = GeoIP.new('GeoIP.dat').country(iphost)[3].to_s.downcase
|
|
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
|
|
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
|
|
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
|
|
end # of if source qw://x.x.x.x:portzzz
|
|
|
|
|
|
# resolve
|
|
# resolve
|
|
@@ -380,9 +452,7 @@ module InterconnectionPointProtocolHandler
|
|
@username = username
|
|
@username = username
|
|
@@connected_clients.push(self)
|
|
@@connected_clients.push(self)
|
|
@ping_timer = EventMachine.add_periodic_timer 90, proc { write_user("PING alive?") }
|
|
@ping_timer = EventMachine.add_periodic_timer 90, proc { write_user("PING alive?") }
|
|
-
|
|
|
|
# starting a pinger
|
|
# starting a pinger
|
|
- write_user("HELLO Hi user '#{@username}'! How are you? I'm '#{$version}'")
|
|
|
|
|
|
|
|
put_log("SYS '#{@username}' connected. Online now: #{ousers.join(", ")}")
|
|
put_log("SYS '#{@username}' connected. Online now: #{ousers.join(", ")}")
|
|
|
|
|
|
@@ -423,11 +493,9 @@ end
|
|
def main
|
|
def main
|
|
# #run: Note that this will block current thread.
|
|
# #run: Note that this will block current thread.
|
|
EventMachine.run do
|
|
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
|
|
end
|
|
|
|
|
|
main
|
|
main
|