Initial support for importing games

This commit is contained in:
2026-09-18 09:28:39 -05:00
parent 56699bb644
commit 6707f260c9
5 changed files with 109 additions and 20 deletions

View File

@@ -5,7 +5,7 @@ GEM
console (~> 1.29) console (~> 1.29)
fiber-annotation fiber-annotation
io-event (~> 1.21) io-event (~> 1.21)
async-http (0.103.0) async-http (0.104.0)
async (>= 2.35.1) async (>= 2.35.1)
async-pool (~> 0.12) async-pool (~> 0.12)
io-endpoint (~> 0.18) io-endpoint (~> 0.18)
@@ -40,11 +40,11 @@ GEM
ffi (~> 1.12) ffi (~> 1.12)
io-endpoint (0.18.0) io-endpoint (0.18.0)
openssl (>= 3.3.0) openssl (>= 3.3.0)
io-event (1.21.1) io-event (1.22.0)
io-stream (0.14.0) io-stream (0.14.0)
openssl (>= 3.3) openssl (>= 3.3)
ircparser (1.0.0) ircparser (1.0.0)
json (3.0.1) json (3.0.2)
logger (1.7.0) logger (1.7.0)
openssl (4.0.2) openssl (4.0.2)
protocol-hpack (1.5.1) protocol-hpack (1.5.1)
@@ -54,7 +54,8 @@ GEM
protocol-http2 (0.28.0) protocol-http2 (0.28.0)
protocol-hpack (~> 1.4) protocol-hpack (~> 1.4)
protocol-http (~> 0.62) protocol-http (~> 0.62)
protocol-rack (0.22.1) protocol-rack (0.23.0)
console (~> 1.0)
io-stream (>= 0.10) io-stream (>= 0.10)
protocol-http (~> 0.58) protocol-http (~> 0.58)
rack (>= 1.0) rack (>= 1.0)
@@ -89,7 +90,7 @@ DEPENDENCIES
CHECKSUMS CHECKSUMS
async (2.45.1) sha256=95849f7432eca535146c69f3078dab3c7228d0075ed71f48733f3e585dd7c267 async (2.45.1) sha256=95849f7432eca535146c69f3078dab3c7228d0075ed71f48733f3e585dd7c267
async-http (0.103.0) sha256=137e3d5d419f7d72d5fa33cf04f30232e79c57b690025a650b8f9e48ece8bc41 async-http (0.104.0) sha256=c5f436fe7778cee07031770b232d9feb412f1d80287a0b5dcbd1f6335a52ce6f
async-pool (0.12.0) sha256=5580493dc024bd704dab2ed0bf1307100722e49cbb825c7965f8501194f58506 async-pool (0.12.0) sha256=5580493dc024bd704dab2ed0bf1307100722e49cbb825c7965f8501194f58506
async-websocket (0.30.1) sha256=54bb8a8f184e4aa64434c7a78ecc55850a67a3d1dcd02e3ae787376e2c673936 async-websocket (0.30.1) sha256=54bb8a8f184e4aa64434c7a78ecc55850a67a3d1dcd02e3ae787376e2c673936
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
@@ -103,17 +104,17 @@ CHECKSUMS
fiber-storage (1.0.1) sha256=f48e5b6d8b0be96dac486332b55cee82240057065dc761c1ea692b2e719240e1 fiber-storage (1.0.1) sha256=f48e5b6d8b0be96dac486332b55cee82240057065dc761c1ea692b2e719240e1
gosu (1.5.0-x86_64-linux) gosu (1.5.0-x86_64-linux)
io-endpoint (0.18.0) sha256=720d186bcd584e8ba490bfc91dab332cc3c5ffee848b5b03894555cb275151aa io-endpoint (0.18.0) sha256=720d186bcd584e8ba490bfc91dab332cc3c5ffee848b5b03894555cb275151aa
io-event (1.21.1) sha256=b3088f89ad67edf9be9fc2f48a5fae0790e92862487551eeb337b49098eb99e6 io-event (1.22.0) sha256=4936d38dfcf2291d897707fd94690f1a63fdb1ea3ab4fa63c6739fc6c61e1534
io-stream (0.14.0) sha256=07d9b13ea2066ccbbc761fff8d69ad5a31e47561d31e02cc271f3ed9c1a8f1cd io-stream (0.14.0) sha256=07d9b13ea2066ccbbc761fff8d69ad5a31e47561d31e02cc271f3ed9c1a8f1cd
ircparser (1.0.0) sha256=0d4598f691172e2ad078207c50ba62c0d3428ae841836b0a682e6cd01d62878d ircparser (1.0.0) sha256=0d4598f691172e2ad078207c50ba62c0d3428ae841836b0a682e6cd01d62878d
json (3.0.1) sha256=c80f74a3570c3a310cd41c526904e7ef8363abdece4432f31fe97d812bc4a39e json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
openssl (4.0.2) sha256=1037ad2868ae58df9ad917891c0c0f9815a1172f6846d4bcdd508e4c2ee747c2 openssl (4.0.2) sha256=1037ad2868ae58df9ad917891c0c0f9815a1172f6846d4bcdd508e4c2ee747c2
protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91 protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91
protocol-http (0.71.0) sha256=38577bf3df0bf0c3f7ee7e21b43fcb4bd7624e36f697dbe9c3eea344f14bd9ba protocol-http (0.71.0) sha256=38577bf3df0bf0c3f7ee7e21b43fcb4bd7624e36f697dbe9c3eea344f14bd9ba
protocol-http1 (0.41.0) sha256=9863874a1228948a896c3e7ea16d13a680c8f3ed50706007c78b7033018b0ea3 protocol-http1 (0.41.0) sha256=9863874a1228948a896c3e7ea16d13a680c8f3ed50706007c78b7033018b0ea3
protocol-http2 (0.28.0) sha256=b7c6195dcfa80ec2484670e9fd8fc21024cc654a391aa0792433aff1188c1691 protocol-http2 (0.28.0) sha256=b7c6195dcfa80ec2484670e9fd8fc21024cc654a391aa0792433aff1188c1691
protocol-rack (0.22.1) sha256=1185d245927ef9849a603700d6991ca353bc89724fbf98efa4a4333ed62a9fc3 protocol-rack (0.23.0) sha256=63eec3341b20565b3dd155345fd1426ecbbed322cdc8a6accc993905388c03d7
protocol-url (0.19.0) sha256=3f6b9f6aa742a259a0b3610fbbd9685dcd9506adf6734f428ff96259faabfb21 protocol-url (0.19.0) sha256=3f6b9f6aa742a259a0b3610fbbd9685dcd9506adf6734f428ff96259faabfb21
protocol-websocket (0.21.2) sha256=cbe35be8e045597b221874fba5928d7cd2483884126e3e36faece4741dc88eb7 protocol-websocket (0.21.2) sha256=cbe35be8e045597b221874fba5928d7cd2483884126e3e36faece4741dc88eb7
rack (3.2.7) sha256=93e13e1c24f93556671d85d2d79fa228c3485815c50d7e2f265b5330c6528fb7 rack (3.2.7) sha256=93e13e1c24f93556671d85d2d79fa228c3485815c50d7e2f265b5330c6528fb7

