shelling out to 'ping' no longer spawns command prompts on windows

This commit is contained in:
2022-10-30 20:58:51 -05:00
parent 340c083a43
commit deaa6ee9d9
7 changed files with 106 additions and 12 deletions

View File

@@ -10,6 +10,7 @@ gem "websocket-client-simple"
gem "thread-local"
gem "ircparser"
gem "win32-security", platforms: [:x64_mingw, :mingw]
gem "win32-process", platforms: [:x64_mingw, :mingw]
# group :windows_packaging do
# gem "rake"

View File

@@ -32,6 +32,8 @@ GEM
websocket-client-simple (0.6.0)
event_emitter
websocket
win32-process (0.10.0)
ffi (>= 1.0.0)
win32-security (0.5.0)
ffi
ffi-win32-extensions
@@ -51,6 +53,7 @@ DEPENDENCIES
rexml
thread-local
websocket-client-simple
win32-process
win32-security
BUNDLED WITH

View File

@@ -42,17 +42,27 @@ class W3DHub
end
def send_ping(force_ping = false)
return
if force_ping || Gosu.milliseconds - @last_pinged >= @ping_interval
@last_pinged = Gosu.milliseconds
Thread.new do
ping = Net::Ping::External.new(@address)
@ping = (ping.duration * 1000.0).round if ping.ping?
W3DHub::BackgroundWorker.parallel_job(
lambda do
@ping = -1
States::Interface.instance&.update_server_ping(self)
end
W3DHub.captured_commmand("ping #{@address} #{W3DHub.windows? ? '-n 3' : '-c 3'}") do |line|
if W3DHub.windows? && line =~ /Minimum|Maximum|Maximum/i
@ping = line.strip.split(",").last.split("=").last.sub("ms", "").to_i
elsif W3DHub.unix? && line.start_with?("rtt min/avg/max/mdev")
@ping = line.strip.split("=").last.split("/")[1].to_i
end
end
@ping
end,
lambda do |_|
States::Interface.instance&.update_server_ping(self)
end
)
end
end

View File

@@ -39,12 +39,18 @@ class W3DHub
def self.kill!
@@thread.kill
@@instance.kill!
end
def self.job(job, callback, error_handler = nil)
@@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler))
end
def self.parallel_job(job, callback, error_handler = nil)
@@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler))
end
def self.foreground_job(job, callback, error_handler = nil)
@@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true))
end
@@ -52,9 +58,40 @@ class W3DHub
def initialize
@busy = false
@jobs = []
# Jobs which are order independent
@parallel_busy = false
@thread_pool = []
@parallel_jobs = []
end
def kill!
@thread_pool.each(&:kill)
end
def handle_jobs
8.times do |i|
Thread.new do |thread|
@thread_pool << thread
while BackgroundWorker.run?
job = @parallel_jobs.shift
@parallel_busy = true
begin
job&.do
rescue => e
job&.raise_error(e)
end
@parallel_busy = !@parallel_jobs.empty?
sleep 0.1
end
end
end
while BackgroundWorker.run?
job = @jobs.shift
@@ -62,8 +99,8 @@ class W3DHub
begin
job&.do
rescue => error
job&.raise_error(error)
rescue => e
job&.raise_error(e)
end
@busy = !@jobs.empty?
@@ -79,8 +116,12 @@ class W3DHub
@jobs << job
end
def add_parallel_job(job)
@parallel_jobs << job
end
def busy?
@busy
@busy || @parallel_busy
end
class Job

View File

@@ -40,11 +40,46 @@ class W3DHub
end
end
def self.commmand(command)
def self.captured_commmand(command, &block)
if windows?
stdout_read, stdout_write = IO.pipe
process_info = Process.create(
command_line: command,
creation_flags: Process::DETACHED_PROCESS,
process_inherit: true,
thread_inherit: true,
inherit: true,
startup_info: {
stdout: stdout_write,
stderr: stdout_write
}
)
pid = process_info.process_id
until Process.get_exitcode(pid)
readable, _writable, _errorable = IO.select([stdout_read], [], [], 1)
readable&.each do |io|
line = io.readpartial(1024)
block&.call(line)
end
end
stdout_read.close
stdout_write.close
Process.get_exitcode(pid).zero?
else
IO.popen(command)
IO.popen(command) do |io|
io.each_line do |line|
block&.call(line)
end
end
$CHILD_STATUS.success?
end
end

View File

@@ -249,6 +249,7 @@ class W3DHub
server_map.value = server&.status&.map
player_count.value = "#{server&.status&.player_count}/#{server&.status&.max_players}"
server_ping.value = ping_icon(server)
server_ping.parent.parent.tip = ping_tip(server)
end
def update_server_ping(server)

View File

@@ -68,6 +68,7 @@ end
require "i18n"
require "launchy"
require "websocket-client-simple"
require "English"
I18n.load_path << Dir["#{W3DHub::GAME_ROOT_PATH}/locales/*.yml"]
I18n.default_locale = :en
@@ -135,6 +136,8 @@ require_relative "lib/asterisk/states/game_form"
require_relative "lib/asterisk/states/irc_profile_form"
require_relative "lib/asterisk/states/server_profile_form"
require "win32/process" if W3DHub.windows?
logger.info(W3DHub::LOG_TAG) { "W3D Hub Linux Launcher v#{W3DHub::VERSION}" }
Thread.new do