diff --git a/lib/api.rb b/lib/api.rb
index ea149d5..451a75a 100644
--- a/lib/api.rb
+++ b/lib/api.rb
@@ -308,6 +308,8 @@ class W3DHub
# ...players[]:
# nick, team (index of teams array), score, kills, deaths
def self.server_details(id, level)
+ return false unless id && level
+
response = get("#{SERVER_LIST_ENDPOINT}/listings/getStatus/v2/#{id}?statusLevel=#{level}", DEFAULT_HEADERS, nil, :gsh)
if response.status == 200
diff --git a/lib/api/server_list_server.rb b/lib/api/server_list_server.rb
index fefe5bf..e6f6b3d 100644
--- a/lib/api/server_list_server.rb
+++ b/lib/api/server_list_server.rb
@@ -14,10 +14,10 @@ class W3DHub
@channel = @data[:channel] || "release"
@ping = -1
- @status = @data[:status] ? Status.new(@data[:status]) : nil
+ @status = Status.new(@data[:status])
@ping_interval = 30_000
- @last_pinged = Gosu.milliseconds + @ping_interval + 1
+ @last_pinged = Gosu.milliseconds + @ping_interval + 1_000
end
def update(hash)
@@ -34,11 +34,11 @@ class W3DHub
@status.players = hash[:players]&.select { |t| t[:nick] != "Nod" && t[:nick] != "GDI" }&.map { |t| Player.new(t) } if hash[:players]
send_ping
-
- return true
+ else
+ @status = Status.new(hash)
end
- false
+ true
end
def send_ping(force_ping = false)
@@ -70,18 +70,18 @@ class W3DHub
attr_accessor :name, :password, :map, :max_players, :player_count, :started, :remaining, :teams, :players
def initialize(hash)
- @data = hash
+ @data = hash || {}
- @teams = @data[:teams]&.map { |t| Team.new(t) }
- @players = @data[:players]&.select { |t| t[:nick] != "Nod" && t[:nick] != "GDI" }&.map { |t| Player.new(t) }
+ @teams = @data[:teams]&.map { |t| Team.new(t) } || []
+ @players = @data[:players]&.select { |t| t[:nick] != "Nod" && t[:nick] != "GDI" }&.map { |t| Player.new(t) } || []
- @name = @data[:name]
+ @name = @data[:name] || ""
@password = @data[:password] || false
- @map = @data[:map]
- @max_players = @data[:maxplayers]
+ @map = @data[:map] || ""
+ @max_players = @data[:maxplayers] || 0
@player_count = @players.size || @data[:numplayers].to_i
- @started = @data[:started]
- @remaining = @data[:remaining]
+ @started = @data[:started] || Time.now
+ @remaining = @data[:remaining] || "00.00.00"
end
end
diff --git a/lib/api/server_list_updater.rb b/lib/api/server_list_updater.rb
index d6caa18..681cc4e 100644
--- a/lib/api/server_list_updater.rb
+++ b/lib/api/server_list_updater.rb
@@ -49,6 +49,7 @@ class W3DHub
response = Excon.post("https://gsh.w3dhub.com/listings/push/v2/negotiate?negotiateVersion=1", headers: Api::DEFAULT_HEADERS, body: "")
data = JSON.parse(response.body, symbolize_names: true)
+ invocation_id = 0
id = data[:connectionToken]
endpoint = "https://gsh.w3dhub.com/listings/push/v2?id=#{id}"
@@ -60,10 +61,10 @@ class W3DHub
ws.send({ protocol: "json", version: 1 }.to_json + "\x1e")
logger.debug(LOG_TAG) { "Subscribing to server changes..." }
- Store.server_list.each_with_index do |server, i|
- i += 1
+ Store.server_list.each do |server|
+ invocation_id += 1
mode = 1 # 2 full details, 1 basic details
- out = { "type": 1, "invocationId": "#{i}", "target": "SubscribeToServerStatusUpdates", "arguments": [server.id, mode] }
+ out = { "type": 1, "invocationId": "#{invocation_id}", "target": "SubscribeToServerStatusUpdates", "arguments": [server.id, mode] }
ws.send(out.to_json + "\x1e")
end
end
@@ -84,15 +85,34 @@ class W3DHub
case hash[:target]
when "ServerRegistered"
data = hash[:arguments].first
- server = ServerListServer.new(data)
- Store.server_list.push(server)
+
+ invocation_id += 1
+ out = { "type": 1, "invocationId": "#{invocation_id}", "target": "SubscribeToServerStatusUpdates", "arguments": [data[:id], 1] }
+ ws.send(out.to_json + "\x1e")
+
+ BackgroundWorker.foreground_job(
+ ->(data) { [Api.server_details(data[:id], 2), data] },
+ ->(array) do
+ server_data, data = array
+
+ next unless server_data
+
+ data[:status] = server_data
+
+ server = ServerListServer.new(data)
+ Store.server_list.push(server)
+ States::Interface.instance&.update_server_browser(server, :update)
+ end,
+ nil,
+ data
+ )
when "ServerStatusChanged"
id, data = hash[:arguments]
server = Store.server_list.find { |s| s.id == id }
server_updated = server&.update(data)
- BackgroundWorker.foreground_job(-> {}, ->(result){ States::Interface.instance&.update_server_browser(server, :update) }) if server_updated
+ BackgroundWorker.foreground_job(->(server) { server }, ->(server) { States::Interface.instance&.update_server_browser(server, :update) }, nil, server) if server_updated
when "ServerUnregistered"
id = hash[:arguments].first
@@ -100,7 +120,7 @@ class W3DHub
if server
Store.server_list.delete(server)
- BackgroundWorker.foreground_job(-> {}, ->(result){ States::Interface.instance&.update_server_browser(server, :remove) })
+ BackgroundWorker.foreground_job(->(server) { server }, ->(server) { States::Interface.instance&.update_server_browser(server, :remove) }, nil, server)
end
end
end
diff --git a/lib/background_worker.rb b/lib/background_worker.rb
index 5628fd9..fee113c 100644
--- a/lib/background_worker.rb
+++ b/lib/background_worker.rb
@@ -43,20 +43,20 @@ class W3DHub
@@instance.kill!
end
- def self.job(job, callback, error_handler = nil)
- @@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler))
+ def self.job(job, callback, error_handler = nil, data = nil)
+ @@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler, data: data))
end
- def self.parallel_job(job, callback, error_handler = nil)
- @@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler))
+ def self.parallel_job(job, callback, error_handler = nil, data = nil)
+ @@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler, data: data))
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))
+ def self.foreground_job(job, callback, error_handler = nil, data = nil)
+ @@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true, data: data))
end
- def self.foreground_parallel_job(job, callback, error_handler = nil)
- @@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true))
+ def self.foreground_parallel_job(job, callback, error_handler = nil, data = nil)
+ @@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true, data: data))
end
def initialize
@@ -136,16 +136,16 @@ class W3DHub
end
class Job
- def initialize(job:, callback:, error_handler: nil, deliver_to_queue: false)
+ def initialize(job:, callback:, error_handler: nil, deliver_to_queue: false, data: nil)
@job = job
@callback = callback
@error_handler = error_handler
-
@deliver_to_queue = deliver_to_queue
+ @data = data
end
def do
- result = @job.call
+ result = @data ? @job.call(@data) : @job.call
deliver(result)
end
diff --git a/lib/pages/server_browser.rb b/lib/pages/server_browser.rb
index 6a7ee0b..8d7c15a 100644
--- a/lib/pages/server_browser.rb
+++ b/lib/pages/server_browser.rb
@@ -258,14 +258,14 @@ class W3DHub
player_count = find_element_by_tag(server_container, :player_count)
server_ping = find_element_by_tag(server_container, :ping)
- game_icon.value = game_icon(server)
- server_name.value = "#{server&.status&.name}"
- server_channel.value = Store.application_manager.channel_name(server.game, server.channel).to_s
- server_region.value = server.region
- 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)
+ game_icon&.value = game_icon(server)
+ server_name&.value = "#{server&.status&.name}"
+ server_channel&.value = Store.application_manager.channel_name(server.game, server.channel).to_s
+ server_region&.value = server.region
+ 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)
@@ -308,7 +308,7 @@ class W3DHub
end
def populate_server_list
- Store.server_list = Store.server_list.sort_by! { |s| [s&.status&.player_count, s&.id] }.reverse if Store.server_list
+ Store.server_list = Store.server_list.sort_by! { |s| [s.status.player_count, s.id] }.reverse
@server_list_container.clear do
Store.server_list.each do |server|