View File

@@ -40,12 +40,16 @@ module W3DHubLauncher
def present_item(item) def present_item(item)
unless item.url.empty? unless item.url.empty?
link item.name, tip: item.url, margin_left: PADDING, font: FONT_BOLD link item.name, tip: item.url, margin_left: PADDING, font: FONT_BOLD do
SDL.OpenURL(item.url)
end
else else
tagline item.name, margin_left: PADDING tagline item.name, margin_left: PADDING
end end
para item.description, margin_left: LARGE_PADDING para item.description, margin_left: LARGE_PADDING
link item.license, tip: item.license_url, margin_left: PADDING + LARGE_PADDING unless item.license.empty? link item.license, tip: item.license_url, margin_left: PADDING + LARGE_PADDING unless item.license.empty? do
SDL.OpenURL(item.license_url)
end
end end
end end
end end

View File

@@ -0,0 +1,77 @@
module W3DHubLauncher
class Dialog
class ImportApplication < W3DHubLauncher::Dialog
def setup
super
@application = @options[:application]
@channel = @options[:channel]
stack(width: 1.0, max_width: 600, height: 1.0, max_height: 600, h_align: :center, v_align: :center, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0xee_63452c) do
flow(width: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0) do
banner "Import Application", width: 1.0, text_align: :center
end
stack(width: 1.0, fill: true, scroll: true, margin_left: PADDING, margin_right: PADDING, padding: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_BLACK) do
title format("%s (%s)", @application.name, @channel.name)
caption "Path to application executable:"
@path_input = edit_line "", width: 1.0
button "Browse..." do
Gosu.choose_file do |file_list|
pp file_list
unless file_list.empty?
@path_input.value = file_list.first
end
end
end
@path_input.subscribe(:changed) do |e, value|
found = false
if File.directory?(File.dirname(value))
Dir.glob("#{File.dirname(value)}/game*.exe").each do |file|
if File.exist?(file)
found = true
break
end
end
end
@import_button.enabled = found
end
end
flow(width: 1.0, padding: PADDING, background_nine_slice: NINE_SLICE_ROUNDED_BOTTOM, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0) do
button "Close" do
pop_state
end
flow(fill: true)
@import_button = button "Import", enabled: false, **CTA_BUTTON_THEME do
pop_state
app = Worker::Api::Settings::Application.create(
id: @application.id,
channel: @channel.id,
version: @channel.version,
installation_path: File.dirname(@path_input.value),
wine_prefix_path: "",
launch_command: "%COMMAND%",
timestamp: Time.now.to_i
)
MemCache[:settings].applications << app
Worker::Api.update_settings(MemCache[:settings])
# FIXME: broadcast app installed on CyberarmEngine::EventBus
end
end
end
end
end
end
end

