From 17614f44161743b77f6dc9f634fc224a4b4d9137 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Fri, 18 Sep 2026 15:25:22 -0500 Subject: [PATCH] Support 'play now' server selection --- lib/application_helper.rb | 22 ++++++++++++++++++++++ lib/pages/games.rb | 10 +++++++++- lib/states/interface.rb | 2 ++ lib/worker/api/game_server.rb | 5 ++++- lib/worker/api/settings.rb | 2 +- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/application_helper.rb b/lib/application_helper.rb index 1150c27..038bdde 100644 --- a/lib/application_helper.rb +++ b/lib/application_helper.rb @@ -42,5 +42,27 @@ module W3DHubLauncher parameters.join(" ") ) end + + # select "best" server to join + def self.play_now_server(app) + channel = MemCache[:applications].find { |appl| appl.id == app.id }&.channels&.find { |c| c.id == app.channel } + return nil unless channel + + server_options = MemCache[:servers].select do |server| + server.game == app.id && + server.channel == channel.server_channel && + !server.password? && + server.player_count < server.max_players + end.sort_by do |s| + [s.player_count, -s.ping] + end.reverse + + # try to find server with lowest ping and matching app version + found_server = server_options.find { |s| s.version == app.version } + # try to find server with lowest ping and undefined version + found_server ||= server_options.find { |s| s.version == Worker::Api::GameServer::NO_OR_DEFAULT_VERSION } + + found_server + end end end diff --git a/lib/pages/games.rb b/lib/pages/games.rb index 2a39546..c6dc525 100644 --- a/lib/pages/games.rb +++ b/lib/pages/games.rb @@ -186,7 +186,15 @@ module W3DHubLauncher flow(width: 1.0, height: 60) do if application - button "JOIN", tip: "Join most populated or lowest ping server", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME + button "JOIN", tip: "Join most populated or lowest ping server", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME do |btn| + server = ApplicationHelper.play_now_server(application) + + if server + ApplicationHelper.join_server(application, server) + else + puts "No server available." + end + end button safe_get_image("#{ROOT_PATH}/media/icons/singleplayer.png"), tip: "Single player", image_height: 1.0, background_nine_slice: NINE_SLICE_SQUARE, **CTA_BUTTON_THEME do ApplicationHelper.run(application) end diff --git a/lib/states/interface.rb b/lib/states/interface.rb index 0b581ce..d8f65e2 100644 --- a/lib/states/interface.rb +++ b/lib/states/interface.rb @@ -159,7 +159,9 @@ module W3DHubLauncher def populate_server_information(server) return unless @server_details_container.visible? + # FIXME: check server channel against application channel's `server_channel` application = MemCache[:settings].applications.find { |app| app.id == server.game && app.channel == server.channel } + # channel = MemCache[:applications].find { |appl| appl.id == application&.id }&.channels&.find { |c| c.id == application&.channel } @server_details_container.clear do tagline server.name, width: 1.0, text_wrap: :none, tip: server.name diff --git a/lib/worker/api/game_server.rb b/lib/worker/api/game_server.rb index 103326a..eaf80d2 100644 --- a/lib/worker/api/game_server.rb +++ b/lib/worker/api/game_server.rb @@ -4,6 +4,7 @@ module W3DHubLauncher # Designed to work with cyberarm's Game Server Hub service data, may work with W3D Hub's service with degraded metadata. class GameServer BAD_OR_UNKNOWN_PING = 1_000_000 + NO_OR_DEFAULT_VERSION = "838".freeze attr_reader :id, :game, :channel, :address, :port, :region, :name, :password, :current_map, :player_count, :max_players, @@ -45,8 +46,10 @@ module W3DHubLauncher end # Cyberarm GSH extras - @version = data["version"] || "838" + @version = data["version"] || NO_OR_DEFAULT_VERSION @next_map = data["status"]["nextmap"] || "" + + @version = Gem::Version.new(@version) if @version.split(".").size == 4 end # TODO: implement :) diff --git a/lib/worker/api/settings.rb b/lib/worker/api/settings.rb index 3d65f27..a6e40db 100644 --- a/lib/worker/api/settings.rb +++ b/lib/worker/api/settings.rb @@ -78,7 +78,7 @@ module W3DHubLauncher SCHEMA = 0 attr_reader :id, :channel - attr_accessor :version, :installation_path, :wine_prefix_path, :launch_command + attr_accessor :version, :installation_path, :wine_prefix_path, :launch_command, :timestamp def self.create(id:, channel:, version:, installation_path:, wine_prefix_path:, launch_command:, timestamp:) hash = {