mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2026-09-19 23:03:53 +00:00
Implemented unprivileged UDP based ICMP echo requests for pinging game server hosts
This commit is contained in:
@@ -29,11 +29,15 @@ module W3DHubLauncher
|
||||
@requests = []
|
||||
|
||||
@settings = 0# Settings.new
|
||||
@game_servers = []
|
||||
@host_pings = {}
|
||||
|
||||
# connect to and monitor GSH web service
|
||||
@threads << Thread.new { game_server_hub_websocket }
|
||||
# connect to and monitor Backend web service
|
||||
@threads << Thread.new { backend_websocket }
|
||||
# poke game servers to ascertain their ping relative to the local machine
|
||||
@threads << Thread.new { ping_game_servers }
|
||||
|
||||
@w3dhub_api = W3DHubLauncher::W3DHubApi.new
|
||||
|
||||
@@ -45,11 +49,11 @@ module W3DHubLauncher
|
||||
json = JSON.parse(data)
|
||||
query = Request::Query.new(type: json["type"].to_sym, request_id: json["request_id"], data: json["data"])
|
||||
|
||||
pp [:server_incoming, data, query]
|
||||
# pp [:server_incoming, data, query]
|
||||
|
||||
if respond_to?(query.type)
|
||||
response = send(query.type, query)
|
||||
pp [:server_to_client, response]
|
||||
# pp [:server_to_client, response]
|
||||
payload = { status: response.status, request_id: response.request_id, data: response.result.data, error: response.result.error }.to_json
|
||||
socket.puts(payload)
|
||||
end
|
||||
@@ -68,9 +72,56 @@ module W3DHubLauncher
|
||||
def backend_websocket
|
||||
end
|
||||
|
||||
def ping_game_servers
|
||||
socket = Socket.open(Socket::AF_INET, Socket::SOCK_DGRAM, Socket::IPPROTO_ICMP)
|
||||
socket.setsockopt(:SOCKET, :TIMESTAMP, true)
|
||||
|
||||
Async do |task|
|
||||
while true
|
||||
echo_requests = {}
|
||||
|
||||
# Send pings to each unique server host
|
||||
@game_servers.map(&:address).uniq.each do |server_address|
|
||||
address = Socket.sockaddr_in(0, server_address)
|
||||
sequence_id = Digest::SHA256.hexdigest("#{server_address}-#{Time.now.iso8601}")
|
||||
|
||||
# ICMP Echo Request, ICMP Code, <checksum>, <identifier>, <sequence number>, Data
|
||||
msg = [8, 0, 0, 0, sequence_id].flatten.pack("C2n2A64")
|
||||
echo_requests[sequence_id] = { send_time: Time.now, address: server_address, replied: false }
|
||||
socket.send(msg, 0, address)
|
||||
end
|
||||
|
||||
# Receive replies until timeout
|
||||
task.with_timeout(3) do
|
||||
while(echo_requests.values.any? { |v| v[:replied] == false })
|
||||
response, sender_address, flags, *controls = socket.recvmsg(256)
|
||||
_type, _code, _identifier, _sequence, data = response.unpack("C2n2A64")
|
||||
|
||||
if (request = echo_requests[data])# && request[:address] == sender_address.
|
||||
request[:replied] = true
|
||||
round_trip_time = ((controls.last.timestamp - request[:send_time]) * 1000.0).round
|
||||
@host_pings[request[:address]] = round_trip_time
|
||||
|
||||
# puts "#{request[:address]}: #{round_trip_time}ms"
|
||||
# else
|
||||
# # packet not for us, or it got mangled in transit.
|
||||
end
|
||||
end
|
||||
rescue Async::TimeoutError
|
||||
# puts "Timed out waiting for: #{echo_requests.values.select { |v| v[:replied] == false }.map { |v| v[:address] }.join(', ')}"
|
||||
end
|
||||
|
||||
sleep 5
|
||||
end
|
||||
end
|
||||
|
||||
ensure
|
||||
socket&.close
|
||||
end
|
||||
|
||||
# Send request to server
|
||||
def request(query)
|
||||
pp [:client_request, query]
|
||||
# pp [:client_request, query]
|
||||
payload = { type: query.type, request_id: query.request_id, data: query.data }.to_json
|
||||
|
||||
if respond_to?(query.type)
|
||||
@@ -82,11 +133,11 @@ module W3DHubLauncher
|
||||
|
||||
def service
|
||||
data = @socket.read_nonblock(1_048_576) # 1 MB
|
||||
pp [:CLIENT, data]
|
||||
# pp [:CLIENT, data]
|
||||
json = JSON.parse(data)
|
||||
request = W3DHubLauncher::Worker::Request.requests.find { |r| r.request_id == json["request_id"] }
|
||||
|
||||
pp [json, request]
|
||||
# pp [json, request]
|
||||
return unless request
|
||||
|
||||
CyberarmEngine::Window.instance&.add_to_queue(proc {
|
||||
@@ -101,7 +152,7 @@ module W3DHubLauncher
|
||||
|
||||
def deliver_response(result, query)
|
||||
response = Response.new(result.okay? ? Request::STATUS_COMPLETE : Request::STATUS_ERROR, query.request_id, result)
|
||||
pp response
|
||||
# pp response
|
||||
|
||||
response
|
||||
end
|
||||
@@ -252,6 +303,10 @@ module W3DHubLauncher
|
||||
|
||||
response = fetch_url(query)
|
||||
|
||||
if response.result.okay?
|
||||
@game_servers = JSON.parse(response.result.data).map { |server| Worker::Api::GameServer.new(server) }
|
||||
end
|
||||
|
||||
deliver_response(response.result, query)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user