View File

@@ -183,6 +183,7 @@ module W3DHubLauncher
populate_game_info populate_game_info
end end
end end
flow(width: 1.0, height: 60) do flow(width: 1.0, height: 60) do
if application 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
@@ -191,18 +192,25 @@ module W3DHubLauncher
end end
button safe_get_image("#{ROOT_PATH}/media/icons/gear.png"), tip: "Options", image_height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME do |btn| button safe_get_image("#{ROOT_PATH}/media/icons/gear.png"), tip: "Options", image_height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME do |btn|
menu(parent: btn) do menu(parent: btn) do
menu_item("Game Settings") menu_item("v#{application.version}", enabled: false, disabled: { color: 0xdd_ffffff }, tip: "Installed application version")
menu_item("Show in Explorer") stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
menu_item("Repair Installation") menu_item("Installation Folder", tip: "Open application installation folder:\n#{application.installation_path}")
menu_item("Check for Updates") menu_item("Screenshots Folder", tip: "Open application installation folder:\n#{Dir.home}/Documents/W3D Hub/#{application.id}-#{application.channel}/Screenshots")
stack(width: 1.0, height: 4, background: 0xff_bbbbbb) stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
menu_item("Move Installation") menu_item("Application Settings", tip: "Edit application launch options")
menu_item("Uninstall") menu_item("Repair Installation", tip: "Attempt to fix and repair installation")
menu_item("Check for Updates", tip: "Manually check for application updates")
stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
menu_item("Move Installation", tip: "Move application installation to a different directory or disk")
menu_item("Unlink Installation", tip: "The application will be removed from the launcher\nbut the application's files will not be touched")
menu_item("Uninstall", tip: "Uninstall application and delete files")
end.show end.show
end end
elsif @current_app.servicable? elsif @current_app.servicable?
# pp @current_app # pp @current_app
button "Import", enabled: false, tip: "Import existing application installation", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME button "Import", tip: "Import existing application installation", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME do |btn|
dialog(Dialog::ImportApplication, application: @current_app, channel: @current_channel)
end
button "Download", tip: "Download and install application", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME do |btn| button "Download", tip: "Download and install application", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME do |btn|
btn.enabled = false btn.enabled = false
@@ -214,8 +222,6 @@ module W3DHubLauncher
button "Import", enabled: false, tip: "Import existing application installation", fill: true, height: 1.0, **CTA_BUTTON_THEME button "Import", enabled: false, tip: "Import existing application installation", fill: true, height: 1.0, **CTA_BUTTON_THEME
end end
end end
inscription "Version: #{application.version}", margin_top: PADDING, tip: "Installed version" if application
end end
end end

View File

@@ -40,6 +40,7 @@ require_relative "lib/dialogs/about"
require_relative "lib/dialogs/downloads" require_relative "lib/dialogs/downloads"
require_relative "lib/dialogs/server" require_relative "lib/dialogs/server"
require_relative "lib/dialogs/account" require_relative "lib/dialogs/account"
require_relative "lib/dialogs/import_application"
require_relative "lib/states/boot" require_relative "lib/states/boot"
require_relative "lib/states/interface" require_relative "lib/states/interface"
require_relative "lib/window" require_relative "lib/window"