|
@@ -5,13 +5,15 @@ require 'digest/md5'
|
|
require 'fiber'
|
|
require 'fiber'
|
|
require 'geoip'
|
|
require 'geoip'
|
|
require 'socket'
|
|
require 'socket'
|
|
|
|
+require 'timeout'
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# .. allowed commands .. ROLES = CAPABILITIES
|
|
# .. allowed commands .. ROLES = CAPABILITIES
|
|
# normal users have ROLE broadcast. Roles are defined on a per-user basis .. in a config.
|
|
# normal users have ROLE broadcast. Roles are defined on a per-user basis .. in a config.
|
|
|
|
|
|
-$version = "0.2EventMachineSocketServer"
|
|
|
|
|
|
+$version = "0.4em_cooldns_classes_for_caching"
|
|
$debug = 0
|
|
$debug = 0
|
|
|
|
|
|
$role_commands = Hash[
|
|
$role_commands = Hash[
|
|
@@ -22,7 +24,7 @@ $role_commands = Hash[
|
|
'broadcast' => %w(REQ_BC BC_RE),
|
|
'broadcast' => %w(REQ_BC BC_RE),
|
|
|
|
|
|
'specbot_admin' => %w(REQ_ASSIGN REQ_UNASSIGN REQ_PING REQ_ASSIGNMENTS),
|
|
'specbot_admin' => %w(REQ_ASSIGN REQ_UNASSIGN REQ_PING REQ_ASSIGNMENTS),
|
|
- 'specbot' => %w(ASSIGN_RE UNASSIGN_RE PING_RE ASSIGNMENTS_RE),
|
|
|
|
|
|
+ 'specbot' => %w(ASSIGN_RE UNASSIGN_RE PING_RE ASSIGNMENTS_RE REQ_DNS),
|
|
]
|
|
]
|
|
|
|
|
|
$default_role = "everyone"
|
|
$default_role = "everyone"
|
|
@@ -57,7 +59,564 @@ $user_roles = Hash[
|
|
'central_brain' => %w(everyone broadcast_admin specbot_admin),
|
|
'central_brain' => %w(everyone broadcast_admin specbot_admin),
|
|
]
|
|
]
|
|
|
|
|
|
-$qw_server = Hash.new
|
|
|
|
|
|
+
|
|
|
|
+$qw_list = Array.new
|
|
|
|
+$qw_list = [
|
|
|
|
+ "89.149.194.72:27700",
|
|
|
|
+ "84.200.47.113:30000",
|
|
|
|
+ "89.149.194.72:27500",
|
|
|
|
+ "84.200.47.113:28502",
|
|
|
|
+ "89.149.194.72:30000",
|
|
|
|
+ "89.149.194.72:27600",
|
|
|
|
+ "93.186.192.16:28502",
|
|
|
|
+ "84.200.47.113:28501",
|
|
|
|
+ "93.186.192.16:28501",
|
|
|
|
+ "188.40.130.10:27502",
|
|
|
|
+ "93.186.192.16:30000",
|
|
|
|
+ "188.40.130.10:27599",
|
|
|
|
+ "188.40.130.10:27503",
|
|
|
|
+ "194.109.69.75:28000",
|
|
|
|
+ "194.109.69.75:27500",
|
|
|
|
+ "194.109.69.75:27501",
|
|
|
|
+ "194.109.69.76:28504",
|
|
|
|
+ "188.165.243.56:30000",
|
|
|
|
+ "188.40.130.10:27501",
|
|
|
|
+ "194.109.69.76:28502",
|
|
|
|
+ "194.109.69.76:28501",
|
|
|
|
+ "194.109.69.76:28503",
|
|
|
|
+ "62.24.64.11:27501",
|
|
|
|
+ "62.24.64.11:44444",
|
|
|
|
+ "188.40.103.81:27600",
|
|
|
|
+ "62.24.64.11:30000",
|
|
|
|
+ "194.109.69.75:27502",
|
|
|
|
+ "91.121.69.201:30000",
|
|
|
|
+ "37.59.63.97:28504",
|
|
|
|
+ "188.40.130.10:27500",
|
|
|
|
+ "188.165.243.56:28009",
|
|
|
|
+ "37.59.63.97:28501",
|
|
|
|
+ "62.24.64.11:27500",
|
|
|
|
+ "37.59.63.97:28503",
|
|
|
|
+ "194.109.69.76:30000",
|
|
|
|
+ "188.165.243.56:28008",
|
|
|
|
+ "188.165.243.56:28006",
|
|
|
|
+ "188.165.243.56:28001",
|
|
|
|
+ "188.165.243.56:28002",
|
|
|
|
+ "93.186.192.16:27500",
|
|
|
|
+ "91.121.69.201:27600",
|
|
|
|
+ "37.59.63.97:28502",
|
|
|
|
+ "91.121.223.163:28001",
|
|
|
|
+ "188.165.243.56:28003",
|
|
|
|
+ "109.74.195.224:30000",
|
|
|
|
+ "178.79.183.178:27500",
|
|
|
|
+ "77.74.194.189:27501",
|
|
|
|
+ "91.121.69.201:27502",
|
|
|
|
+ "188.165.243.56:28007",
|
|
|
|
+ "109.74.195.224:27500",
|
|
|
|
+ "213.5.176.135:27502",
|
|
|
|
+ "77.74.194.189:27504",
|
|
|
|
+ "178.79.172.251:27600",
|
|
|
|
+ "77.74.194.189:27502",
|
|
|
|
+ "77.74.194.189:27503",
|
|
|
|
+ "213.5.176.135:27500",
|
|
|
|
+ "109.74.195.224:27501",
|
|
|
|
+ "89.104.194.146:27504",
|
|
|
|
+ "89.104.194.146:27503",
|
|
|
|
+ "89.104.194.146:27508",
|
|
|
|
+ "213.5.176.136:27510",
|
|
|
|
+ "213.5.176.135:27501",
|
|
|
|
+ "213.5.176.135:27503",
|
|
|
|
+ "77.74.194.189:30000",
|
|
|
|
+ "89.149.194.72:27800",
|
|
|
|
+ "89.104.194.146:27502",
|
|
|
|
+ "89.104.194.146:27666",
|
|
|
|
+ "89.104.194.146:27507",
|
|
|
|
+ "89.104.194.146:27509",
|
|
|
|
+ "89.104.194.146:30000",
|
|
|
|
+ "188.165.243.56:28004",
|
|
|
|
+ "89.104.194.146:27500",
|
|
|
|
+ "89.104.194.146:27501",
|
|
|
|
+ "194.109.69.76:27500",
|
|
|
|
+ "89.104.194.146:27506",
|
|
|
|
+ "94.236.92.49:27501",
|
|
|
|
+ "91.121.69.201:27501",
|
|
|
|
+ "213.239.214.134:27500",
|
|
|
|
+ "89.104.194.146:27510",
|
|
|
|
+ "95.131.48.86:27502",
|
|
|
|
+ "94.236.92.49:27500",
|
|
|
|
+ "94.236.92.49:30000",
|
|
|
|
+ "95.131.48.86:27504",
|
|
|
|
+ "78.137.161.109:27501",
|
|
|
|
+ "188.165.243.56:28005",
|
|
|
|
+ "178.217.185.104:27500",
|
|
|
|
+ "178.217.185.104:27600",
|
|
|
|
+ "178.217.185.104:30000",
|
|
|
|
+ "87.102.202.23:27502",
|
|
|
|
+ "78.137.161.109:27500",
|
|
|
|
+ "89.104.194.146:27505",
|
|
|
|
+ "87.102.202.23:27505",
|
|
|
|
+ "178.217.185.104:27501",
|
|
|
|
+ "91.121.69.201:27500",
|
|
|
|
+ "82.141.152.3:27501",
|
|
|
|
+ "82.141.152.3:27500",
|
|
|
|
+ "83.179.23.16:28002",
|
|
|
|
+ "109.74.7.60:27500",
|
|
|
|
+ "212.62.234.153:27502",
|
|
|
|
+ "83.179.23.16:28003",
|
|
|
|
+ "195.54.182.34:27500",
|
|
|
|
+ "83.179.23.16:28005",
|
|
|
|
+ "212.62.234.153:27503",
|
|
|
|
+ "95.143.243.24:27600",
|
|
|
|
+ "83.179.23.16:28001",
|
|
|
|
+ "212.62.234.153:27504",
|
|
|
|
+ "78.137.161.109:27502",
|
|
|
|
+ "83.179.23.16:28004",
|
|
|
|
+ "212.62.234.153:27501",
|
|
|
|
+ "95.143.243.24:27500",
|
|
|
|
+ "109.228.137.161:28501",
|
|
|
|
+ "95.143.243.24:27900",
|
|
|
|
+ "83.226.149.218:27500",
|
|
|
|
+ "83.226.149.218:28001",
|
|
|
|
+ "83.226.149.218:28002",
|
|
|
|
+ "83.226.149.218:28003",
|
|
|
|
+ "193.1.40.166:27975",
|
|
|
|
+ "87.237.112.11:30000",
|
|
|
|
+ "217.30.184.104:27500",
|
|
|
|
+ "78.108.53.19:27500",
|
|
|
|
+ "78.108.53.19:27501",
|
|
|
|
+ "195.54.142.7:28001",
|
|
|
|
+ "193.1.40.166:27500",
|
|
|
|
+ "87.237.112.11:27501",
|
|
|
|
+ "195.54.142.7:30000",
|
|
|
|
+ "195.54.142.7:28007",
|
|
|
|
+ "217.119.36.79:30000",
|
|
|
|
+ "95.131.48.86:27501",
|
|
|
|
+ "195.54.142.7:28002",
|
|
|
|
+ "195.54.142.7:28008",
|
|
|
|
+ "80.101.105.103:27500",
|
|
|
|
+ "87.237.112.11:27502",
|
|
|
|
+ "217.119.36.79:27500",
|
|
|
|
+ "81.170.128.75:28501",
|
|
|
|
+ "217.119.36.79:28001",
|
|
|
|
+ "193.1.40.167:27500",
|
|
|
|
+ "217.119.36.79:28003",
|
|
|
|
+ "217.119.36.79:28002",
|
|
|
|
+ "81.170.128.75:30000",
|
|
|
|
+ "81.170.128.75:28504",
|
|
|
|
+ "195.54.142.7:28005",
|
|
|
|
+ "195.54.142.7:28010",
|
|
|
|
+ "81.170.128.75:28503",
|
|
|
|
+ "93.81.254.63:27502",
|
|
|
|
+ "212.42.38.88:27504",
|
|
|
|
+ "81.170.128.75:28502",
|
|
|
|
+ "93.81.254.63:27500",
|
|
|
|
+ "81.170.128.75:28000",
|
|
|
|
+ "212.42.38.88:27500",
|
|
|
|
+ "82.203.213.117:28002",
|
|
|
|
+ "212.42.38.88:30000",
|
|
|
|
+ "93.81.254.63:30000",
|
|
|
|
+ "82.203.213.117:28001",
|
|
|
|
+ "212.42.38.88:27501",
|
|
|
|
+ "212.42.38.88:27503",
|
|
|
|
+ "93.81.254.63:27503",
|
|
|
|
+ "93.81.254.63:27501",
|
|
|
|
+ "82.203.213.117:30000",
|
|
|
|
+ "95.131.48.86:27503",
|
|
|
|
+ "83.252.244.76:27500",
|
|
|
|
+ "212.42.38.88:27502",
|
|
|
|
+ "195.54.142.7:28003",
|
|
|
|
+ "95.31.4.132:30000",
|
|
|
|
+ "83.252.244.76:27501",
|
|
|
|
+ "93.81.254.63:30001",
|
|
|
|
+ "195.54.142.7:28006",
|
|
|
|
+ "82.203.213.117:28003",
|
|
|
|
+ "95.143.243.24:27700",
|
|
|
|
+ "84.234.185.215:27503",
|
|
|
|
+ "84.234.185.215:27500",
|
|
|
|
+ "84.234.185.215:27519",
|
|
|
|
+ "84.234.185.215:27508",
|
|
|
|
+ "84.234.185.215:27506",
|
|
|
|
+ "84.234.185.215:27505",
|
|
|
|
+ "195.54.142.7:28004",
|
|
|
|
+ "84.234.185.215:27501",
|
|
|
|
+ "195.54.142.7:28009",
|
|
|
|
+ "212.109.128.148:27501",
|
|
|
|
+ "84.234.185.215:27502",
|
|
|
|
+ "31.209.7.104:28501",
|
|
|
|
+ "194.79.85.66:27501",
|
|
|
|
+ "194.79.85.66:30000",
|
|
|
|
+ "95.84.164.245:27501",
|
|
|
|
+ "194.79.85.66:27502",
|
|
|
|
+ "83.222.112.157:30000",
|
|
|
|
+ "212.109.128.148:27500",
|
|
|
|
+ "94.100.6.66:27500",
|
|
|
|
+ "129.241.205.153:28000",
|
|
|
|
+ "84.234.185.215:27507",
|
|
|
|
+ "129.241.205.153:27500",
|
|
|
|
+ "95.84.164.245:27500",
|
|
|
|
+ "69.31.82.226:27501",
|
|
|
|
+ "69.31.82.226:30000",
|
|
|
|
+ "130.240.207.177:30000",
|
|
|
|
+ "69.31.82.226:28100",
|
|
|
|
+ "69.31.82.226:27500",
|
|
|
|
+ "69.31.82.226:28101",
|
|
|
|
+ "69.31.82.226:28010",
|
|
|
|
+ "69.31.82.226:30001",
|
|
|
|
+ "69.31.82.226:28000",
|
|
|
|
+ "69.31.82.226:28002",
|
|
|
|
+ "93.186.192.16:28000",
|
|
|
|
+ "195.222.130.83:27500",
|
|
|
|
+ "84.200.47.113:28000",
|
|
|
|
+ "130.85.56.131:27500",
|
|
|
|
+ "108.174.51.73:28003",
|
|
|
|
+ "96.8.113.36:27501",
|
|
|
|
+ "96.8.113.36:27500",
|
|
|
|
+ "68.100.130.114:27501",
|
|
|
|
+ "65.31.69.75:27500",
|
|
|
|
+ "108.174.51.73:28006",
|
|
|
|
+ "65.31.69.75:27508",
|
|
|
|
+ "108.174.51.73:30000",
|
|
|
|
+ "67.81.59.41:27500",
|
|
|
|
+ "108.174.51.73:28004",
|
|
|
|
+ "217.18.138.23:27505",
|
|
|
|
+ "108.174.51.73:28001",
|
|
|
|
+ "68.100.130.114:27500",
|
|
|
|
+ "174.49.198.60:27502",
|
|
|
|
+ "174.49.198.60:27503",
|
|
|
|
+ "209.239.113.236:27500",
|
|
|
|
+ "174.49.198.60:27515",
|
|
|
|
+ "217.119.36.79:28000",
|
|
|
|
+ "108.174.51.73:28005",
|
|
|
|
+ "74.91.115.244:28001",
|
|
|
|
+ "174.49.198.60:27500",
|
|
|
|
+ "74.91.115.244:28000",
|
|
|
|
+ "199.101.96.48:27501",
|
|
|
|
+ "96.8.113.36:30000",
|
|
|
|
+ "174.101.185.59:27500",
|
|
|
|
+ "67.228.69.114:27502",
|
|
|
|
+ "199.101.96.48:27500",
|
|
|
|
+ "108.174.51.73:28002",
|
|
|
|
+ "199.192.229.74:28001",
|
|
|
|
+ "74.86.171.201:27502",
|
|
|
|
+ "67.228.69.114:27501",
|
|
|
|
+ "74.86.171.201:27500",
|
|
|
|
+ "67.228.69.114:26666",
|
|
|
|
+ "199.192.228.71:27501",
|
|
|
|
+ "199.192.229.74:28003",
|
|
|
|
+ "74.86.171.201:27501",
|
|
|
|
+ "199.192.229.74:30000",
|
|
|
|
+ "199.192.229.74:28002",
|
|
|
|
+ "74.91.115.244:28002",
|
|
|
|
+ "199.192.228.71:27500",
|
|
|
|
+ "199.101.96.48:30000",
|
|
|
|
+ "199.101.96.48:28000",
|
|
|
|
+ "199.192.229.74:28004",
|
|
|
|
+ "199.192.228.71:30000",
|
|
|
|
+ "65.31.238.37:27500",
|
|
|
|
+ "31.209.7.104:28000",
|
|
|
|
+ "208.131.136.169:27500",
|
|
|
|
+ "66.212.17.78:27500",
|
|
|
|
+ "200.177.229.11:27510",
|
|
|
|
+ "200.177.229.11:27522",
|
|
|
|
+ "200.177.229.11:27521",
|
|
|
|
+ "200.177.229.11:27500",
|
|
|
|
+ "190.96.80.67:27500",
|
|
|
|
+ "200.177.229.11:27511",
|
|
|
|
+ "200.177.229.11:27520",
|
|
|
|
+ "190.96.80.67:27000",
|
|
|
|
+ "202.37.129.186:27500",
|
|
|
|
+ "202.37.129.186:27505",
|
|
|
|
+ "202.37.129.186:27501",
|
|
|
|
+ "219.88.241.81:27500",
|
|
|
|
+ "202.172.99.2:28001",
|
|
|
|
+ "202.172.99.2:28002",
|
|
|
|
+ "202.172.99.2:28003",
|
|
|
|
+ "202.172.99.2:27500",
|
|
|
|
+ "210.50.4.11:27501",
|
|
|
|
+ "202.172.99.2:27501",
|
|
|
|
+ "210.50.4.11:27508",
|
|
|
|
+ "210.50.4.11:27511",
|
|
|
|
+ "210.50.4.11:27509",
|
|
|
|
+ "210.50.4.11:27510",
|
|
|
|
+ "122.99.118.2:28001",
|
|
|
|
+ "210.50.4.11:27500",
|
|
|
|
+ "210.50.4.11:27503",
|
|
|
|
+ "210.50.4.11:27506",
|
|
|
|
+ "210.50.4.11:27505",
|
|
|
|
+ "210.50.4.11:27504",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class GameServers
|
|
|
|
+
|
|
|
|
+ attr_accessor :gameservers # now, @gameservers is accessible via GameServers.gameservers
|
|
|
|
+
|
|
|
|
+ def initialize
|
|
|
|
+
|
|
|
|
+ @gameservers = Hash.new
|
|
|
|
+ @gameservers.default = {
|
|
|
|
+ :reverse_dns => "",
|
|
|
|
+ :hostname_dns => "",
|
|
|
|
+ :cool_dns => "",
|
|
|
|
+ :type => "",
|
|
|
|
+ :serverinfos => "",
|
|
|
|
+ :timestamp => 0,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @gameservers["blah:blah"]
|
|
|
|
+
|
|
|
|
+ wat = Hash.new(@gameservers["blah:blah"])
|
|
|
|
+ wat
|
|
|
|
+ wat.store(:reverse_dns, "6")
|
|
|
|
+ @gameservers.merge(wat)
|
|
|
|
+
|
|
|
|
+ p @gameservers
|
|
|
|
+ p @gameservers.default
|
|
|
|
+
|
|
|
|
+ wat = Hash.new(@gameservers["blah:blah"])
|
|
|
|
+ wat
|
|
|
|
+ wat.store(:hostname_dns, "12")
|
|
|
|
+ @gameservers.merge(wat)
|
|
|
|
+
|
|
|
|
+ p @gameservers
|
|
|
|
+ p @gameservers.default
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def scanserver(iphostport, type="qw", force=false)
|
|
|
|
+ put_log "scanserver drin"
|
|
|
|
+ if iphostport =~ /^(\d+\.\d+\.\d+\.\d+):(\d{1,5})/
|
|
|
|
+ iphost = $1
|
|
|
|
+ ipport = $2
|
|
|
|
+
|
|
|
|
+ if type == "qw"
|
|
|
|
+ #p current
|
|
|
|
+
|
|
|
|
+ # check if it already exists
|
|
|
|
+
|
|
|
|
+ #if @gameservers["#{iphost}:#{ipport}"][:timestamp] > 0
|
|
|
|
+
|
|
|
|
+ # if old general data, then freshly get general data...
|
|
|
|
+ # if @gameservers["#{iphost}:#{ipport}"][:timestamp] + 60 * 60 * 20 < Time.now.utc.to_i || force == true
|
|
|
|
+ # end # of old
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ #else
|
|
|
|
+ current = Hash.new
|
|
|
|
+
|
|
|
|
+ serverinfos = qwstatus(iphost, ipport)
|
|
|
|
+
|
|
|
|
+ current.store(:serverinfos, serverinfos)
|
|
|
|
+ current.store(:reverse_dns, find_reverse_dname(iphost))
|
|
|
|
+ current.store(:hostname_dns, qw_find_dname_by_serverinfos(serverinfos))
|
|
|
|
+ current.store(:type, "qw")
|
|
|
|
+ # set new timestamp
|
|
|
|
+ current.store(:timestamp, Time.now.utc.to_i)
|
|
|
|
+ @gameservers.store("#{iphost}:#{ipport}", current) # save it all.
|
|
|
|
+
|
|
|
|
+ current.store(:cool_dns, find_cooldns(iphost, ipport))
|
|
|
|
+ @gameservers.store("#{iphost}:#{ipport}", current) # save it all.
|
|
|
|
+
|
|
|
|
+ #put_log "the saved one: #{@gameservers.fetch("#{iphost}:#{ipport}").fetch(:cool_dns)}"
|
|
|
|
+
|
|
|
|
+ #puts "ALL"
|
|
|
|
+ #p @gameservers
|
|
|
|
+ #puts "DEFAULT of the hash"
|
|
|
|
+ #p @gameservers.default
|
|
|
|
+
|
|
|
|
+ #end
|
|
|
|
+ end # of type qw
|
|
|
|
+ end # of check form of iphostport parameter
|
|
|
|
+ end # of scan()
|
|
|
|
+
|
|
|
|
+ def scanserverlist(gs_array, type="qw")
|
|
|
|
+ put_log "scanserverlist drin"
|
|
|
|
+ gs_array.each do
|
|
|
|
+ |gserver|
|
|
|
|
+ scanserver(gserver, type)
|
|
|
|
+ end
|
|
|
|
+ put_log "End of scanning."
|
|
|
|
+ put_log "foppa: #{@gameservers.fetch("89.104.194.146:27503")} "
|
|
|
|
+ end # of scanserverlist()
|
|
|
|
+
|
|
|
|
+ def get_cool_dns(iphost, ipport)
|
|
|
|
+ put_log "get_cool_dns drin"
|
|
|
|
+ @gameservers.fetch("#{iphost}:#{ipport}").fetch(:cool_dns)
|
|
|
|
+ rescue
|
|
|
|
+ scanserver("#{iphost}:#{ipport}", "qw")
|
|
|
|
+ @gameservers.fetch("#{iphost}:#{ipport}").fetch(:cool_dns)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ private # all following methods are private
|
|
|
|
+ # returns serverinfo hash
|
|
|
|
+ def qwstatus(iphost, ipport)
|
|
|
|
+ put_log "qwstatus drin"
|
|
|
|
+ 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
|
|
|
|
+
|
|
|
|
+ Timeout::timeout(2) do
|
|
|
|
+ begin
|
|
|
|
+ u2 = UDPSocket.new
|
|
|
|
+ #put_log "#{iphost} #{ipport} #{udp_payload}"
|
|
|
|
+ u2.send(udp_payload, 0, iphost, ipport)
|
|
|
|
+ #put_log "sent"
|
|
|
|
+
|
|
|
|
+ the_return = u2.recv(500)
|
|
|
|
+
|
|
|
|
+ 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
|
|
|
|
+
|
|
|
|
+ rescue Exception => e
|
|
|
|
+ puts e.message
|
|
|
|
+ end # of begin
|
|
|
|
+ end # of Timeout
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def find_cooldns_full(iphost, ipport)
|
|
|
|
+ targetname = iphost
|
|
|
|
+ # resolve it to a dns name (reverse lookup)
|
|
|
|
+ if targetname == iphost # if it is still default
|
|
|
|
+ put_log "Ip not resolved .. we try hostname dns finder"
|
|
|
|
+ targetname = qw_find_dname_in_hostnames(iphost, ipport)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ # resolve it to a dns name (reverse lookup)
|
|
|
|
+ if targetname == iphost
|
|
|
|
+ put_log "Still no resolve .. we try reverse dns lookup"
|
|
|
|
+ targetname = find_reverse_dname(iphost)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ return targetname
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def find_cooldns(iphost, ipport)
|
|
|
|
+ put_log "find_cooldns drin"
|
|
|
|
+ current = @gameservers["#{iphost}:#{ipport}"] # only use this for reading...
|
|
|
|
+
|
|
|
|
+ my_cooldns = iphost
|
|
|
|
+
|
|
|
|
+ # we still haven't found a cool dns
|
|
|
|
+ if (my_cooldns == iphost) && (not current[:hostname_dns].to_s.empty?)
|
|
|
|
+ put_log "Try if #{current[:hostname_dns]} resolves to #{iphost}"
|
|
|
|
+ begin
|
|
|
|
+ ip_of_hostnamedns = Resolv.getaddress(current[:hostname_dns])
|
|
|
|
+ if ip_of_hostnamedns && (ip_of_hostnamedns == iphost)
|
|
|
|
+ # ok, we take it.
|
|
|
|
+ put_log "Ok, we take #{current[:hostname_dns]} for #{iphost} here.."
|
|
|
|
+ my_cooldns = current[:hostname_dns]
|
|
|
|
+ else
|
|
|
|
+ put_log "Found #{current[:hostname_dns]} but #{ip_of_hostnamedns} is not #{iphost}"
|
|
|
|
+ end
|
|
|
|
+ rescue Exception => e
|
|
|
|
+ my_cooldns = iphost
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ # we still haven't found a cool dns
|
|
|
|
+ if (my_cooldns == iphost) && (not current[:reverse_dns].empty?)
|
|
|
|
+
|
|
|
|
+ rdns = current[:reverse_dns]
|
|
|
|
+
|
|
|
|
+ # 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 rdns.length > 21 || rdns.split(".").size > 3 || rdns.scan(/\d/).size > 3
|
|
|
|
+ put_log "cutting down host_name: #{rdns}, because:"
|
|
|
|
+ put_log "length: #{rdns.length}"
|
|
|
|
+ put_log "chunks count: #{rdns.split(".").size}"
|
|
|
|
+ put_log "num count: #{rdns.scan(/\d/).size}"
|
|
|
|
+ else
|
|
|
|
+ my_cooldns = rdns
|
|
|
|
+ end # of Resolv.getname
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ put_log "COOOOOOOOOOOOLDNS: #{my_cooldns}"
|
|
|
|
+
|
|
|
|
+ my_cooldns
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ def find_reverse_dname(iphost)
|
|
|
|
+ put_log "find_reverse_dname drin"
|
|
|
|
+ Resolv.getname(iphost)
|
|
|
|
+ rescue
|
|
|
|
+ iphost
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def qw_find_dname_by_udp(iphost, ipport)
|
|
|
|
+ targetname = iphost # set a default
|
|
|
|
+
|
|
|
|
+ # get hostname from a qw status packet! perhaps there's a DNS name inside, which we can use!
|
|
|
|
+ status = qwstatus(iphost, ipport)
|
|
|
|
+ p status
|
|
|
|
+
|
|
|
|
+ if status["hostname"] =~ /([\w\.-]{3,}\.\w{2,4})/
|
|
|
|
+ hostnamedns = $1.downcase
|
|
|
|
+
|
|
|
|
+ begin
|
|
|
|
+ ip_of_hostnamedns = Resolv.getaddress(hostnamedns)
|
|
|
|
+ if ip_of_hostnamedns && (ip_of_hostnamedns == iphost)
|
|
|
|
+ # ok, we take it.
|
|
|
|
+ put_log "Ok, we take #{hostnamedns} for #{iphost} here.."
|
|
|
|
+ targetname = hostnamedns
|
|
|
|
+ else
|
|
|
|
+ put_log "Found #{hostnamedns} but #{ip_of_hostnamedns} is not #{iphost}"
|
|
|
|
+ end
|
|
|
|
+ rescue Exception => e
|
|
|
|
+ targetname = iphost
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ targetname
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def qw_find_dname_by_serverinfos(serverinfos)
|
|
|
|
+ hostnamedns = ""
|
|
|
|
+ begin
|
|
|
|
+ hostname = serverinfos.fetch("hostname")
|
|
|
|
+
|
|
|
|
+ if hostname =~ /([\w\.-]{3,}\.\w{2,4})/
|
|
|
|
+ hostnamedns = $1.downcase
|
|
|
|
+ end
|
|
|
|
+ return hostnamedns
|
|
|
|
+
|
|
|
|
+ rescue
|
|
|
|
+ return ""
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+end # of Class GameServers!
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
def string2bytearray(text)
|
|
def string2bytearray(text)
|
|
return_array = Array.new
|
|
return_array = Array.new
|
|
@@ -68,60 +627,24 @@ def string2bytearray(text)
|
|
return_array
|
|
return_array
|
|
end
|
|
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
|
|
|
|
-
|
|
|
|
|
|
+def put_log(msg)
|
|
|
|
+ puts "#{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")}: #{msg}"
|
|
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 CentralProtocolHandler
|
|
module CentralProtocolHandler
|
|
|
|
|
|
@@connected_clients = Array.new
|
|
@@connected_clients = Array.new
|
|
@@broadcasts = Hash.new
|
|
@@broadcasts = Hash.new
|
|
|
|
+ put_log "Server started"
|
|
|
|
+
|
|
|
|
|
|
- # default method that is being run on connection!
|
|
|
|
|
|
+
|
|
|
|
+ # default method that is being run on connection!
|
|
def post_init # connection of someone starts here...
|
|
def post_init # connection of someone starts here...
|
|
@username = nil
|
|
@username = nil
|
|
end
|
|
end
|
|
@@ -175,10 +698,6 @@ module CentralProtocolHandler
|
|
|
|
|
|
|
|
|
|
### actions
|
|
### actions
|
|
- def put_log(msg)
|
|
|
|
- puts "#{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")}: #{msg}"
|
|
|
|
- end
|
|
|
|
-
|
|
|
|
# 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 username.nil? || username.empty?
|
|
if username.nil? || username.empty?
|
|
@@ -301,10 +820,10 @@ module CentralProtocolHandler
|
|
error = 1
|
|
error = 1
|
|
end
|
|
end
|
|
|
|
|
|
- else # of check syntax
|
|
|
|
|
|
+ else # of payload has format
|
|
write_user("SYS Command format is REQ_BC <network>,<frequency>,<source/channel>,'<nickname>','<message>'")
|
|
write_user("SYS Command format is REQ_BC <network>,<frequency>,<source/channel>,'<nickname>','<message>'")
|
|
error = 1
|
|
error = 1
|
|
- end
|
|
|
|
|
|
+ end # of payload has format
|
|
|
|
|
|
if error == 0
|
|
if error == 0
|
|
|
|
|
|
@@ -329,46 +848,7 @@ module CentralProtocolHandler
|
|
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? || c.empty?
|
|
rest.prepend " #{c}" unless c.nil? || c.empty?
|
|
|
|
|
|
-
|
|
|
|
- # resolve it to a dns name (reverse lookup)
|
|
|
|
- if targetname == iphost # if it is still default
|
|
|
|
- put_log "Ip not resolved .. we try hostname dns finder"
|
|
|
|
- # get hostname from a qw status packet! perhaps there's a DNS name inside, which we can use! fixme
|
|
|
|
- status = qwstatus(iphost, ipport)
|
|
|
|
- p status
|
|
|
|
- if status["hostname"] =~ /([\w\.]{3,}\.\w{2,4})/
|
|
|
|
- hostnamedns = $1.downcase
|
|
|
|
- ip_of_hostnamedns = Resolv.getaddress(hostnamedns)
|
|
|
|
- if ip_of_hostnamedns && (ip_of_hostnamedns == iphost)
|
|
|
|
- # ok, we take it.
|
|
|
|
- put_log "Ok, we take #{hostnamedns} for #{iphost} here.."
|
|
|
|
- targetname = hostnamedns
|
|
|
|
- else
|
|
|
|
- put_log "Found #{hostnamedns} but #{ip_of_hostnamedns} is not #{iphost}"
|
|
|
|
- end
|
|
|
|
- end
|
|
|
|
- end
|
|
|
|
-
|
|
|
|
- # resolve it to a dns name (reverse lookup)
|
|
|
|
- if targetname == iphost # if it is still default
|
|
|
|
- put_log "Still no resolve .. we try reverse dns lookup"
|
|
|
|
- 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
|
|
|
|
- targetname = resulting_name
|
|
|
|
- end # of Resolv.getname
|
|
|
|
- end
|
|
|
|
-
|
|
|
|
- end
|
|
|
|
|
|
+ targetname = $gs.get_cool_dns(iphost, ipport)
|
|
|
|
|
|
end # if ip is x.x.x.x
|
|
end # if ip is x.x.x.x
|
|
|
|
|
|
@@ -381,9 +861,26 @@ module CentralProtocolHandler
|
|
|
|
|
|
|
|
|
|
end
|
|
end
|
|
- #end of REQ_BC here..
|
|
|
|
|
|
+ #end of REQ_BC here..
|
|
|
|
|
|
- elsif cmd == "BC_RE"
|
|
|
|
|
|
+ elsif cmd == "REQ_DNS"
|
|
|
|
+ # help with format .. but send the raw payload
|
|
|
|
+ if payload =~ /^(\d+\.\d+\.\d+\.\d+):(\d{1,5})/
|
|
|
|
+ iphost = $1
|
|
|
|
+ ipport = $2
|
|
|
|
+
|
|
|
|
+ targetname = $gs.get_cool_dns(iphost, ipport)
|
|
|
|
+
|
|
|
|
+ write_user("DNS_RE #{iphost}:#{ipport} #{targetname}") # write back to asking user.
|
|
|
|
+
|
|
|
|
+ else # of payload has format
|
|
|
|
+ write_user("SYS Command format is REQ_DNS <serverip>:<serverport>")
|
|
|
|
+ error = 1
|
|
|
|
+ end # of if payload has format
|
|
|
|
+ #end of REQ_DNS here..
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ elsif cmd == "BC_RE"
|
|
|
|
|
|
if payload =~ /^(.+) (.+)=(\d+),(.+)=(\d+)$/
|
|
if payload =~ /^(.+) (.+)=(\d+),(.+)=(\d+)$/
|
|
|
|
|
|
@@ -499,34 +996,30 @@ module CentralProtocolHandler
|
|
end
|
|
end
|
|
end
|
|
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.start_server("0.0.0.0", 7337, CentralProtocolHandler)
|
|
|
|
- end
|
|
|
|
-
|
|
|
|
-end
|
|
|
|
-
|
|
|
|
-main
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+ $gs = GameServers.new
|
|
|
|
|
|
|
|
+ EventMachine.run do
|
|
|
|
|
|
|
|
+ # initial scan
|
|
|
|
+ EM.defer do
|
|
|
|
+ $gs.scanserverlist($qw_list, "qw") # initial scan
|
|
|
|
+ end
|
|
|
|
|
|
|
|
+ # periodic scan, 20 hours
|
|
|
|
+ EventMachine.add_periodic_timer( 60 * 60 * 20 ) {
|
|
|
|
+ EM.defer do
|
|
|
|
+ $gs.scanserverlist($qw_list, "qw") # initial scan
|
|
|
|
+ end
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ EventMachine.start_server("0.0.0.0", 7337, CentralProtocolHandler)
|
|
|
|
+ end
|
|
|
|
|
|
|
|
+end
|
|
|
|
|
|
|
|
+main
|
|
|
|
|
|
|
|
|