From f55924596ddac9923c9f01b132f4ccb4773627c4 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 11 Mar 2024 19:17:38 -0500 Subject: [PATCH] Fix some weird scoping issues with ServerListUpdater lambdas --- lib/api.rb | 2 ++ lib/api/server_list_server.rb | 26 +++++++++++++------------- lib/api/server_list_updater.rb | 34 +++++++++++++++++++++++++++------- lib/background_worker.rb | 22 +++++++++++----------- lib/pages/server_browser.rb | 18 +++++++++--------- 5 files changed, 62 insertions(+), 40 deletions(-) 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|