Actually start using the game server pings

This commit is contained in:
2026-09-08 18:51:22 -05:00
parent a7ae460446
commit 8c14ecffc1
4 changed files with 74 additions and 11 deletions

View File

@@ -6,6 +6,8 @@ module W3DHubLauncher
def setup def setup
@games_filter = [] @games_filter = []
CyberarmEngine::EventBus.subscribe("game_server_pings", self, :handle_game_server_pings)
# game bar container # game bar container
flow(width: 1.0, height: 60) do flow(width: 1.0, height: 60) do
widget(width: 220, height: 1.0, style_class: [:all_button]) do |w| widget(width: 220, height: 1.0, style_class: [:all_button]) do |w|
@@ -49,9 +51,17 @@ module W3DHubLauncher
populate_server_list populate_server_list
end end
def blur
CyberarmEngine::EventBus.unsubscribe("game_server_pings", self)
end
def handle_game_server_pings(payload)
# TODO: Update displayed server ping
end
def populate_server_list def populate_server_list
@servers_container.clear do @servers_container.clear do
(MemCache[:servers] || []).select { |s| @games_filter.empty? ? true : @games_filter.include?(s.game) }.sort_by { |s| s.player_count }.reverse.each do |server| (MemCache[:servers] || []).select { |s| @games_filter.empty? ? true : @games_filter.include?(s.game) }.sort_by { |s| [s.player_count, -s.ping] }.reverse.each do |server|
app = MemCache[:applications].find { |a| a.id == server.game } app = MemCache[:applications].find { |a| a.id == server.game }
widget(width: 1.0, height: 48, padding_top: HALF_PADDING, padding_bottom: HALF_PADDING, margin_bottom: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: server.channel == "release" ? ALPHA_GRAY : 0xaa_c64600, hover: { background_nine_slice_color: 0xff_5e5c64 } , active: { background_nine_slice_color: 0xaa_5e5c64 }) do widget(width: 1.0, height: 48, padding_top: HALF_PADDING, padding_bottom: HALF_PADDING, margin_bottom: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: server.channel == "release" ? ALPHA_GRAY : 0xaa_c64600, hover: { background_nine_slice_color: 0xff_5e5c64 } , active: { background_nine_slice_color: 0xaa_5e5c64 }) do
@@ -87,10 +97,10 @@ module W3DHubLauncher
# server ping # server ping
flow(width: 96, height: 1.0, margin_left: HALF_PADDING, margin_right: HALF_PADDING) do flow(width: 96, height: 1.0, margin_left: HALF_PADDING, margin_right: HALF_PADDING) do
stack(fill: true, height: 1.0, v_align: :center) do stack(fill: true, height: 1.0, v_align: :center) do
caption rand > 0.85 ? "?" : format("%d ms", rand(16..360)), width: 1.0, text_align: :center caption server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "?" : server.ping, width: 1.0, text_align: :center, tip: server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "Server has not replied yet or did not reply to ICMP Echo Request.\nPing unknown." : ""
inscription "ping", text_wrap: :none, width: 1.0, text_align: :center, margin_top: -HALF_PADDING inscription "ping", text_wrap: :none, width: 1.0, text_align: :center, margin_top: -HALF_PADDING
end end
stack(width: 8, height: rand(0.25..1.0), v_align: :center, min_height: 8, background_nine_slice: NINE_SLICE_ROUNDED_SMALL, background_nine_slice_from_edge: NINE_SLICE_EDGE_SMALL, background_nine_slice_color: [0xff_26a269, 0xff_e5a50a, 0xff_a51d2d, 0xff_3d3846].sample) stack(width: 8, height: server.ping_score_ratio, v_align: :center, min_height: 8, background_nine_slice: NINE_SLICE_ROUNDED_SMALL, background_nine_slice_from_edge: NINE_SLICE_EDGE_SMALL, background_nine_slice_color: server.ping_score_color)
end end
end end
end end

View File

@@ -6,6 +6,10 @@ module W3DHubLauncher
@main_thread_queue = [] @main_thread_queue = []
CyberarmEngine::EventBus.subscribe("game_server_pings", self) do |payload|
MemCache[:game_server_pings] = payload
end
push_state(States::Boot) push_state(States::Boot)
# push_state(States::Interface) # push_state(States::Interface)
end end

