mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2025-12-17 01:32:34 +00:00
Compare commits
2 Commits
d880d1525f
...
1b91191d90
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b91191d90 | |||
| 1214c35fb5 |
10
lib/api.rb
10
lib/api.rb
@@ -177,7 +177,7 @@ class W3DHub
|
|||||||
return data.map { |hash| ServerListServer.new(hash) }
|
return data.map { |hash| ServerListServer.new(hash) }
|
||||||
end
|
end
|
||||||
|
|
||||||
pp response
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# /listings/getStatus/v2/:id?statusLevel=#{0-2}
|
# /listings/getStatus/v2/:id?statusLevel=#{0-2}
|
||||||
@@ -192,6 +192,14 @@ class W3DHub
|
|||||||
# ...players[]:
|
# ...players[]:
|
||||||
# nick, team (index of teams array), score, kills, deaths
|
# nick, team (index of teams array), score, kills, deaths
|
||||||
def self.server_details(internet, id, level)
|
def self.server_details(internet, id, level)
|
||||||
|
response = internet.get("#{SERVER_LIST_ENDPOINT}/listings/getStatus/v2/#{id}?statusLevel=#{level}", DEFAULT_HEADERS)
|
||||||
|
|
||||||
|
if response.success?
|
||||||
|
hash = JSON.parse(response.read, symbolize_names: true)
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# /listings/push/v2/negotiate?negotiateVersion=1
|
# /listings/push/v2/negotiate?negotiateVersion=1
|
||||||
|
|||||||
@@ -25,7 +25,14 @@ class W3DHub
|
|||||||
@status.instance_variable_set(:@player_count, hash[:numplayers] || 0)
|
@status.instance_variable_set(:@player_count, hash[:numplayers] || 0)
|
||||||
@status.instance_variable_set(:@started, hash[:started])
|
@status.instance_variable_set(:@started, hash[:started])
|
||||||
@status.instance_variable_set(:@remaining, hash[:remaining])
|
@status.instance_variable_set(:@remaining, hash[:remaining])
|
||||||
|
|
||||||
|
@status.instance_variable_set(:@teams, hash[:teams]&.map { |t| Team.new(t) }) if hash[:teams]
|
||||||
|
@status.instance_variable_set(:@players, hash[:players]&.select { |t| t[:nick] != "Nod" && t[:nick] != "GDI" }&.map { |t| Player.new(t) }) if hash[:players]
|
||||||
|
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
class Status
|
class Status
|
||||||
|
|||||||
@@ -105,9 +105,8 @@ class W3DHub
|
|||||||
|
|
||||||
id, data = rpc[:arguments]
|
id, data = rpc[:arguments]
|
||||||
server = Store.server_list.find { |s| s.id == id }
|
server = Store.server_list.find { |s| s.id == id }
|
||||||
server&.update(data)
|
server_updated = server&.update(data)
|
||||||
state = window.current_state
|
States::Interface.instance&.update_server_browser(server) if server_updated
|
||||||
state.update_server_browser(server) if state.is_a?(States::Interface) && server
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
|
|
||||||
def uninstall(app_id, channel)
|
def uninstall(app_id, channel)
|
||||||
puts "Uninstall Request: #{app_id} #{channel}"
|
puts "Uninstall Request: #{app_id}-#{channel}"
|
||||||
|
|
||||||
return false if !installed?(app_id, channel) || installing?(app_id, channel)
|
return false if !installed?(app_id, channel) || installing?(app_id, channel)
|
||||||
|
|
||||||
@@ -297,6 +297,11 @@ class W3DHub
|
|||||||
listed_version > current_version
|
listed_version > current_version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def uninstalled!(task)
|
||||||
|
Store.settings[:games].delete(:"#{task.app_id}_#{task.release_channel}")
|
||||||
|
Store.settings.save_settings
|
||||||
|
end
|
||||||
|
|
||||||
# No application tasks are being done
|
# No application tasks are being done
|
||||||
def idle?
|
def idle?
|
||||||
!busy?
|
!busy?
|
||||||
@@ -314,6 +319,8 @@ class W3DHub
|
|||||||
def start_next_available_task
|
def start_next_available_task
|
||||||
return unless idle?
|
return unless idle?
|
||||||
|
|
||||||
|
@tasks.delete_if { |t| t.state == :complete || t.state == :halted || t.state == :failed }
|
||||||
|
|
||||||
task = @tasks.find { |t| t.state == :not_started }
|
task = @tasks.find { |t| t.state == :not_started }
|
||||||
task&.start
|
task&.start
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ class W3DHub
|
|||||||
def fail!(reason = "")
|
def fail!(reason = "")
|
||||||
@task_state = :failed
|
@task_state = :failed
|
||||||
@task_failure_reason = reason.to_s
|
@task_failure_reason = reason.to_s
|
||||||
|
|
||||||
|
hide_application_taskbar
|
||||||
end
|
end
|
||||||
|
|
||||||
def fail_silently!
|
def fail_silently!
|
||||||
@@ -138,7 +140,15 @@ class W3DHub
|
|||||||
def update_interface_task_status
|
def update_interface_task_status
|
||||||
run_on_main_thread(
|
run_on_main_thread(
|
||||||
proc do
|
proc do
|
||||||
window.current_state.interface_task_update_pending = self
|
States::Interface.instance&.interface_task_update_pending = self
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_application_taskbar
|
||||||
|
run_on_main_thread(
|
||||||
|
proc do
|
||||||
|
States::Interface.instance&.show_application_taskbar
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -146,7 +156,7 @@ class W3DHub
|
|||||||
def hide_application_taskbar
|
def hide_application_taskbar
|
||||||
run_on_main_thread(
|
run_on_main_thread(
|
||||||
proc do
|
proc do
|
||||||
window.current_state.hide_application_taskbar
|
States::Interface.instance&.hide_application_taskbar
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
|
|
||||||
def execute_task
|
def execute_task
|
||||||
|
show_application_taskbar
|
||||||
|
|
||||||
fail_fast
|
fail_fast
|
||||||
return false if failed?
|
return false if failed?
|
||||||
|
|
||||||
@@ -26,20 +28,17 @@ class W3DHub
|
|||||||
|
|
||||||
unpack_packages(packages)
|
unpack_packages(packages)
|
||||||
return false if failed?
|
return false if failed?
|
||||||
sleep 1
|
|
||||||
|
|
||||||
create_wine_prefix
|
create_wine_prefix
|
||||||
return false if failed?
|
return false if failed?
|
||||||
sleep 1
|
|
||||||
|
|
||||||
install_dependencies(packages)
|
install_dependencies(packages)
|
||||||
return false if failed?
|
return false if failed?
|
||||||
sleep 1
|
|
||||||
|
|
||||||
mark_application_installed
|
mark_application_installed
|
||||||
return false if failed?
|
return false if failed?
|
||||||
|
|
||||||
sleep 5
|
sleep 1
|
||||||
hide_application_taskbar
|
hide_application_taskbar
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class W3DHub
|
|||||||
:uninstaller
|
:uninstaller
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec_task
|
def execute_task
|
||||||
# TODO: cherrypick or nuke installation folder
|
# TODO: cherrypick or nuke installation folder
|
||||||
# A:
|
# A:
|
||||||
# fetch manifests
|
# fetch manifests
|
||||||
@@ -15,6 +15,43 @@ class W3DHub
|
|||||||
# B:
|
# B:
|
||||||
# Nuke installation folder
|
# Nuke installation folder
|
||||||
# mark application as uninstalled
|
# mark application as uninstalled
|
||||||
|
|
||||||
|
show_application_taskbar
|
||||||
|
|
||||||
|
remove_installation_directory
|
||||||
|
mark_application_uninstalled
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
hide_application_taskbar
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_installation_directory
|
||||||
|
@status.operations.clear
|
||||||
|
@status.label = "Uninstalling #{@application.name}"
|
||||||
|
@status.value = "Purging installation folder..."
|
||||||
|
@status.progress = Float::INFINITY
|
||||||
|
|
||||||
|
path = Cache.install_path(@application, @channel)
|
||||||
|
|
||||||
|
puts path
|
||||||
|
# TODO: Do some sanity checking, i.e. DO NOT start launcher if `whoami` returns root, path makes sense,
|
||||||
|
# we're not on Windows trying to uninstall a game likely installed by the official launcher
|
||||||
|
FileUtils.remove_dir(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_application_uninstalled
|
||||||
|
Store.application_manager.uninstalled!(self)
|
||||||
|
|
||||||
|
@status.operations.clear
|
||||||
|
@status.label = "Uninstalled #{@application.name}"
|
||||||
|
@status.value = ""
|
||||||
|
@status.progress = 1.0
|
||||||
|
|
||||||
|
@status.step = :mark_application_uninstalled
|
||||||
|
|
||||||
|
puts "#{@app_id} has been uninstalled."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class W3DHub
|
|||||||
Hash.new.tap { |hash|
|
Hash.new.tap { |hash|
|
||||||
hash[I18n.t(:"games.game_settings")] = { icon: "gear", block: proc { Store.application_manager.settings(game.id, channel.id) } }
|
hash[I18n.t(:"games.game_settings")] = { icon: "gear", block: proc { Store.application_manager.settings(game.id, channel.id) } }
|
||||||
hash[I18n.t(:"games.wine_configuration")] = { icon: "gear", block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
|
hash[I18n.t(:"games.wine_configuration")] = { icon: "gear", block: proc { Store.application_manager.wine_configuration(game.id, channel.id) } } if W3DHub.unix?
|
||||||
hash[I18n.t(:"games.game_modifications")] = { icon: "gear", enabled: false, block: proc { puts "Coming Soon!" } }
|
hash[I18n.t(:"games.game_modifications")] = { icon: "gear", enabled: true, block: proc { populate_game_modifications(game, channel) } }
|
||||||
if game.id != "ren"
|
if game.id != "ren"
|
||||||
hash[I18n.t(:"games.repair_installation")] = { icon: "wrench", block: proc { Store.application_manager.repair(game.id, channel.id) } }
|
hash[I18n.t(:"games.repair_installation")] = { icon: "wrench", block: proc { Store.application_manager.repair(game.id, channel.id) } }
|
||||||
hash[I18n.t(:"games.uninstall_game")] = { icon: "trashCan", block: proc { Store.application_manager.uninstall(game.id, channel.id) } }
|
hash[I18n.t(:"games.uninstall_game")] = { icon: "trashCan", block: proc { Store.application_manager.uninstall(game.id, channel.id) } }
|
||||||
@@ -225,6 +225,46 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def populate_game_modifications(application, channel)
|
||||||
|
@game_news_container.clear do
|
||||||
|
([
|
||||||
|
{
|
||||||
|
id: "4E4CB0548029FF234E289B4B8B3E357A",
|
||||||
|
name: "HD Purchase Terminal Icons",
|
||||||
|
author: "username",
|
||||||
|
description: "Replaces them blurry low res icons with juicy hi-res ones.",
|
||||||
|
icon: nil,
|
||||||
|
type: "Textures",
|
||||||
|
subtype: "Purchase Terminal",
|
||||||
|
multiplayer_approved: true,
|
||||||
|
games: ["ren", "ia"],
|
||||||
|
versions: ["0.0.1", "0.0.2", "0.1.0"],
|
||||||
|
url: "https://w3dhub.com/mods/username/hd_purchase_terminal_icons"
|
||||||
|
}
|
||||||
|
] * 10).flatten.each do |mod|
|
||||||
|
flow(width: 1.0, height: 128, margin: 4, border_bottom_thickness: 1, border_bottom_color: 0xff_ffffff) do
|
||||||
|
stack(width: 128, height: 128, padding: 4) do
|
||||||
|
image BLACK_IMAGE, height: 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
stack(width: 0.75, height: 1.0) do
|
||||||
|
stack(width: 1.0, height: 128 - 28) do
|
||||||
|
link(mod[:name]) { Launchy.open(mod[:url]) }
|
||||||
|
inscription "Author: #{mod[:author]} | #{mod[:type]} | #{mod[:subtype]}"
|
||||||
|
para mod[:description][0..180]
|
||||||
|
end
|
||||||
|
|
||||||
|
flow(width: 1.0, height: 28, padding: 4) do
|
||||||
|
inscription "Version", width: 0.25, text_align: :center
|
||||||
|
list_box items: mod[:versions], width: 0.5, enabled: mod[:versions].size > 1, padding_top: 0, padding_bottom: 0
|
||||||
|
button "Install", width: 0.25, padding_top: 0, padding_bottom: 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3,6 +3,8 @@ class W3DHub
|
|||||||
class ServerBrowser < Page
|
class ServerBrowser < Page
|
||||||
def setup
|
def setup
|
||||||
@server_locked_icons = {}
|
@server_locked_icons = {}
|
||||||
|
@refresh_server_list = false
|
||||||
|
refresh_server = false
|
||||||
|
|
||||||
@selected_server ||= nil
|
@selected_server ||= nil
|
||||||
@selected_server_container ||= nil
|
@selected_server_container ||= nil
|
||||||
@@ -52,9 +54,9 @@ class W3DHub
|
|||||||
populate_server_list
|
populate_server_list
|
||||||
end
|
end
|
||||||
|
|
||||||
button get_image("#{GAME_ROOT_PATH}/media/ui_icons/return.png"), tip: I18n.t(:"server_browser.refresh"), image_height: 1.0, margin_left: 16, padding_left: 2, padding_right: 2, padding_top: 2, padding_bottom: 2 do
|
# button get_image("#{GAME_ROOT_PATH}/media/ui_icons/return.png"), tip: I18n.t(:"server_browser.refresh"), image_height: 1.0, margin_left: 16, padding_left: 2, padding_right: 2, padding_top: 2, padding_bottom: 2 do
|
||||||
fetch_server_list
|
# fetch_server_list
|
||||||
end
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
flow(width: 0.249, height: 1.0) do
|
flow(width: 0.249, height: 1.0) do
|
||||||
@@ -113,37 +115,48 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Store.server_list.empty?
|
|
||||||
fetch_server_list
|
|
||||||
else
|
|
||||||
populate_server_list
|
populate_server_list
|
||||||
end
|
populate_server_info(@selected_server) if @selected_server
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
super
|
super
|
||||||
|
|
||||||
populate_server_list if @refresh_server_list
|
if @refresh_server_list && Gosu.milliseconds >= @refresh_server_list
|
||||||
@refresh_server_list = false
|
@refresh_server_list = nil
|
||||||
|
|
||||||
|
populate_server_list
|
||||||
|
|
||||||
|
if @selected_server&.id == @refresh_server&.id
|
||||||
|
Async do
|
||||||
|
fetch_server_details(@refresh_server) if @refresh_server
|
||||||
|
populate_server_info(@refresh_server) if @refresh_server && @refresh_server == @selected_server
|
||||||
|
|
||||||
|
@refresh_server = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def refresh_server_list(server)
|
def refresh_server_list(server)
|
||||||
populate_server_info(server) if @selected_server&.id == server.id
|
@refresh_server_list = Gosu.milliseconds + 3_000
|
||||||
@refresh_server_list = true
|
@refresh_server = server if @selected_server&.id == server.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def stylize_selected_server(server_container)
|
def stylize_selected_server(server_container)
|
||||||
server_container.style.server_item_background = server_container.style.default[:background]
|
server_container.style.server_item_background = server_container.style.default[:background]
|
||||||
server_container.style.server_item_hover_background = server_container.style.hover[:background]
|
server_container.style.server_item_hover_background = server_container.style.hover[:background]
|
||||||
server_container.style.server_item_active_background = server_container.style.active[:background]
|
server_container.style.server_item_active_background = server_container.style.active[:background]
|
||||||
|
|
||||||
server_container.style.background = @selected_color
|
server_container.style.background = @selected_color
|
||||||
|
|
||||||
server_container.style.default[:background] = @selected_color
|
server_container.style.default[:background] = @selected_color
|
||||||
server_container.style.hover[:background] = @selected_color
|
server_container.style.hover[:background] = @selected_color
|
||||||
server_container.style.active[:background] = @selected_color
|
server_container.style.active[:background] = @selected_color
|
||||||
end
|
end
|
||||||
|
|
||||||
def populate_server_list
|
def populate_server_list
|
||||||
@server_list_container.scroll_top = 0
|
Store.server_list = Store.server_list.sort_by! { |s| [s&.status&.player_count, s&.id] }.reverse if Store.server_list
|
||||||
|
|
||||||
@server_list_container.clear do
|
@server_list_container.clear do
|
||||||
i = -1
|
i = -1
|
||||||
@@ -207,7 +220,10 @@ class W3DHub
|
|||||||
|
|
||||||
@selected_server = server
|
@selected_server = server
|
||||||
|
|
||||||
populate_server_info(server)
|
Async do
|
||||||
|
fetch_server_details(server)
|
||||||
|
populate_server_info(server) if server == @selected_server
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
stylize_selected_server(server_container) if server.id == @selected_server&.id
|
stylize_selected_server(server_container) if server.id == @selected_server&.id
|
||||||
@@ -333,29 +349,12 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_server_list
|
def fetch_server_details(server)
|
||||||
unless Gosu.milliseconds - Store.server_list_last_fetch >= 3_000 # 3 seconds
|
|
||||||
populate_server_list # Fake it
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Async do
|
Async do
|
||||||
internet = Async::HTTP::Internet.instance
|
internet = Async::HTTP::Internet.instance
|
||||||
|
|
||||||
begin
|
server_data = Api.server_details(internet, server.id, 2)
|
||||||
list = Api.server_list(internet, 2)
|
server.update(server_data) if server_data
|
||||||
|
|
||||||
if list
|
|
||||||
Store.server_list = list.sort_by! { |s| s&.status&.players&.size }.reverse
|
|
||||||
Store.server_list_last_fetch = Gosu.milliseconds
|
|
||||||
|
|
||||||
main_thread_queue << proc { populate_server_list }
|
|
||||||
end
|
|
||||||
rescue => e
|
|
||||||
# Something went wrong!
|
|
||||||
pp e
|
|
||||||
Store.server_list = []
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,15 @@ class W3DHub
|
|||||||
attr_reader :main_thread_queue
|
attr_reader :main_thread_queue
|
||||||
attr_accessor :interface_task_update_pending
|
attr_accessor :interface_task_update_pending
|
||||||
|
|
||||||
|
@@instance = nil
|
||||||
|
|
||||||
|
def self.instance
|
||||||
|
@@instance
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
|
@@instance = self
|
||||||
|
|
||||||
window.show_cursor = true
|
window.show_cursor = true
|
||||||
|
|
||||||
@account = @options[:account]
|
@account = @options[:account]
|
||||||
@@ -165,8 +173,6 @@ class W3DHub
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_interface_task_status(task)
|
def update_interface_task_status(task)
|
||||||
show_application_taskbar
|
|
||||||
|
|
||||||
@application_taskbar_label.value = task.status.label
|
@application_taskbar_label.value = task.status.label
|
||||||
@application_taskbar_status_label.value = "#{task.status.value} (#{format("%.2f%%", task.status.progress.clamp(0.0, 1.0) * 100.0)})"
|
@application_taskbar_status_label.value = "#{task.status.value} (#{format("%.2f%%", task.status.progress.clamp(0.0, 1.0) * 100.0)})"
|
||||||
@application_taskbar_progressbar.value = task.status.progress.clamp(0.0, 1.0)
|
@application_taskbar_progressbar.value = task.status.progress.clamp(0.0, 1.0)
|
||||||
|
|||||||
@@ -78,5 +78,5 @@ require_relative "lib/pages/download_manager"
|
|||||||
Async do
|
Async do
|
||||||
W3DHub::Window.new(width: 980, height: 720, borderless: false).show
|
W3DHub::Window.new(width: 980, height: 720, borderless: false).show
|
||||||
|
|
||||||
raise Async::Stop # ensure reactor is shutdown when window is closed
|
exit # ensure reactor is shutdown when window is closed
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user