Support 'play now' server selection

This commit is contained in:
2026-09-18 15:25:22 -05:00
parent f8ceb69402
commit 17614f4416
5 changed files with 38 additions and 3 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 :)

View File

@@ -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 = {