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 "thread-local"
gem "ircparser" gem "ircparser"
gem "win32-security", platforms: [:x64_mingw, :mingw] gem "win32-security", platforms: [:x64_mingw, :mingw]
gem "win32-process", platforms: [:x64_mingw, :mingw]
# group :windows_packaging do # group :windows_packaging do
# gem "rake" # gem "rake"

View File

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

View File

@@ -42,17 +42,27 @@ class W3DHub
end end
def send_ping(force_ping = false) def send_ping(force_ping = false)
return
if force_ping || Gosu.milliseconds - @last_pinged >= @ping_interval if force_ping || Gosu.milliseconds - @last_pinged >= @ping_interval
@last_pinged = Gosu.milliseconds @last_pinged = Gosu.milliseconds
Thread.new do W3DHub::BackgroundWorker.parallel_job(
ping = Net::Ping::External.new(@address) lambda do
@ping = (ping.duration * 1000.0).round if ping.ping? @ping = -1
States::Interface.instance&.update_server_ping(self) W3DHub.captured_commmand("ping #{@address} #{W3DHub.windows? ? '-n 3' : '-c 3'}") do |line|
end 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
end end

View File

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

View File

@@ -40,11 +40,46 @@ class W3DHub
end end
end end
def self.commmand(command) def self.captured_commmand(command, &block)
if windows? 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 else
IO.popen(command) IO.popen(command) do |io|
io.each_line do |line|
block&.call(line)
end
end
$CHILD_STATUS.success?
end end
end end

View File

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

View File

@@ -68,6 +68,7 @@ end
require "i18n" require "i18n"
require "launchy" require "launchy"
require "websocket-client-simple" require "websocket-client-simple"
require "English"
I18n.load_path << Dir["#{W3DHub::GAME_ROOT_PATH}/locales/*.yml"] I18n.load_path << Dir["#{W3DHub::GAME_ROOT_PATH}/locales/*.yml"]
I18n.default_locale = :en 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/irc_profile_form"
require_relative "lib/asterisk/states/server_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}" } logger.info(W3DHub::LOG_TAG) { "W3D Hub Linux Launcher v#{W3DHub::VERSION}" }
Thread.new do Thread.new do