View File

@@ -30,6 +30,8 @@ module W3DHubLauncher
@threads = [] @threads = []
@requests = [] @requests = []
@client = nil
@settings = 0# Settings.new @settings = 0# Settings.new
@game_servers = [] @game_servers = []
@host_pings = {} @host_pings = {}
@@ -46,6 +48,8 @@ module W3DHubLauncher
Async do |task| Async do |task|
UNIXServer.open(IPC_PATH) do |server| UNIXServer.open(IPC_PATH) do |server|
while(socket = server.accept) while(socket = server.accept)
@client = socket
task.async do task.async do
while(data = socket.gets) while(data = socket.gets)
json = JSON.parse(data) json = JSON.parse(data)
@@ -115,6 +119,8 @@ module W3DHubLauncher
# puts "Timed out waiting for: #{echo_requests.values.select { |v| v[:replied] == false }.map { |v| v[:address] }.join(', ')}" # puts "Timed out waiting for: #{echo_requests.values.select { |v| v[:replied] == false }.map { |v| v[:address] }.join(', ')}"
end end
broadcast(:game_server_pings, data: @host_pings)
sleep 5 sleep 5
end end
end end
@@ -123,6 +129,14 @@ module W3DHubLauncher
socket&.close socket&.close
end end
def broadcast(type, data:)
payload = { type: :eventbus, request_id: -1, data: { type: type, data: data } }.to_json
@client&.write(payload)
@client&.write(RESPONSE_SEPARATOR)
@client&.flush
end
# Send request to server # Send request to server
def request(query) def request(query)
# pp [:client_request, query] # pp [:client_request, query]
@@ -150,14 +164,18 @@ module W3DHubLauncher
request = W3DHubLauncher::Worker::Request.requests.find { |r| r.request_id == json["request_id"] } request = W3DHubLauncher::Worker::Request.requests.find { |r| r.request_id == json["request_id"] }
# pp [json, request] # pp [json, request]
return unless request if request.nil? && json["request_id"] && json["type"] == "eventbus"
CyberarmEngine::Window.instance&.add_to_queue(proc {
CyberarmEngine::Window.instance&.add_to_queue(proc { CyberarmEngine::EventBus.publish(json["data"]["type"], json["data"]["data"])
request.handle_event( })
json["status"], else
CyberarmEngine::Result.new(data: json["data"], error: json["error"]) CyberarmEngine::Window.instance&.add_to_queue(proc {
) request.handle_event(
}) json["status"],
CyberarmEngine::Result.new(data: json["data"], error: json["error"])
)
})
end
rescue JSON::ParserError => e rescue JSON::ParserError => e
puts "This should never happen!?!?!" puts "This should never happen!?!?!"

View File

@@ -3,6 +3,8 @@ module W3DHubLauncher
class Api class Api
# Designed to work with cyberarm's Game Server Hub service data, may work with W3D Hub's service with degraded metadata. # Designed to work with cyberarm's Game Server Hub service data, may work with W3D Hub's service with degraded metadata.
class GameServer class GameServer
BAD_OR_UNKNOWN_PING = 1_000_000
attr_reader :id, :game, :channel, :address, :port, :region, attr_reader :id, :game, :channel, :address, :port, :region,
:name, :password, :current_map, :player_count, :max_players, :name, :password, :current_map, :player_count, :max_players,
:match_start_time, :estimated_end_time, :match_remaining_time, :match_start_time, :estimated_end_time, :match_remaining_time,
@@ -55,6 +57,35 @@ module W3DHubLauncher
def password? def password?
@password @password
end end
def ping
MemCache.dig(:game_server_pings, @address) || BAD_OR_UNKNOWN_PING
end
def ping_score_ratio
# under 50 is best, over 200 is worst
case ping
when 0..49
return 1.0
when 50..200
1.0 - (ping / 200.0) + 0.1
else
return 0.1
end
end
def ping_score_color
case ping
when 0..49 # gentle green
0xff_26a269
when 50..149 # rich orange
0xff_e5a50a
when 150..200 # dark red
0xff_a51d2d
else # dark gray
0xff_3d3846
end
end
end end
class Team class Team